From b3ff717d328a31d14f14fd26c4ca7a3f7cc8b878 Mon Sep 17 00:00:00 2001 From: Philippe G Date: Thu, 4 Mar 2021 20:30:06 -0800 Subject: [PATCH] 32 bits cleanup --- components/squeezelite/CMakeLists.txt | 1 + components/squeezelite/display.c | 14 ++- components/squeezelite/embedded.h | 13 +- components/squeezelite/output_bt.c | 2 +- components/squeezelite/output_i2s.c | 28 +---- components/squeezelite/output_pack.c | 6 - components/squeezelite/output_visu.c | 10 +- .../plugins/SqueezeESP32/settings/player.html | 114 +++++++++--------- plugin/SqueezeESP32/Player.pm | 30 ++++- plugin/SqueezeESP32/PlayerSettings.pm | 16 +-- plugin/SqueezeESP32/Plugin.pm | 2 +- 11 files changed, 120 insertions(+), 116 deletions(-) diff --git a/components/squeezelite/CMakeLists.txt b/components/squeezelite/CMakeLists.txt index 4795130c..2925111b 100644 --- a/components/squeezelite/CMakeLists.txt +++ b/components/squeezelite/CMakeLists.txt @@ -34,6 +34,7 @@ set_source_files_properties(flac.c ) add_definitions(-DLINKALL -DLOOPBACK -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4) +# add_definitions(-DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=8) add_compile_options (-O3 ) diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index b1ee365f..8678b24b 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -853,8 +853,8 @@ static void visu_update(void) { int mode = visu.mode & ~VISU_ESP32; - // not enough samples - if (visu_export.level < (mode == VISU_VUMETER ? RMS_LEN : FFT_LEN) * 2 && visu_export.running) { + // not enough frames + if (visu_export.level < (mode == VISU_VUMETER ? RMS_LEN : FFT_LEN) && visu_export.running) { pthread_mutex_unlock(&visu_export.mutex); return; } @@ -865,14 +865,14 @@ static void visu_update(void) { if (visu_export.running) { if (mode == VISU_VUMETER) { - s16_t *iptr = visu_export.buffer; + s16_t *iptr = (s16_t*) visu_export.buffer + (BYTES_PER_FRAME / 4) - 1; // calculate sum(L²+R²), try to not overflow at the expense of some precision for (int i = RMS_LEN; --i >= 0;) { visu.bars[0].current += (*iptr * *iptr + (1 << (RMS_LEN_BIT - 2))) >> (RMS_LEN_BIT - 1); - iptr++; + iptr += BYTES_PER_FRAME / 4; visu.bars[1].current += (*iptr * *iptr + (1 << (RMS_LEN_BIT - 2))) >> (RMS_LEN_BIT - 1); - iptr++; + iptr += BYTES_PER_FRAME / 4; } // convert to dB (1 bit remaining for getting X²/N, 60dB dynamic starting from 0dBFS = 3 bits back-off) @@ -882,11 +882,13 @@ static void visu_update(void) { else if (visu.bars[i].current < 0) visu.bars[i].current = 0; } } else { + s16_t *iptr = (s16_t*) visu_export.buffer + (BYTES_PER_FRAME / 4) - 1; // on xtensa/esp32 the floating point FFT takes 1/2 cycles of the fixed point for (int i = 0 ; i < FFT_LEN ; i++) { // don't normalize here, but we are due INT16_MAX and FFT_LEN / 2 / 2 - visu.samples[i * 2 + 0] = (float) (visu_export.buffer[2*i] + visu_export.buffer[2*i + 1]) * visu.hanning[i]; + visu.samples[i * 2 + 0] = (float) (*iptr + *(iptr+BYTES_PER_FRAME/4)) * visu.hanning[i]; visu.samples[i * 2 + 1] = 0; + iptr += 2 * BYTES_PER_FRAME / 4; } // actual FFT that might be less cycle than all the crap below diff --git a/components/squeezelite/embedded.h b/components/squeezelite/embedded.h index f4db7710..23f4384d 100644 --- a/components/squeezelite/embedded.h +++ b/components/squeezelite/embedded.h @@ -22,7 +22,7 @@ typedef int16_t s16_t; typedef int32_t s32_t; typedef int64_t s64_t; typedef unsigned long long u64_t; - + #ifndef PTHREAD_STACK_MIN #define PTHREAD_STACK_MIN 256 #endif @@ -42,7 +42,12 @@ typedef unsigned long long u64_t; #define PLAYER_ID custom_player_id extern u8_t custom_player_id; -#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Balance=1,Firmware=" VERSION +#if BYTES_PER_FRAME == 8 +#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Balance=1,Depth=32,Firmware=" VERSION +#else +#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Balance=1,Depth=16,Firmware=" VERSION +#endif + // to force some special buffer attribute #define EXT_BSS __attribute__((section(".ext_ram.bss"))) @@ -78,10 +83,10 @@ u8_t get_battery(void); // must provide 0..15 or define as 0x0 extern struct visu_export_s { pthread_mutex_t mutex; u32_t level, size, rate, gain; - s16_t *buffer; + void *buffer; bool running; } visu_export; -void output_visu_export(s16_t *frames, frames_t out_frames, u32_t rate, bool silence, u32_t gain); +void output_visu_export(void *frames, frames_t out_frames, u32_t rate, bool silence, u32_t gain); void output_visu_init(log_level level); void output_visu_close(void); diff --git a/components/squeezelite/output_bt.c b/components/squeezelite/output_bt.c index 6bb223ac..eed7ba88 100644 --- a/components/squeezelite/output_bt.c +++ b/components/squeezelite/output_bt.c @@ -112,7 +112,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g memcpy(btout + oframes * BYTES_PER_FRAME, buf, out_frames * BYTES_PER_FRAME); } - output_visu_export((s16_t*) (btout + oframes * BYTES_PER_FRAME), out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2); + output_visu_export(btout + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2); oframes += out_frames; diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index a30ed983..53adf37e 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -400,42 +400,18 @@ bool output_volume_i2s(unsigned left, unsigned right) { */ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { -#if BYTES_PER_FRAME == 8 - s32_t *optr; -#endif - if (!silence) { if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) { _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); } -#if BYTES_PER_FRAME == 4 _apply_gain(outputbuf, out_frames, gainL, gainR); memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME); -#else - optr = (s32_t*) outputbuf->readp; -#endif } else { -#if BYTES_PER_FRAME == 4 memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME); -#else - optr = (s32_t*) silencebuf; -#endif } -#if BYTES_PER_FRAME == 8 - IF_DSD( - if (output.outfmt == DOP) { - update_dop((u32_t *) optr, out_frames, output.invert); - } else if (output.outfmt != PCM && output.invert) - dsd_invert((u32_t *) optr, out_frames); - ) - - _scale_and_pack_frames(obuf + oframes * BYTES_PER_FRAME, optr, out_frames, gainL, gainR, output.format); -#endif - - output_visu_export((s16_t*) (obuf + oframes * BYTES_PER_FRAME), out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2); - + output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2); oframes += out_frames; return out_frames; @@ -556,8 +532,10 @@ static void *output_thread_i2s(void *arg) { //return; } +#if BYTES_PER_FRAME == 4 // run equalizer equalizer_process(obuf, oframes * BYTES_PER_FRAME, output.current_sample_rate); +#endif // we assume that here we have been able to entirely fill the DMA buffers if (spdif) { diff --git a/components/squeezelite/output_pack.c b/components/squeezelite/output_pack.c index fb137f6a..c84d7c4e 100644 --- a/components/squeezelite/output_pack.c +++ b/components/squeezelite/output_pack.c @@ -23,14 +23,8 @@ #include "squeezelite.h" -#if BYTES_PER_FRAM == 4 -#define MAX_VAL16 0x7fffffffLL #define MAX_SCALESAMPLE 0x7fffffffffffLL #define MIN_SCALESAMPLE -MAX_SCALESAMPLE -#else -#define MAX_SCALESAMPLE 0x7fffffffffffLL -#define MIN_SCALESAMPLE -MAX_SCALESAMPLE -#endif // inlining these on windows prevents them being linkable... #if !WIN diff --git a/components/squeezelite/output_visu.c b/components/squeezelite/output_visu.c index 2a847a2b..df31006c 100644 --- a/components/squeezelite/output_visu.c +++ b/components/squeezelite/output_visu.c @@ -29,7 +29,7 @@ static struct visu_export_s *visu = &visu_export; static log_level loglevel = lINFO; -void output_visu_export(s16_t *frames, frames_t out_frames, u32_t rate, bool silence, u32_t gain) { +void output_visu_export(void *frames, frames_t out_frames, u32_t rate, bool silence, u32_t gain) { // no data to process if (silence) { @@ -44,10 +44,10 @@ void output_visu_export(s16_t *frames, frames_t out_frames, u32_t rate, bool sil // stuff buffer up and wait for consumer to read it (should reset level) if (visu->level < visu->size) { - u32_t space = min(visu->size - visu->level, out_frames * 2) * 2; + u32_t space = min(visu->size - visu->level, out_frames) * BYTES_PER_FRAME; memcpy(visu->buffer + visu->level, frames, space); - visu->level += space / 2; + visu->level += space / BYTES_PER_FRAME; visu->running = true; visu->rate = rate ? rate : 44100; visu->gain = gain; @@ -71,7 +71,7 @@ void output_visu_init(log_level level) { visu->size = VISUEXPORT_SIZE; visu->running = false; visu->rate = 44100; - visu->buffer = malloc(VISUEXPORT_SIZE * sizeof(s16_t) * 2); - LOG_INFO("Initialize VISUEXPORT %u 16 bits samples", VISUEXPORT_SIZE); + visu->buffer = malloc(VISUEXPORT_SIZE * BYTES_PER_FRAME); + LOG_INFO("Initialize VISUEXPORT %u %u bits samples", VISUEXPORT_SIZE, BYTES_PER_FRAME * 4); } diff --git a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html b/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html index 0bcc15f4..fd07f991 100644 --- a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html +++ b/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html @@ -38,67 +38,69 @@
[% END %] - [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_EQUALIZER" desc="" %] -
[% "PLUGIN_SQUEEZEESP32_EQUALIZER_SAVE" | string %]
- [% END %] + [% IF pref_equalizer %] + [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_EQUALIZER" desc="" %] +
[% "PLUGIN_SQUEEZEESP32_EQUALIZER_SAVE" | string %]
+ [% END %] - - [% WRAPPER settingSection %] - [% WRAPPER settingGroup title='31Hz' desc="" %] + + [% WRAPPER settingSection %] + [% WRAPPER settingGroup title='31Hz' desc="" %] + [% END %] + [% WRAPPER settingGroup title='62Hz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='125Hz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='250Hz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='500Hz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='1kHz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='2kHz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='4kHz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='8kHz' desc="" %] + + [% END %] + [% WRAPPER settingGroup title='16kHz' desc="" %] + + [% END %] [% END %] - [% WRAPPER settingGroup title='62Hz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='125Hz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='250Hz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='500Hz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='1kHz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='2kHz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='4kHz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='8kHz' desc="" %] - - [% END %] - [% WRAPPER settingGroup title='16kHz' desc="" %] - - [% END %] - [% END %] + [% END %] [% PROCESS settings/footer.html %] diff --git a/plugin/SqueezeESP32/Player.pm b/plugin/SqueezeESP32/Player.pm index 2f97ba6f..158d1395 100644 --- a/plugin/SqueezeESP32/Player.pm +++ b/plugin/SqueezeESP32/Player.pm @@ -14,7 +14,7 @@ my $prefs = preferences('plugin.squeezeesp32'); my $log = logger('plugin.squeezeesp32'); { - __PACKAGE__->mk_accessor('rw', 'tone_update'); + __PACKAGE__->mk_accessor('rw', qw(tone_update depth)); } sub new { @@ -64,6 +64,10 @@ sub minBass { -13 } sub init { my $client = shift; + my ($id, $caps) = @_; + + my ($depth) = $caps =~ /Depth=(\d+)/; + $client->depth($depth || 16); if (!$handlersAdded) { @@ -107,6 +111,22 @@ sub initPrefs { $client->SUPER::initPrefs; } +sub power { + my $client = shift; + my $on = shift; + + my $res = $client->SUPER::power($on, @_); + return $res unless defined $on; + + if ($on) { + $client->update_artwork(1); + } else { + $client->clear_artwork(1); + } + + return $res; +} + # Allow the player to define it's display width (and probably more) sub playerSettingsFrame { my $client = shift; @@ -232,16 +252,16 @@ sub send_artwork { } sub clear_artwork { - my ($client, $request) = @_; + my ($client, $force, $from) = @_; my $artwork = $prefs->client($client)->get('artwork'); if ($artwork && $artwork->{'enable'}) { - main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . $request->getRequestString()); + main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . ($from || "")); $client->pluginData('artwork_md5', ''); # refresh screen and disable artwork when artwork was full screen (hack) - if (!$artwork->{'x'} && !$artwork->{'y'}) { - $client->sendFrame(grfa => \("\x00"x4)) unless $artwork->{'x'} || $artwork->{'y'}; + if ((!$artwork->{'x'} && !$artwork->{'y'}) || $force) { + $client->sendFrame(grfa => \("\x00"x4)); $client->display->update; } } diff --git a/plugin/SqueezeESP32/PlayerSettings.pm b/plugin/SqueezeESP32/PlayerSettings.pm index b2bbf166..e1619200 100644 --- a/plugin/SqueezeESP32/PlayerSettings.pm +++ b/plugin/SqueezeESP32/PlayerSettings.pm @@ -76,12 +76,14 @@ sub handler { } - my $equalizer = $cprefs->get('equalizer'); - for my $i (0 .. $#{$equalizer}) { - $equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0; - } - $cprefs->set('equalizer', $equalizer); - $client->update_tones($equalizer); + if ($client->depth == 16) { + my $equalizer = $cprefs->get('equalizer'); + for my $i (0 .. $#{$equalizer}) { + $equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0; + } + $cprefs->set('equalizer', $equalizer); + $client->update_tones($equalizer); + } } if ($client->displayWidth) { @@ -91,7 +93,7 @@ sub handler { $paramRef->{'pref_artwork'} = $cprefs->get('artwork'); } - $paramRef->{'pref_equalizer'} = $cprefs->get('equalizer'); + $paramRef->{'pref_equalizer'} = $cprefs->get('equalizer') if $client->depth == 16; return $class->SUPER::handler($client, $paramRef); } diff --git a/plugin/SqueezeESP32/Plugin.pm b/plugin/SqueezeESP32/Plugin.pm index d5a0158b..5b203617 100644 --- a/plugin/SqueezeESP32/Plugin.pm +++ b/plugin/SqueezeESP32/Plugin.pm @@ -65,7 +65,7 @@ sub onStopClear { my $client = $request->client || return; if ($client->isa('Plugins::SqueezeESP32::Player')) { - $client->clear_artwork($request); + $client->clear_artwork(0, $request->getRequestString()); } }