webClient: improved spectrum draw.

pull/6/head
Michal Fratczak 2018-11-22 22:01:49 +01:00
rodzic 6a97d1b908
commit 76890ef5ee
2 zmienionych plików z 132 dodań i 43 usunięć

Wyświetl plik

@ -1,3 +1,84 @@
class Average // rolling avg classs
{
constructor(max_count, init_val=0)
{
this.max_count_ = max_count;
this.count_ = 0;
this.sum_ = 0;
this.add(init_val);
}
get_avg()
{
if(this.count_ == 0)
return this.sum_;
return this.sum_/this.count_;
}
add(val)
{
if(this.count_ == this.max_count_)
{
// console.debug("SATURATE");
this.sum_ = this.get_avg() * (this.max_count_-1) + val;
}
else
{
this.count_ += 1;
this.sum_ += val;
}
}
reset(val)
{
this.sum_ = val;
this.count_ = 1;
}
};
var AccSpectrumArray = {
arr_: new Array(),
count_: 0,
maxCount_: 3
};
var AvgCnt = 10; // Rolling average length. Smooths out spectrum drawing.
var NoiseFloorAvg = new Average(AvgCnt);
var SpectrumMinAvg = new Average(AvgCnt);
// rolling average on array
function AccumulateSpectrumArray(i_arr)
{
if(AccSpectrumArray.arr_.length != i_arr.length)
{
AccSpectrumArray.arr_ = i_arr;
AccSpectrumArray.count_ = 1;
return AccSpectrumArray.arr_;
}
if( AccSpectrumArray.count_ < AccSpectrumArray.maxCount_ )
{
for(var i=0 ; i<AccSpectrumArray.arr_.length; ++i)
AccSpectrumArray.arr_[i] += i_arr[i];
AccSpectrumArray.count_ += 1;
}
else
{
for(var i=0 ; i<AccSpectrumArray.arr_.length; ++i)
{
AccSpectrumArray.arr_[i] =
(AccSpectrumArray.arr_[i] / AccSpectrumArray.count_) * (AccSpectrumArray.maxCount_-1) + i_arr[i];
}
}
// return value
var spectr_result = new Array(AccSpectrumArray.arr_.length);
for(var i=0 ; i<AccSpectrumArray.arr_.length; ++i)
spectr_result[i] = AccSpectrumArray.arr_[i] / AccSpectrumArray.count_;
return spectr_result;
}
function DrawPowerSpectrum(i_canvas, i_spectrum)
{
var ctx = i_canvas.getContext("2d");
@ -45,40 +126,47 @@ function DrawPowerSpectrum(i_canvas, i_spectrum)
power_grd.addColorStop(.6, "#993311");
power_grd.addColorStop(1, "black");
// decode spectrum values
var spectrum_values_arr = new Array(i_canvas.width);
for(var x=0; x<i_canvas.width; ++x)
{
var x_0_1 = x/(i_canvas.width-1);
var value_encoded = i_spectrum.values_[ Math.round(x_0_1 * i_spectrum.values_.length) ];
var true_value;
if(i_spectrum.type_size_ == 1) // 8 bit char
true_value = i_spectrum.min_ + (value_encoded / 255) * (i_spectrum.max_ - i_spectrum.min_);
else if(i_spectrum.type_size_ == 2) // uint16_t
true_value = i_spectrum.min_ + (value_encoded / 65535) * (i_spectrum.max_ - i_spectrum.min_);
else if(i_spectrum.type_size_ == 4) // 32float
true_value = value_encoded;
spectrum_values_arr[x] = true_value;
}
// border values are NaN. needs fixing
spectrum_values_arr[0] = spectrum_values_arr[1];
spectrum_values_arr[spectrum_values_arr.length-1] = spectrum_values_arr[spectrum_values_arr.length-2];
// accumulate spectrum and noisefloor for nice rendering
spectrum_values_arr = AccumulateSpectrumArray(spectrum_values_arr);
NoiseFloorAvg.add(i_spectrum.noise_floor_);
SpectrumMinAvg.add(i_spectrum.min_);
var noise_floor_avg = NoiseFloorAvg.get_avg();
var spectrum_min_avg = SpectrumMinAvg.get_avg();
// spectrum_min_avg *= 1.3; // drawing pedestal
// draw
ctx.strokeStyle = power_grd;
ctx.beginPath();
if(i_spectrum.type_size_ == 1) // 8 bit char
for(var x=0; x<i_canvas.width; ++x)
{
for(var x=0; x<i_canvas.width; ++x)
{
var x_0_1 = x/(i_canvas.width-1);
var val_0_1 = i_spectrum.values_[ Math.round(x_0_1 * i_spectrum.values_.length) ] / 255;
var val_pixel = (1-val_0_1) * (i_canvas.height-1);
ctx.moveTo(x, i_canvas.height - 1);
ctx.lineTo(x, val_pixel);
}
}
else if(i_spectrum.type_size_ == 2) // uint16_t
{
for(var x=0; x<i_canvas.width; ++x)
{
var x_0_1 = x/(i_canvas.width-1);
var val_0_1 = i_spectrum.values_[ Math.round(x_0_1 * i_spectrum.values_.length) ] / 65535;
var val_pixel = (1-val_0_1) * (i_canvas.height-1);
ctx.moveTo(x, i_canvas.height - 1);
ctx.lineTo(x, val_pixel);
}
}
else if(i_spectrum.type_size_ == 4) // 32float
{
for(var x=0; x<i_canvas.width; ++x)
{
var x_0_1 = x/(i_canvas.width-1);
var val_0_1 = (i_spectrum.values_[Math.round(x_0_1 * i_spectrum.values_.length)] - i_spectrum.min_) / (i_spectrum.max_ - i_spectrum.min_) ;
var val_pixel = (1-val_0_1) * (i_canvas.height-1);
ctx.moveTo(x, i_canvas.height - 1);
ctx.lineTo(x, val_pixel);
}
var val_0_1 = 1.0 - Math.abs(spectrum_values_arr[x] / spectrum_min_avg);
val_0_1 = Math.max(val_0_1, 0);
var val_pixel = (1-val_0_1) * (i_canvas.height-1);
ctx.moveTo(x, i_canvas.height - 1);
ctx.lineTo(x, val_pixel);
}
ctx.stroke();
@ -94,7 +182,8 @@ function DrawPowerSpectrum(i_canvas, i_spectrum)
//
ctx.strokeStyle = '#333388';
ctx.beginPath();
var nf_0_1 = (i_spectrum.noise_floor_ - i_spectrum.min_) / (i_spectrum.max_ - i_spectrum.min_);
var nf_0_1 = 1.0 - Math.abs(noise_floor_avg / spectrum_min_avg);
nf_0_1 = Math.max(nf_0_1, 0);
ctx.moveTo(0, (1-nf_0_1)*i_canvas.height - 1);
ctx.lineTo(i_canvas.width-1, (1-nf_0_1)*i_canvas.height - 1);
ctx.stroke();
@ -102,9 +191,9 @@ function DrawPowerSpectrum(i_canvas, i_spectrum)
// PEAK LEFT
//
if(i_spectrum.peak_left_valid_)
ctx.strokeStyle = '#FF5500';
ctx.strokeStyle = '#FF2200';
else
ctx.strokeStyle = '#55000';
ctx.strokeStyle = '#113322';
ctx.beginPath();
var peak_left_0_1 = i_spectrum.peak_left_ / i_spectrum.size_;
ctx.moveTo(peak_left_0_1 * i_canvas.width, 0);
@ -116,7 +205,7 @@ function DrawPowerSpectrum(i_canvas, i_spectrum)
if(i_spectrum.peak_right_valid_)
ctx.strokeStyle = '#0088FF';
else
ctx.strokeStyle = '#000055';
ctx.strokeStyle = '#113322';
ctx.beginPath();
var peak_right_0_1 = i_spectrum.peak_right_ / i_spectrum.size_;
ctx.moveTo(peak_right_0_1 * i_canvas.width, 0);
@ -162,17 +251,17 @@ function DrawDemod(i_canvas, i_demod)
{
var x_0_1 = x/(i_canvas.width-1);
var raw_value = i_demod.values_[ Math.round(x_0_1 * i_demod.values_.length) ];
var full_scale_value = 0;
var encoded_value = i_demod.values_[ Math.round(x_0_1 * i_demod.values_.length) ];
var true_value = 0;
if(i_demod.type_size_ == 1) // 8 bit char
full_scale_value = i_demod.min_ + raw_value / 255.0 * (i_demod.max_ - i_demod.min_);
true_value = i_demod.min_ + encoded_value / 255.0 * (i_demod.max_ - i_demod.min_);
else if(i_demod.type_size_ == 2) // uint16_t
full_scale_value = i_demod.min_ + raw_value / 65535.0 * (i_demod.max_ - i_demod.min_);
true_value = i_demod.min_ + encoded_value / 65535.0 * (i_demod.max_ - i_demod.min_);
else if(i_demod.type_size_ == 4) // 32float
full_scale_value = raw_value;
true_value = encoded_value;
full_scale_value *= .75; // scale down a little bit
var val_0_1 = .5 + .5 * full_scale_value / Math.max( Math.abs( i_demod.min_ ), Math.abs( i_demod.max_ ) );
true_value *= .75; // scale down a little bit
var val_0_1 = .5 + .5 * true_value / Math.max( Math.abs( i_demod.min_ ), Math.abs( i_demod.max_ ) );
var val_pixel = (1.0-val_0_1) * (i_canvas.height-1);
ctx.lineTo(x, val_pixel);

Wyświetl plik

@ -23,7 +23,7 @@ var GLOBALS =
function debug_print()
{
console.debug(arguments);
// console.debug(arguments);
/*
document.getElementById("cnt_debug").innerHTML = "";
for (i = 0; i < arguments.length; i++)