diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index bd805b28..0fedb87e 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -61,14 +61,20 @@ struct visu_packet { u8_t which; u8_t count; union { - u32_t width; - u32_t full_bars; + struct { + u32_t bars; + u32_t spectrum_scale; + } full; + struct { + u32_t width; + u32_t height; + s32_t col; + s32_t row; + u32_t border; + u32_t bars; + u32_t spectrum_scale; + }; }; - u32_t height; - s32_t col; - s32_t row; - u32_t border; - u32_t small_bars; }; struct ANIC_header { @@ -98,8 +104,7 @@ static struct { #define RMS_LEN_BIT 6 #define RMS_LEN (1 << RMS_LEN_BIT) -// actually this is 2x the displayed BW -#define DISPLAY_BW 32000 +#define DISPLAY_BW 20000 static struct scroller_s { // copy of grfs content @@ -128,9 +133,10 @@ static struct scroller_s { static EXT_RAM_ATTR struct { int bar_gap, bar_width, bar_border; struct { - int current; - int max; + int current, max; + int limit; } bars[MAX_BARS]; + float spectrum_scale; int n, col, row, height, width, border; enum { VISU_BLANK, VISU_VUMETER, VISU_SPECTRUM, VISU_WAVEFORM } mode; int speed, wake; @@ -659,13 +665,14 @@ static void visu_update(void) { // actual FFT that might be less cycle than all the crap below dsps_fft2r_fc32_ae32(visu.samples, FFT_LEN); dsps_bit_rev_fc32_ansi(visu.samples, FFT_LEN); + float rate = visu_export.rate; // now arrange the result with the number of bar and sampling rate (don't want DC) - for (int i = 1, j = 1; i <= visu.n && j < (FFT_LEN / 2); i++) { + for (int i = 0, j = 1; i < visu.n && j < (FFT_LEN / 2); i++) { float power, count; // find the next point in FFT (this is real signal, so only half matters) - for (count = 0, power = 0; j * visu.n * visu_export.rate < i * (FFT_LEN / 2) * DISPLAY_BW && j < (FFT_LEN / 2); j++, count += 1) { + for (count = 0, power = 0; j * visu_export.rate < visu.bars[i].limit * FFT_LEN && j < FFT_LEN / 2; j++, count += 1) { power += visu.samples[2*j] * visu.samples[2*j] + visu.samples[2*j+1] * visu.samples[2*j+1]; } // due to sample rate, we have reached the end of the available spectrum @@ -674,7 +681,7 @@ static void visu_update(void) { if (count) power /= count * 2.; } else if (count) { // how much of what remains do we need to add - float ratio = j - (float) (i * DISPLAY_BW * (FFT_LEN / 2)) / (float) (visu.n * visu_export.rate); + float ratio = j - (visu.bars[i].limit * FFT_LEN) / rate; power += (visu.samples[2*j] * visu.samples[2*j] + visu.samples[2*j+1] * visu.samples[2*j+1]) * ratio; // normalize accumulated data @@ -685,9 +692,9 @@ static void visu_update(void) { } // convert to dB and bars, same back-off - if (power) visu.bars[i-1].current = 32 * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f); - if (visu.bars[i-1].current > 31) visu.bars[i-1].current = 31; - else if (visu.bars[i-1].current < 0) visu.bars[i-1].current = 0; + if (power) visu.bars[i].current = 32 * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f); + if (visu.bars[i].current > 31) visu.bars[i].current = 31; + else if (visu.bars[i].current < 0) visu.bars[i].current = 0; } } } @@ -715,6 +722,22 @@ static void visu_update(void) { } } + +/**************************************************************************************** + * Visu packet handler + */ +void spectrum_limits(int min, int n, int pos) { + if (n / 2) { + int i; + float step = (DISPLAY_BW - min) * visu.spectrum_scale / (n/2); + visu.bars[pos].limit = min + step; + for (i = 1; i < n/2; i++) visu.bars[pos+i].limit = visu.bars[pos+i-1].limit + step; + spectrum_limits(visu.bars[pos + n/2 - 1].limit, n/2, pos + n/2); + } else { + visu.bars[pos].limit = DISPLAY_BW; + } +} + /**************************************************************************************** * Visu packet handler */ @@ -737,31 +760,38 @@ static void visu_handler( u8_t *data, int len) { if (visu.row >= SB_HEIGHT) display->clear(false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1); if (visu.mode) { - pkt->width = htonl(pkt->width); - pkt->height = htonl(pkt->height); - pkt->row = htonl(pkt->row); - pkt->col = htonl(pkt->col); - - if (pkt->width > 0 && pkt->count >= 4) { + if (pkt->count >= 4) { // small visu, then go were we are told to - visu.width = pkt->width; + pkt->height = htonl(pkt->height); + pkt->row = htonl(pkt->row); + pkt->col = htonl(pkt->col); + + visu.width = htonl(pkt->width); visu.height = pkt->height ? pkt->height : SB_HEIGHT; visu.col = pkt->col < 0 ? display->width + pkt->col : pkt->col; visu.row = pkt->row < 0 ? display->height + pkt->row : pkt->row; visu.border = htonl(pkt->border); - bars = htonl(pkt->small_bars); + bars = htonl(pkt->bars); + visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.; } else { // full screen visu, try to use bottom screen if available visu.width = display->width; visu.height = display->height > SB_HEIGHT ? display->height - SB_HEIGHT : display->height; visu.col = visu.border = 0; visu.row = display->height - visu.height; - // already in CPU order - bars = pkt->full_bars; + bars = htonl(pkt->full.bars); + visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.; } // try to adapt to what we have - visu.n = visu.mode == VISU_VUMETER ? 2 : (bars ? bars : MAX_BARS); + if (visu.mode == VISU_SPECTRUM) { + visu.n = bars ? bars : MAX_BARS; + if (visu.spectrum_scale <= 0 || visu.spectrum_scale > 0.5) visu.spectrum_scale = 0.5; + spectrum_limits(0, visu.n, 0); + } else { + visu.n = 2; + } + do { visu.bar_width = (visu.width - visu.border - visu.bar_gap * (visu.n - 1)) / visu.n; if (visu.bar_width > 0) break; @@ -784,7 +814,7 @@ static void visu_handler( u8_t *data, int len) { display->clear(false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1); - LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row); + LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale); } else { LOG_INFO("Stopping visualizer"); } diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip index 626d46d9..4942fc51 100644 Binary files a/plugin/SqueezeESP32.zip and b/plugin/SqueezeESP32.zip differ diff --git a/plugin/SqueezeESP32/Graphics.pm b/plugin/SqueezeESP32/Graphics.pm index 42ab788e..29b53bc2 100644 --- a/plugin/SqueezeESP32/Graphics.pm +++ b/plugin/SqueezeESP32/Graphics.pm @@ -16,6 +16,7 @@ my $VISUALIZER_SPECTRUM_ANALYZER = 2; my $VISUALIZER_WAVEFORM = 3; my $width = $prefs->get('width') || 128; +my $spectrum_scale = $prefs->get('spectrum_scale') || 0.5; my @modes = ( # mode 0 @@ -55,7 +56,7 @@ my @modes = ( { desc => ['VISUALIZER_SPECTRUM_ANALYZER_SMALL'], bar => 0, secs => 0, width => $width, _width => -32, # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), bars, left space) - params => [$VISUALIZER_SPECTRUM_ANALYZER, 32, 32, -32, 0, 2, 6] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER, 32, 32, -32, 0, 2, 6, $spectrum_scale] }, # mode 9 { desc => ['VISUALIZER_VUMETER'], bar => 0, secs => 0, width => $width, @@ -64,7 +65,7 @@ my @modes = ( { desc => ['VISUALIZER_SPECTRUM_ANALYZER'], bar => 0, secs => 0, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, 16] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER, 16, $spectrum_scale] }, # mode 11 { desc => ['VISUALIZER_VUMETER', 'AND', 'ELAPSED'], bar => 0, secs => 1, width => $width, @@ -73,7 +74,7 @@ my @modes = ( { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'ELAPSED'], bar => 0, secs => 1, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, 16] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER, 16, $spectrum_scale] }, # mode 13 { desc => ['VISUALIZER_VUMETER', 'AND', 'REMAINING'], bar => 0, secs => -1, width => $width, @@ -82,7 +83,7 @@ my @modes = ( { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'REMAINING'], bar => 0, secs => -1, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, 16] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER, 16, $spectrum_scale] }, ); @@ -135,14 +136,6 @@ sub displayHeight { return 32; } -sub updateWidth { - my ($display, $width) = @_; - - foreach my $mode (@{$display->modes}) { - $mode->{width} = $width + 1 + $mode->{_width} || 0; - } -} - sub vfdmodel { return 'graphic-'.$width.'x32'; } diff --git a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html b/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html index f6cffbe7..dec653b4 100644 --- a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html +++ b/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html @@ -6,6 +6,11 @@ [% END %] + [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE" desc="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE_DESC" %] + + [% END %] + + [% PROCESS settings/footer.html %] diff --git a/plugin/SqueezeESP32/Plugin.pm b/plugin/SqueezeESP32/Plugin.pm index 893500b0..e39979bf 100644 --- a/plugin/SqueezeESP32/Plugin.pm +++ b/plugin/SqueezeESP32/Plugin.pm @@ -10,6 +10,7 @@ my $prefs = preferences('plugin.squeezeesp32'); $prefs->init({ width => 128, + spectrum_scale => 50, }); my $log = Slim::Utils::Log->addLogCategory({ diff --git a/plugin/SqueezeESP32/Settings.pm b/plugin/SqueezeESP32/Settings.pm index 0281fb07..4856383d 100644 --- a/plugin/SqueezeESP32/Settings.pm +++ b/plugin/SqueezeESP32/Settings.pm @@ -17,13 +17,14 @@ sub page { } sub prefs { - return (preferences('plugin.SqueezeESP32'), qw(width)); + return (preferences('plugin.SqueezeESP32'), qw(width spectrum_scale)); } sub handler { my ($class, $client, $params, $callback, @args) = @_; $callback->($client, $params, $class->SUPER::handler($client, $params), @args); + $client->update(); } diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml index 548170f5..51365287 100644 --- a/plugin/SqueezeESP32/install.xml +++ b/plugin/SqueezeESP32/install.xml @@ -10,6 +10,6 @@ PLUGIN_SQUEEZEESP32 PLUGIN_SQUEEZEESP32_DESC Plugins::SqueezeESP32::Plugin - 0.10 + 0.11 Philippe diff --git a/plugin/SqueezeESP32/strings.txt b/plugin/SqueezeESP32/strings.txt index ae441532..d51fa50e 100644 --- a/plugin/SqueezeESP32/strings.txt +++ b/plugin/SqueezeESP32/strings.txt @@ -9,3 +9,11 @@ PLUGIN_SQUEEZEESP32_DESC PLUGIN_SQUEEZEESP32_WIDTH EN Screen width + +PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE + EN Spectrum scale + +PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE_DESC + EN Sets the scale factor % of spectrum visualizer by halves for better representation. + EN For example, 50 means that 50% of spectrum is displayed in 1/2 of the screen, so it's linear... + EN But 25 means that only 25% of spectrum is displayed in 1/2 of the screen, so it's a sort of log diff --git a/plugin/repo.xml b/plugin/repo.xml index 81067947..1d31dcdf 100644 --- a/plugin/repo.xml +++ b/plugin/repo.xml @@ -1,10 +1,10 @@ - + https://github.com/sle118/squeezelite-esp32 Philippe - 5a35a7b821e887baf869535f113b8b55bbc52a54 + b923bd7dd412d1897eb8be2dec862f91f1e36dc4 philippe_44@outlook.com SqueezeESP32 additional player id (100) http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip