diff --git a/htdocs/index.wrx b/htdocs/index.wrx index c0dc4cf..5b5f1dd 100644 --- a/htdocs/index.wrx +++ b/htdocs/index.wrx @@ -1,7 +1,7 @@
-
+
---.--- MHz
---.--- MHz
+
-
FM
-
AM
-
LSB
-
USB
-
CW
+
FM
+
AM
+
LSB
+
USB
+
CW
-
- +
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
-
diff --git a/htdocs/openwebrx.css b/htdocs/openwebrx.css index 37f6b62..760241e 100644 --- a/htdocs/openwebrx.css +++ b/htdocs/openwebrx.css @@ -1,6 +1,6 @@ /* - This file is part of OpenWebRX, + This file is part of OpenWebRX, an open-source SDR receiver software with a web UI. Copyright (c) 2013-2015 by Andras Retzler @@ -37,7 +37,6 @@ input[type=range] { -webkit-appearance: none; margin: 10px 0; - width: 100%; } input[type=range]:focus { @@ -242,7 +241,7 @@ input[type=range]:focus::-ms-fill-upper position: absolute; bottom: 0px; left: 0px; - background-image:url(gfx/webrx-photo-gradient-corner.png); + background-image:url(gfx/webrx-photo-gradient-corner.png); width: 59px; height: 92px; @@ -255,7 +254,7 @@ input[type=range]:focus::-ms-fill-upper left: 59px; right: 59px; height: 92px; - background-image:url(gfx/webrx-photo-gradient-middle.png); + background-image:url(gfx/webrx-photo-gradient-middle.png); } #webrx-photo-gradient-right @@ -263,7 +262,7 @@ input[type=range]:focus::-ms-fill-upper position: absolute; bottom: 0px; right: 0px; - background-image:url(gfx/webrx-photo-gradient-corner.png); + background-image:url(gfx/webrx-photo-gradient-corner.png); width: 59px; height: 92px; -webkit-transform:scaleX(-1); @@ -456,7 +455,7 @@ input[type=range]:focus::-ms-fill-upper background-color: #999999; color: White; z-index:9999; /*should be higher? - + }*/ /* removed non-free fonts like that: */ @@ -484,7 +483,7 @@ input[type=range]:focus::-ms-fill-upper padding: 0; margin: 0; line-height:22px; - + } #webrx-mouse-freq @@ -497,6 +496,7 @@ input[type=range]:focus::-ms-fill-upper margin-bottom: 5px; } + .openwebrx-panel { visibility: hidden; @@ -551,13 +551,72 @@ input[type=range]:focus::-ms-fill-upper color: #FFFF50; } -.openwebrx-button:active +.openwebrx-button:active { background: #777777; - color: #FFFF50; + color: #FFFF50; } -#openwebrx-client-log-title +.openwebrx-demodulator-button +{ + width: 35px; + height: 19px; + font-size: 12pt; + text-align: center; +} + +.openwebrx-square-button img +{ + height: 30px; +} + +.openwebrx-round-button +{ + margin-right: -2px; + width: 35px; + height: 35px; + border-radius: 25px; +} + +.openwebrx-round-button img +{ + height: 30px; +} + +.openwebrx-round-button-small +{ + margin-right: -3px; + width: 20px; + height: 20px; + border-radius: 25px; +} + +.openwebrx-round-button-small img +{ + height: 20px; +} + +img.openwebrx-mirror-img +{ + transform: scale(-1, 1); +} + + +.openwebrx-round-rightarrow img +{ + position: relative; + left: 12px; + top: 3px; +} + +.openwebrx-round-leftarrow img +{ + position: relative; + left: 7px; + top: 3px; +} + +#openwebrx-client-log-title { margin-bottom: 5px; font-weight: bold; @@ -626,7 +685,7 @@ input[type=range]:focus::-ms-fill-upper display: table-cell; padding-left: 5px; padding-right: 5px; - cursor:pointer; + cursor:pointer; } #openwebrx-main-buttons li:hover @@ -668,14 +727,14 @@ input[type=range]:focus::-ms-fill-upper color: white; } -#openwebrx-panel-volume +.openwebrx-panel-slider { position: relative; top: -2px; - width:170px; + width:91px; } -#openwebrx-mute-img +.openwebrx-sliderbtn-img { width: 14px; position:relative; diff --git a/htdocs/openwebrx.js b/htdocs/openwebrx.js index eaf7bdf..2d3f960 100644 --- a/htdocs/openwebrx.js +++ b/htdocs/openwebrx.js @@ -1,6 +1,6 @@ /* - This file is part of OpenWebRX, + This file is part of OpenWebRX, an open-source SDR receiver software with a web UI. Copyright (c) 2013-2015 by Andras Retzler @@ -58,12 +58,12 @@ var waterfall_timer; something.fade_i=0; n_of_iters=time_ms/(1000/fps); change=(to-from)/(n_of_iters-1); - + something.fade_timer=window.setInterval( function(){ if(something.fade_i++=parseInt(wfmax.value)) + { + if(!which) wfmin.value=(parseInt(wfmax.value)-1).toString(); + else wfmax.value=(parseInt(wfmin.value)+1).toString(); + } + waterfall_min_level=parseInt(wfmin.value); + waterfall_max_level=parseInt(wfmax.value); +} +function waterfallColorsDefault() +{ + waterfall_min_level=waterfall_min_level_default; + waterfall_max_level=waterfall_max_level_default; + e("openwebrx-waterfall-color-min").value=waterfall_min_level.toString(); + e("openwebrx-waterfall-color-max").value=waterfall_max_level.toString(); +} + +function waterfallColorsAuto() +{ + e("openwebrx-waterfall-color-min").value=(waterfall_measure_minmax_min-20).toString(); + e("openwebrx-waterfall-color-max").value=(waterfall_measure_minmax_max+30).toString(); + updateWaterfallColors(0); +} // ======================================================== // ================= ANIMATION ROUTINES ================= @@ -165,8 +196,8 @@ function animate(object,style_name,unit,from,to,accel,time_ms,fps,to_exec) if(object.anim_i++9||unit!="px") new_val=(to+accel*remain); else {if(Math.abs(remain)<2) new_val=to; @@ -174,7 +205,7 @@ function animate(object,style_name,unit,from,to,accel,time_ms,fps,to_exec) object.style[style_name]=new_val.toString()+unit; } } - else + else {object.style[style_name]=to.toString()+unit; window.clearInterval(object.anim_timer); delete object.anim_timer; } if(to_exec!=0) to_exec(); },1000/fps); @@ -209,7 +240,7 @@ function demod_envelope_draw(range, from, to, color, line) // A "drag range" object is returned, containing information about the draggable areas of the envelope // (beginning, ending and the line showing the offset frequency). if(typeof color == "undefined") color="#ffff00"; //yellow - env_bounding_line_w=5; // + env_bounding_line_w=5; // env_att_w=5; // _______ ___env_h2 in px ___|_____ env_h1=17; // _/| \_ ___env_h1 in px _/ |_ \_ env_h2=5; // |||env_att_line_w |_env_lineplus @@ -219,11 +250,11 @@ function demod_envelope_draw(range, from, to, color, line) from_px=scale_px_from_freq(from,range); to_px=scale_px_from_freq(to,range); if(to_pxwindow.innerWidth)) @@ -275,12 +306,12 @@ function demod_envelope_where_clicked(x, drag_ranges, key_modifiers) if(drag_ranges.envelope_on_screen&&in_range(x,drag_ranges.whole_envelope)) return dr.pbs; } if(drag_ranges.envelope_on_screen) - { + { // For low and high cut: if(in_range(x,drag_ranges.beginning)) return dr.beginning; if(in_range(x,drag_ranges.ending)) return dr.ending; // Last priority: having clicked anything else on the envelope, without holding the shift key - if(in_range(x,drag_ranges.whole_envelope)) return dr.anything_else; + if(in_range(x,drag_ranges.whole_envelope)) return dr.anything_else; } return dr.none; //User doesn't drag the envelope for this demodulator } @@ -304,7 +335,7 @@ demodulator.draggable_ranges={none: 0, beginning:1 /*from*/, ending: 2 /*to*/, a // This can be used as a base for basic audio demodulators. // It already supports most basic modulations used for ham radio and commercial services: AM/FM/LSB/USB -demodulator_response_time=50; +demodulator_response_time=50; //in ms; if we don't limit the number of SETs sent to the server, audio will underrun (possibly output buffer is cleared on SETs in GNU Radio function demodulator_default_analog(offset_frequency,subtype) @@ -318,7 +349,7 @@ function demodulator_default_analog(offset_frequency,subtype) high_cut_limit: audio_context.sampleRate/2, low_cut_limit: -audio_context.sampleRate/2 }; - //Subtypes only define some filter parameters and the mod string sent to server, + //Subtypes only define some filter parameters and the mod string sent to server, //so you may set these parameters in your custom child class. //Why? As of demodulation is done on the server, difference is mainly on the server side. this.server_mod=subtype; @@ -339,23 +370,23 @@ function demodulator_default_analog(offset_frequency,subtype) this.low_cut=700; this.high_cut=900; this.server_mod="ssb"; - } + } else if(subtype=="nfm") { this.low_cut=-4000; this.high_cut=4000; - } + } else if(subtype=="am") { this.low_cut=-4000; this.high_cut=4000; - } + } this.wait_for_timer=false; this.set_after=false; this.set=function() { //set() is a wrapper to call doset(), but it ensures that doset won't execute more frequently than demodulator_response_time. - if(!this.wait_for_timer) + if(!this.wait_for_timer) { this.doset(false); this.set_after=false; @@ -384,7 +415,7 @@ function demodulator_default_analog(offset_frequency,subtype) // for drawing the filter envelope above scale this.envelope.parent=this; - this.envelope.draw=function(visible_range) + this.envelope.draw=function(visible_range) { this.visible_range=visible_range; this.drag_ranges=demod_envelope_draw(range, @@ -428,22 +459,22 @@ function demodulator_default_analog(offset_frequency,subtype) //dragging any other parts of the filter envelope while holding Shift does emulate the PBS knob //(PassBand Shift) on radio equipment: PBS does move the whole passband without moving the offset //frequency. - if(this.dragged_range==dr.beginning||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs) + if(this.dragged_range==dr.beginning||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs) { //we don't let low_cut go beyond its limits if((new_value=this.drag_origin.low_cut+minus*freq_change)=this.parent.high_cut) return true; this.parent.low_cut=new_value; } - if(this.dragged_range==dr.ending||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs) + if(this.dragged_range==dr.ending||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs) { //we don't let high_cut go beyond its limits if((new_value=this.drag_origin.high_cut+minus*freq_change)>this.parent.filter.high_cut_limit) return true; //nor the filter passband be too small - if(new_value-this.parent.low_cutcanvas_drag_min_delta) + if(scale_canvas_drag_params.mouse_down&&!scale_canvas_drag_params.drag&&Math.abs(evt.pageX-scale_canvas_drag_params.start_x)>canvas_drag_min_delta) //we can use the main drag_min_delta thing of the main canvas { scale_canvas_drag_params.drag=true; @@ -577,7 +608,7 @@ function scale_canvas_mousemove(evt) for (var i=0;i=scale_min_space_bw_small_markers&&freq.toString()[0]!="5") {out.small/=2; out.ratio*=2; } out.smallbw=freq/out.ratio; return true; @@ -725,11 +756,11 @@ function mkscale() { var x=scale_px_from_freq(marker_hz,range); if(x>window.innerWidth) break; - scale_ctx.beginPath(); + scale_ctx.beginPath(); scale_ctx.moveTo(x, 22); if(marker_hz%spacing.params.large_marker_per_hz==0) { //large marker - if(typeof first_large == "undefined") var first_large=marker_hz; + if(typeof first_large == "undefined") var first_large=marker_hz; last_large=marker_hz; scale_ctx.lineWidth=3.5; scale_ctx.lineTo(x,22+11); @@ -742,16 +773,16 @@ function mkscale() if(scale_px_from_freq(marker_hz+spacing.smallbw*spacing.ratio,range)-text_measured.width>=scale_min_space_bw_texts) { //and if we have enough space to draw it correctly without clipping scale_ctx.textAlign = "left"; - scale_ctx.fillText(text_to_draw, 0, text_h_pos); + scale_ctx.fillText(text_to_draw, 0, text_h_pos); } } - else if( zoom_level==0 && (range.end-spacing.smallbw*spacing.ratiowindow.innerWidth-text_measured.width/2) ) + else if( zoom_level==0 && (range.end-spacing.smallbw*spacing.ratiowindow.innerWidth-text_measured.width/2) ) { // if this is the last overall marker when zoomed out... and if it would be clipped off the screen... if(window.innerWidth-text_measured.width-scale_px_from_freq(marker_hz-spacing.smallbw*spacing.ratio,range)>=scale_min_space_bw_texts) { //and if we have enough space to draw it correctly without clipping scale_ctx.textAlign = "right"; - scale_ctx.fillText(text_to_draw, window.innerWidth, text_h_pos); - } + scale_ctx.fillText(text_to_draw, window.innerWidth, text_h_pos); + } } else scale_ctx.fillText(text_to_draw, x, text_h_pos); //draw text normally } @@ -791,7 +822,7 @@ function resize_scale() function canvas_mouseover(evt) { if(!waterfall_setup_done) return; - //e("webrx-freq-show").style.visibility="visible"; + //e("webrx-freq-show").style.visibility="visible"; } function canvas_mouseout(evt) @@ -854,17 +885,17 @@ function canvas_mousemove(evt) element.style.left=realX.toString()+"px";*/ if(canvas_mouse_down) { - if(!canvas_drag&&Math.abs(evt.pageX-canvas_drag_start_x)>canvas_drag_min_delta) + if(!canvas_drag&&Math.abs(evt.pageX-canvas_drag_start_x)>canvas_drag_min_delta) { canvas_drag=true; canvas_container.style.cursor="move"; } - if(canvas_drag) + if(canvas_drag) { var deltaX=canvas_drag_last_x-evt.pageX; var deltaY=canvas_drag_last_y-evt.pageY; //zoom_center_where=zoom_center_where_calc(evt.pageX); - var dpx=range.hps*deltaX; + var dpx=range.hps*deltaX; if( !(zoom_center_rel+dpx>(bandwidth/2-canvas_container.clientWidth*(1-zoom_center_where)*range.hps)) && !(zoom_center_rel+dpx<-bandwidth/2+canvas_container.clientWidth*zoom_center_where*range.hps) @@ -892,10 +923,10 @@ function canvas_mouseup(evt) if(!waterfall_setup_done) return; relativeX=(evt.offsetX)?evt.offsetX:evt.layerX; - if(!canvas_drag) + if(!canvas_drag) { //ws.send("SET offset_freq="+canvas_get_freq_offset(relativeX).toString()); - demodulator_set_offset_frequency(0, canvas_get_freq_offset(relativeX)); + demodulator_set_offset_frequency(0, canvas_get_freq_offset(relativeX)); e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",canvas_get_frequency(relativeX),1e6,4); } else @@ -928,7 +959,7 @@ function canvas_mousewheel(evt) //console.log(dir); //i/=120; /*while (i--)*/ zoom_step(dir, relativeX, zoom_center_where_calc(evt.pageX)); - evt.preventDefault(); + evt.preventDefault(); //evt.returnValue = false; //disable scrollbar move } @@ -961,12 +992,26 @@ function mkzoomlevels() function zoom_step(out, where, onscreen) { if((out&&zoom_level==0)||(!out&&zoom_level>=zoom_levels_count-1)) return; - if(out) --zoom_level; else ++zoom_level; + zoom_center_rel=canvas_get_freq_offset(where); //console.log("zoom_step || zlevel: "+zoom_level.toString()+" zlevel_val: "+zoom_levels[zoom_level].toString()+" zoom_center_rel: "+zoom_center_rel.toString()); zoom_center_where=onscreen; + console.log(zoom_center_where, zoom_center_rel, where); + resize_canvases(true); + mkscale(); +} + +function zoom_set(level) +{ + if(!(level>=0&&level<=zoom_levels.length-1)) return; + level=parseInt(level); + zoom_level = level; + //zoom_center_rel=canvas_get_freq_offset(-canvases[0].offsetLeft+canvas_container.clientWidth/2); //zoom to screen center instead of demod envelope + zoom_center_rel=demodulators[0].offset_frequency; + zoom_center_where=0.5+(zoom_center_rel/bandwidth); //this is a kind of hack + console.log(zoom_center_where, zoom_center_rel, -canvases[0].offsetLeft+canvas_container.clientWidth/2); resize_canvases(true); mkscale(); } @@ -977,7 +1022,7 @@ function zoom_calc() var canvases_new_width=winsize*zoom_levels[zoom_level]; zoom_offset_px=-((canvases_new_width*(0.5+zoom_center_rel/bandwidth))-(winsize*zoom_center_where)); if(zoom_offset_px>0) zoom_offset_px=0; - if(zoom_offset_pxPlease change your operating system default settings in order to fix this.",1); } if(audio_server_output_rate >= output_range_min && audio_server_output_rate <= output_range_max) break; //okay, we're done @@ -1029,7 +1074,7 @@ function on_ws_recv(evt) { var stringData=arrayBufferToString(evt.data); if(stringData.substring(0,16)=="CLIENT DE SERVER") divlog("Acknowledged WebSocket connection: "+stringData); - + } if(firstChars=="AUD") { @@ -1048,7 +1093,7 @@ function on_ws_recv(evt) else if(fft_compression="adpcm") { fft_codec.reset(); - + var waterfall_i16=fft_codec.decode(new Uint8Array(evt.data,4)); var waterfall_f32=new Float32Array(waterfall_i16.length-COMPRESS_FFT_PAD_N); for(var i=0;iMath.max(fft_fps/2,20)) //in case of emergency + if(waterfall_queue.length>Math.max(fft_fps/2,20)) //in case of emergency { console.log("waterfall queue length:", waterfall_queue.length); add_problem("fft overflow"); @@ -1165,7 +1212,7 @@ function divlog(what, is_error) { is_error=!!is_error; was_error |= is_error; - if(is_error) + if(is_error) { what=""+what+""; if(e("openwebrx-panel-log").openwebrxHidden) toggle_panel("openwebrx-panel-log"); //show panel if any error is present @@ -1213,7 +1260,7 @@ function gain_ff(gain_value,data) //great! solved clicking! will have to move to function audio_prepare(data) { - + //audio_rebuffer.push(sdrjs.ConvertI16_F(data));//no resampling //audio_rebuffer.push(audio_resampler.process(sdrjs.ConvertI16_F(data)));//resampling without ADPCM if(audio_compression=="none") @@ -1223,7 +1270,7 @@ function audio_prepare(data) else return; //console.log("prepare",data.length,audio_rebuffer.remaining()); - while(audio_rebuffer.remaining()) + while(audio_rebuffer.remaining()) { audio_prepared_buffers.push(audio_rebuffer.take()); audio_buffer_current_count_debug++; @@ -1236,7 +1283,7 @@ function audio_prepare_without_resampler(data) { audio_rebuffer.push(sdrjs.ConvertI16_F(data)); console.log("prepare",data.length,audio_rebuffer.remaining()); - while(audio_rebuffer.remaining()) + while(audio_rebuffer.remaining()) { audio_prepared_buffers.push(audio_rebuffer.take()); audio_buffer_current_count_debug++; @@ -1271,7 +1318,7 @@ function audio_prepare_old(data) if(audio_last_output_offset==audio_buffer_size) dopush(); } else - { //array is larger than the remaining space in the output buffer + { //array is larger than the remaining space in the output buffer var copied=audio_buffer_size-audio_last_output_offset; var remain=data.length-copied; for(var i=0;iread_remain) { @@ -1367,7 +1414,7 @@ function audio_onprocess_notused(e) break; } else - { + { for (i=audio_buffer_index; iaudio_buffer_maximal_length_sec*audio_context.sampleRate) - { + { add_problem("audio overrun"); console.log("audio_flush() :: size: "+audio_buffer_current_size.toString()+" allowed: "+(audio_buffer_maximal_length_sec*audio_context.sampleRate).toString()); while (audio_buffer_current_size>audio_buffer_maximal_length_sec*audio_context.sampleRate*0.5) @@ -1410,7 +1457,7 @@ function webrx_set_param(what, value) function parsehash() { - if(h=window.location.hash) + if(h=window.location.hash) { h.substring(1).split(",").forEach(function(x){ harr=x.split("="); @@ -1418,28 +1465,28 @@ function parsehash() if(harr[0]=="mod") starting_mod = harr[1]; if(harr[0]=="freq") { console.log(parseInt(harr[1])); - console.log(center_freq); + console.log(center_freq); starting_offset_frequency = parseInt(harr[1])-center_freq; } }); - + } } function audio_preinit() { - try + try { window.AudioContext = window.AudioContext||window.webkitAudioContext; audio_context = new AudioContext(); } - catch(e) + catch(e) { divlog('Your browser does not support Web Audio API, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser.', 1); } //we send our setup packet - + parsehash(); //needs audio_context.sampleRate to exist @@ -1465,7 +1512,7 @@ function audio_init() audio_node = createjsnode_function(audio_buffer_size, 0, 1); audio_node.onaudioprocess = audio_onprocess; audio_node.connect(audio_context.destination); - // --- Resampling --- + // --- Resampling --- //https://github.com/grantgalitz/XAudioJS/blob/master/XAudioServer.js //audio_resampler = new Resampler(audio_received_sample_rate, audio_context.sampleRate, 1, audio_buffer_size, true); //audio_input_buffer_size = audio_buffer_size*(audio_received_sample_rate/audio_context.sampleRate); @@ -1478,8 +1525,8 @@ function audio_init() audio_source.buffer = buffer; audio_source.noteOn(0);*/ demodulator_analog_replace(starting_mod); - if(starting_offset_frequency) - { + if(starting_offset_frequency) + { demodulators[0].offset_frequency = starting_offset_frequency; e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",center_freq+starting_offset_frequency,1e6,4); demodulators[0].set(); @@ -1499,11 +1546,11 @@ function audio_init() function on_ws_closed() { try - { + { audio_node.disconnect(); } catch (dont_care) {} - divlog("WebSocket has closed unexpectedly. Please reload the page.", 1); + divlog("WebSocket has closed unexpectedly. Please reload the page.", 1); } function on_ws_error(event) @@ -1516,11 +1563,11 @@ String.prototype.startswith=function(str){ return this.indexOf(str) == 0; }; //h function open_websocket() { //if(ws_url.startswith("ws://localhost:")&&window.location.hostname!="127.0.0.1"&&window.location.hostname!="localhost") - //{ - //divlog("Server administrator should set server_hostname correctly, because it is left as \"localhost\". Now guessing hostname from page URL.",1); + //{ + //divlog("Server administrator should set server_hostname correctly, because it is left as \"localhost\". Now guessing hostname from page URL.",1); ws_url="ws://"+(window.location.origin.split("://")[1])+"/ws/"; //guess automatically -> now default behaviour //} - if (!("WebSocket" in window)) + if (!("WebSocket" in window)) divlog("Your browser does not support WebSocket, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser."); ws = new WebSocket(ws_url+client_id); ws.onopen = on_ws_opened; @@ -1566,15 +1613,15 @@ var canvas_container; var canvas_phantom; function add_canvas() -{ +{ new_canvas = document.createElement("canvas"); new_canvas.width=fft_size; new_canvas.height=canvas_default_height; canvas_actual_line=canvas_default_height-1; - new_canvas.style.width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px"; + new_canvas.style.width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px"; new_canvas.style.left=zoom_offset_px.toString()+"px"; new_canvas.style.height=canvas_default_height.toString()+"px"; - new_canvas.openwebrx_top=(-canvas_default_height+1); + new_canvas.openwebrx_top=(-canvas_default_height+1); new_canvas.style.top=new_canvas.openwebrx_top.toString()+"px"; canvas_context = new_canvas.getContext("2d"); canvas_container.appendChild(new_canvas); @@ -1608,7 +1655,7 @@ canvas_maxshift=0; function shift_canvases() { - canvases.forEach(function(p) + canvases.forEach(function(p) { p.style.top=(p.openwebrx_top++).toString()+"px"; }); @@ -1621,8 +1668,8 @@ function shift_canvases() } else canvas_phantom.style.display="none"; - - + + //canvas_container.style.height=(((canvases.length-1)*canvas_default_height)+(canvas_default_height-canvas_actual_line)).toString()+"px"; //canvas_container.style.height="100%"; } @@ -1634,7 +1681,7 @@ function resize_canvases(zoom) zoom_calc(); new_width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px"; var zoom_value=zoom_offset_px.toString()+"px"; - canvases.forEach(function(p) + canvases.forEach(function(p) { p.style.width=new_width; p.style.left=zoom_value; @@ -1695,7 +1742,7 @@ function waterfall_add(data) remain=pixel_per_point-(1-remain); } } - + } else { //make line smaller (linear decimation, moving average) @@ -1708,7 +1755,7 @@ function waterfall_add(data) { if(remain>1) { - last_pixel+=data[i]; + last_pixel+=data[i]; remain--; } else @@ -1722,8 +1769,8 @@ function waterfall_add(data) } } - //Add line to waterfall image - base=(h-1)*w*4; + //Add line to waterfall image + base=(h-1)*w*4; for(x=0;x>>0)>>((3-i)*8))&0xff; }*/ - //Add line to waterfall image + //Add line to waterfall image oneline_image = canvas_context.createImageData(w,1); for(x=0;x>>0)>>((3-i)*8))&0xff; } - + //Draw image canvas_context.putImageData(oneline_image, 0, canvas_actual_line--); shift_canvases(); if(canvas_actual_line<0) add_canvas(); - + //divlog("Drawn FFT"); } @@ -1769,14 +1816,14 @@ function check_top_bar_congestion() var rightmost=Math.max(rmf(wet),rmf(wed)); var tl=e("openwebrx-main-buttons"); - [wet, wed].map(function(what) { - if(rmf(what)>tl.offsetLeft-20) what.style.opacity=what.style.opacity="0"; + [wet, wed].map(function(what) { + if(rmf(what)>tl.offsetLeft-20) what.style.opacity=what.style.opacity="0"; else wet.style.opacity=wed.style.opacity="1"; }); } -function openwebrx_resize() +function openwebrx_resize() { resize_canvases(); resize_waterfall_container(true); @@ -1795,10 +1842,11 @@ function openwebrx_init() //Synchronise volume with slider updateVolume(); + waterfallColorsDefault(); } /* -window.setInterval(function(){ +window.setInterval(function(){ sum=0; for(i=0;i55000||audio_output_value<10000); + progressbar_set(e("openwebrx-bar-audio-output"),audio_output_value/55000,"Audio output ["+(audio_output_value/1000).toFixed(1)+" ksps]",audio_output_value>55000||audio_output_value<10000); audio_buffer_progressbar_update(); var network_speed_value=debug_ws_data_received/audio_debug_time_taken; - progressbar_set(e("openwebrx-bar-network-speed"),network_speed_value*8/2000,"Network usage ["+(network_speed_value*8).toFixed(1)+" kbps]",false); + progressbar_set(e("openwebrx-bar-network-speed"),network_speed_value*8/2000,"Network usage ["+(network_speed_value*8).toFixed(1)+" kbps]",false); audio_buffer_current_size_debug=0; @@ -1858,10 +1906,10 @@ function pop_bottommost_panel(from) { min_order=parseInt(from[0].dataset.panelOrder); min_index=0; - for(i=0;i1) val=1; var innerBar=null; var innerText=null; - for(var i=0;i