From bb81d4fb55f6da25ae5fe0766b2d84801b594030 Mon Sep 17 00:00:00 2001 From: Wizmo2 Date: Fri, 10 Nov 2023 15:18:33 -0500 Subject: [PATCH] merge remote/master --- CHANGELOG | 23 +++++ Dockerfile | 4 + README.md | 16 +-- components/led_strip/led_strip.c | 3 - components/platform_config/platform_config.c | 2 +- components/platform_config/platform_config.h | 2 +- components/platform_console/cmd_system.c | 15 +-- components/platform_console/cmd_wifi.c | 4 +- components/services/accessors.h | 2 +- .../nanopb/generator/nanopb_generator.py | 0 .../nanopb/generator/nanopb_generator.py2 | 0 .../bell/external/nanopb/generator/protoc | 0 .../nanopb/generator/protoc-gen-nanopb | 0 .../spotify/cspot/include/TrackPlayer.h | 1 - components/spotify/cspot/include/TrackQueue.h | 3 +- components/spotify/cspot/src/SpircHandler.cpp | 14 +-- components/spotify/cspot/src/TrackPlayer.cpp | 2 + components/spotify/cspot/src/TrackQueue.cpp | 28 ++++-- components/squeezelite/displayer.c | 2 +- .../squeezelite/external/dac_external.c | 2 +- components/squeezelite/opus.c | 16 +-- components/squeezelite/slimproto.c | 4 +- components/squeezelite/vorbis.c | 39 +++++--- components/wifi-manager/webapp/src/bootswatch | 1 - docker/ToggleGitTracking.ps1 | 91 ++++++++++++++++++ main/esp_app_main.c | 3 +- plugin/SqueezeESP32.zip | Bin 21192 -> 21255 bytes plugin/SqueezeESP32/install.xml | 2 +- plugin/repo.xml | 4 +- 29 files changed, 217 insertions(+), 66 deletions(-) mode change 100644 => 100755 components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py mode change 100644 => 100755 components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py2 mode change 100644 => 100755 components/spotify/cspot/bell/external/nanopb/generator/protoc mode change 100644 => 100755 components/spotify/cspot/bell/external/nanopb/generator/protoc-gen-nanopb delete mode 160000 components/wifi-manager/webapp/src/bootswatch create mode 100644 docker/ToggleGitTracking.ps1 diff --git a/CHANGELOG b/CHANGELOG index b50d1f6ab..d7f348162 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,26 @@ +2023-11-09 + - force gpio_pad_select_gpio in dac_controlset in case somebody uses UART gpio's (or other pre-programmed) + +2023-11-08 + - execute dac_controlset even whne there is no i2s (for gpio) + +2023-11-07 + - led-vu gain + misc fixes + - bump plugin version to 0.600 + +2023-11-03 + - don't reboot when external decoder is connected even with a LMS server + +2023-10-28 + - fix recovery size (remove bootstrap) + - improve NVS initialization structure + +2023-10-27 + - fix vorbis (and opus) memory leak + +2023-10-25 + - fix vorbis codec close + 2023-10-23 - fix Spotify track insertion - [WEB] Allow running without LMS with option "Audio/Disable Squeezelite" diff --git a/Dockerfile b/Dockerfile index fb8815c65..716f93c3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,11 @@ ENV GCC_TOOLS_BASE=/opt/esp/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtens # pushd components/wifi-manager/webapp/ && npm install && npm run-script build && popd # # to run the docker with netwotrk port published on the host: +# (windows) # docker run --rm -p 5000:5000/tcp -v %cd%:/project -w /project -it sle118/squeezelite-esp32-idfv435 +# (linux) +# docker run --rm -p 5000:5000/tcp -v `pwd`:/project -w /project -it sle118/squeezelite-esp32-idfv435 + ARG IDF_CLONE_URL=https://github.com/espressif/esp-idf.git ARG IDF_CLONE_BRANCH_OR_TAG=master diff --git a/README.md b/README.md index ab9cc9021..ba740fa0a 100644 --- a/README.md +++ b/README.md @@ -194,15 +194,19 @@ if "model" is not set or is not recognized, then default "I2S" is used. The opti So far, TAS57xx, TAS5713, AC101, WM8978 and ES8388 are recognized models where the proper init sequence/volume/power controls are sent. For other codecs that might require an I2C commands, please use the parameter "dac_controlset" that allows definition of simple commands to be sent over i2c for init, power, speaker and headset on and off using a JSON syntax: ```json -{ : [ {"reg":,"val":,"mode":|"or"|"and"}, ... {{"reg":,"val":,"mode":|"or"|"and"} ], - : [ {"reg":,"val":,"mode":|"or"|"and"}, ... {{"reg":,"val":,"mode":|"or"|"and"} ], +{ : [ , , ... ], + : [ , , ... ], ... } ``` -Where `` is one of init, poweron, poweroff, speakeron, speakeroff, headseton, headsetoff - -This is standard JSON notation, so if you are not familiar with it, Google is your best friend. Be aware that the '...' means you can have as many entries as you want, it's not part of the syntax. Every section is optional, but it does not make sense to set i2c in the 'dac_config' parameter and not setting anything here. The parameter 'mode' allows to *or* the register with the value or to *and* it. Don't set 'mode' if you simply want to write. The 'val parameter can be an array [v1, v2,...] to write a series of bytes in a single i2c burst (in that case 'mode' is ignored). **Note that all values must be decimal**. You can use a validator like [this](https://jsonlint.com) to verify your syntax +Where `` is one of init, poweron, poweroff, speakeron, speakeroff, headseton, headsetoff (it **must** be an array even for a single item). Item is any of the following elements +``` +{"reg":,"val":,"mode":|"or"|"and"} +{"gpio":,"level":0|1} +{"delay":} +``` +This is standard JSON notation, so if you are not familiar with it, Google is your best friend. Be aware that the '...' means you can have as many entries as you want, it's not part of the syntax. Every section is optional, but it does not make sense to set i2c in the 'dac_config' parameter and not setting anything here. -The 'power' command is used when powering on/off the DAC after the idle period (see -C option of squeezelite) and the 'speaker/headset' commands are sent when switching between speakers and headsets (see headset jack detection). +The `reg` key allow to write registers on i2c bus. The parameter `mode` allows to *or* the register with the value or to *and* it. Don't set `mode` if you simply want to write. The `val` parameter can be an array [v1, v2,...] to write a serie of bytes in a single i2c burst (in that case 'mode' is ignored). **Note that all values must be decimal**. You can use a validator like [this](https://jsonlint.com) to verify your syntax. The `gpio` key is simply to set a gpio as part of DAC action and `delay` allows a pause between elements. The 'power' command is used when powering on/off the DAC after the idle period (see -C option of squeezelite) and the 'speaker/headset' commands are sent when switching between speakers and headsets (see headset jack detection). diff --git a/components/led_strip/led_strip.c b/components/led_strip/led_strip.c index 5441dc237..80d9a0528 100644 --- a/components/led_strip/led_strip.c +++ b/components/led_strip/led_strip.c @@ -391,11 +391,8 @@ bool led_strip_init(struct led_strip_t *led_strip) static EXT_RAM_ATTR StackType_t xStack[LED_STRIP_TASK_SIZE] __attribute__ ((aligned (4))); if ((led_strip == NULL) || - //(led_strip->rmt_channel >= RMT_CHANNEL_MAX) || - //(led_strip->gpio > GPIO_NUM_33) || (led_strip->led_strip_working == NULL) || (led_strip->led_strip_showing == NULL) || - //(led_strip->led_strip_length == 0) || (led_strip->access_semaphore == NULL)) { return false; } diff --git a/components/platform_config/platform_config.c b/components/platform_config/platform_config.c index 3f6c538a1..2753a87d5 100644 --- a/components/platform_config/platform_config.c +++ b/components/platform_config/platform_config.c @@ -538,7 +538,7 @@ bool config_set_group_bit(int bit_num,bool flag){ return result; } -void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size) { +void config_set_default(nvs_type_t type, const char *key, const void * default_value, size_t blob_size) { if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ ESP_LOGE(TAG, "Unable to lock config"); return; diff --git a/components/platform_config/platform_config.h b/components/platform_config/platform_config.h index 9e3aa8037..6af2ecd0e 100644 --- a/components/platform_config/platform_config.h +++ b/components/platform_config/platform_config.h @@ -65,7 +65,7 @@ esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value); esp_err_t config_set_cjson(const char *key, cJSON *value, bool free_cjson); void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value); void config_delete_key(const char *key); -void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size); +void config_set_default(nvs_type_t type, const char *key, const void * default_value, size_t blob_size); void * config_alloc_get(nvs_type_t nvs_type, const char *key) ; bool wait_for_commit(); char * config_alloc_get_json(bool bFormatted); diff --git a/components/platform_console/cmd_system.c b/components/platform_console/cmd_system.c index 5f1cac3e8..d528864bb 100644 --- a/components/platform_console/cmd_system.c +++ b/components/platform_console/cmd_system.c @@ -73,8 +73,10 @@ static void register_heap(); static void register_dump_heap(); static void register_version(); static void register_restart(); +#if CONFIG_WITH_CONFIG_UI static void register_deep_sleep(); static void register_light_sleep(); +#endif static void register_factory_boot(); static void register_restart_ota(); static void register_set_services(); @@ -92,8 +94,8 @@ FILE * system_open_memstream(const char * cmdname,char **buf,size_t *buf_size){ void register_system() { - register_set_services(); register_setdevicename(); + register_set_services(); register_free(); register_heap(); register_dump_heap(); @@ -585,7 +587,7 @@ static void register_tasks() /** 'deep_sleep' command puts the chip into deep sleep mode */ - +#if CONFIG_WITH_CONFIG_UI static struct { struct arg_int *wakeup_time; struct arg_int *wakeup_gpio_num; @@ -649,6 +651,8 @@ static void register_deep_sleep() }; ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); } +#endif + static int enable_disable(FILE * f,char * nvs_name, struct arg_lit *arg){ esp_err_t err = config_set_value(NVS_TYPE_STR, nvs_name, arg->count>0?"Y":"N"); const char * name = arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary; @@ -744,9 +748,6 @@ cJSON * set_services_cb(){ else { cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled"); } -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature_variant("telnet",p); -#endif FREE_AND_NULL(p); } @@ -778,6 +779,8 @@ static void register_set_services(){ cmd_to_json_with_cb(&cmd,&set_services_cb); ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); } + +#if CONFIG_WITH_CONFIG_UI static struct { struct arg_int *wakeup_time; struct arg_int *wakeup_gpio_num; @@ -871,4 +874,4 @@ static void register_light_sleep() }; ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); } - +#endif diff --git a/components/platform_console/cmd_wifi.c b/components/platform_console/cmd_wifi.c index ef0033ecb..e6e32d151 100644 --- a/components/platform_console/cmd_wifi.c +++ b/components/platform_console/cmd_wifi.c @@ -180,10 +180,10 @@ void register_wifi_join() void register_wifi() { - #ifdef WIFI_CMDLINE + #ifdef WIFI_CMDLINE register_wifi_join(); if(bypass_network_manager){ initialise_wifi(); } - #endif +#endif } diff --git a/components/services/accessors.h b/components/services/accessors.h index b0e11238c..7fb312a03 100644 --- a/components/services/accessors.h +++ b/components/services/accessors.h @@ -13,7 +13,7 @@ #include "driver/i2s.h" #include "driver/spi_master.h" #include "gpio_exp.h" - +#include "cJSON.h" extern const char *i2c_name_type; extern const char *spi_name_type; diff --git a/components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py b/components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py old mode 100644 new mode 100755 diff --git a/components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py2 b/components/spotify/cspot/bell/external/nanopb/generator/nanopb_generator.py2 old mode 100644 new mode 100755 diff --git a/components/spotify/cspot/bell/external/nanopb/generator/protoc b/components/spotify/cspot/bell/external/nanopb/generator/protoc old mode 100644 new mode 100755 diff --git a/components/spotify/cspot/bell/external/nanopb/generator/protoc-gen-nanopb b/components/spotify/cspot/bell/external/nanopb/generator/protoc-gen-nanopb old mode 100644 new mode 100755 diff --git a/components/spotify/cspot/include/TrackPlayer.h b/components/spotify/cspot/include/TrackPlayer.h index 31f989397..1577c4767 100644 --- a/components/spotify/cspot/include/TrackPlayer.h +++ b/components/spotify/cspot/include/TrackPlayer.h @@ -37,7 +37,6 @@ class TrackPlayer : bell::Task { typedef std::function DataCallback; typedef std::function EOFCallback; - typedef std::function isAiringCallback; TrackPlayer(std::shared_ptr ctx, std::shared_ptr trackQueue, diff --git a/components/spotify/cspot/include/TrackQueue.h b/components/spotify/cspot/include/TrackQueue.h index 174d51af1..60c1d3185 100644 --- a/components/spotify/cspot/include/TrackQueue.h +++ b/components/spotify/cspot/include/TrackQueue.h @@ -54,6 +54,7 @@ class QueuedTrack { uint32_t requestedPosition; std::string identifier; + bool loading = false; // Will return nullptr if the track is not ready std::shared_ptr getAudioFile(); @@ -100,7 +101,7 @@ class TrackQueue : public bell::Task { bool hasTracks(); bool isFinished(); bool skipTrack(SkipDirection dir, bool expectNotify = true); - void updateTracks(uint32_t requestedPosition = 0, bool initial = false); + bool updateTracks(uint32_t requestedPosition = 0, bool initial = false); TrackInfo getTrackInfo(std::string_view identifier); std::shared_ptr consumeTrack( std::shared_ptr prevSong, int& offset); diff --git a/components/spotify/cspot/src/SpircHandler.cpp b/components/spotify/cspot/src/SpircHandler.cpp index 8f225b76e..92531a641 100644 --- a/components/spotify/cspot/src/SpircHandler.cpp +++ b/components/spotify/cspot/src/SpircHandler.cpp @@ -205,16 +205,18 @@ void SpircHandler::handleFrame(std::vector& data) { playbackState->syncWithRemote(); // 1st track is the current one, but update the position - trackQueue->updateTracks( + bool cleared = trackQueue->updateTracks( playbackState->remoteFrame.state.position_ms + - ctx->timeProvider->getSyncedTimestamp() - - playbackState->innerFrame.state.position_measured_at, - false); + ctx->timeProvider->getSyncedTimestamp() - + playbackState->innerFrame.state.position_measured_at); this->notify(); - sendEvent(EventType::FLUSH); - trackPlayer->resetState(); + // need to re-load all if streaming track is completed + if (cleared) { + sendEvent(EventType::FLUSH); + trackPlayer->resetState(); + } break; } case MessageType_kMessageTypeShuffle: { diff --git a/components/spotify/cspot/src/TrackPlayer.cpp b/components/spotify/cspot/src/TrackPlayer.cpp index a252b3cbf..c96f2ec7d 100644 --- a/components/spotify/cspot/src/TrackPlayer.cpp +++ b/components/spotify/cspot/src/TrackPlayer.cpp @@ -201,6 +201,7 @@ void TrackPlayer::runTask() { } eof = false; + track->loading = true; CSPOT_LOG(info, "Playing"); @@ -255,6 +256,7 @@ void TrackPlayer::runTask() { // always move back to LOADING (ensure proper seeking after last track has been loaded) currentTrackStream = nullptr; + track->loading = false; } if (eof) { diff --git a/components/spotify/cspot/src/TrackQueue.cpp b/components/spotify/cspot/src/TrackQueue.cpp index b859539f9..5c416bbe3 100644 --- a/components/spotify/cspot/src/TrackQueue.cpp +++ b/components/spotify/cspot/src/TrackQueue.cpp @@ -587,8 +587,9 @@ bool TrackQueue::isFinished() { return currentTracksIndex >= currentTracks.size() - 1; } -void TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) { +bool TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) { std::scoped_lock lock(tracksMutex); + bool cleared = true; if (initial) { // Clear preloaded tracks @@ -609,13 +610,28 @@ void TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) { playableSemaphore->give(); } else { - // Clear preloaded tracks - preloadedTracks.clear(); - // Copy requested track list currentTracks = playbackState->remoteTracks; - // Push a song on the preloaded queue - queueNextTrack(0, requestedPosition); + // try to not re-load track if we are still loading it + if (preloadedTracks[0]->loading) { + // remove everything except first track + preloadedTracks.erase(preloadedTracks.begin() + 1, preloadedTracks.end()); + + // Push a song on the preloaded queue + CSPOT_LOG(info, "Keeping current track"); + queueNextTrack(1); + + cleared = false; + } else { + // Clear preloaded tracks + preloadedTracks.clear(); + + // Push a song on the preloaded queue + CSPOT_LOG(info, "Re-loading current track"); + queueNextTrack(0, requestedPosition); + } } + + return cleared; } diff --git a/components/squeezelite/displayer.c b/components/squeezelite/displayer.c index 3d07af517..99940cc8e 100644 --- a/components/squeezelite/displayer.c +++ b/components/squeezelite/displayer.c @@ -1295,7 +1295,7 @@ static void ledv_handler( u8_t *data, int len) { LOG_INFO("LED Visualizer mode %u with bars:%u max:%u style:%d gain:%u", led_visu.mode, led_visu.n, led_visu.max, led_visu.style, led_visu.gain); } else { - led_vu_clear(); + led_vu_clear(); LOG_INFO("Stopping led visualizer"); } diff --git a/components/squeezelite/external/dac_external.c b/components/squeezelite/external/dac_external.c index d9eb81896..08f182340 100644 --- a/components/squeezelite/external/dac_external.c +++ b/components/squeezelite/external/dac_external.c @@ -61,7 +61,6 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool char *p; i2c_addr = adac_init(config, i2c_port_num); - if (!i2c_addr) return true; ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr); @@ -137,6 +136,7 @@ bool i2c_json_execute(char *set) { if ((action = cJSON_GetObjectItemCaseSensitive(item, "gpio")) != NULL) { cJSON *level = cJSON_GetObjectItemCaseSensitive(item, "level"); ESP_LOGI(TAG, "set GPIO %d at %d", action->valueint, level->valueint); + if (action->valueint < GPIO_NUM_MAX) gpio_pad_select_gpio(action->valueint); gpio_set_direction_x(action->valueint, GPIO_MODE_OUTPUT); gpio_set_level_x(action->valueint, level->valueint); continue; diff --git a/components/squeezelite/opus.c b/components/squeezelite/opus.c index ec13d62d8..0086c3f0e 100644 --- a/components/squeezelite/opus.c +++ b/components/squeezelite/opus.c @@ -186,7 +186,7 @@ static int read_opus_header(void) { switch (u->status) { case OGG_SYNC: u->status = OGG_ID_HEADER; - OG(&gu, stream_init, &u->state, OG(&gu, page_serialno, &u->page)); + OG(&gu, stream_reset_serialno, &u->state, OG(&gu, page_serialno, &u->page)); fetch = false; break; case OGG_ID_HEADER: @@ -359,10 +359,10 @@ static void opus_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { u->status = OGG_SYNC; u->overframes = 0; - - OG(&gu, sync_clear, &u->sync); - OG(&gu, stream_clear, &u->state); - OG(&gu, stream_init, &u->state, -1); + + OG(&go, stream_clear, &u->state); + OG(&go, sync_clear, &u->sync); + OG(&go, stream_init, &u->state, -1); } static void opus_close(void) { @@ -372,8 +372,8 @@ static void opus_close(void) { free(u->overbuf); u->overbuf = NULL; - OG(&gu, stream_clear, &u->state); - OG(&gu, sync_clear, &u->sync); + OG(&go, stream_clear, &u->state); + OG(&go, sync_clear, &u->sync); } static bool load_opus(void) { @@ -394,7 +394,7 @@ static bool load_opus(void) { } g_handle->ogg_stream_clear = dlsym(g_handle->handle, "ogg_stream_clear"); - g_handle->.ogg_stream_reset = dlsym(g_handle->handle, "ogg_stream_reset"); + g_handle->ogg_stream_reset = dlsym(g_handle->handle, "ogg_stream_reset"); g_handle->ogg_stream_eos = dlsym(g_handle->handle, "ogg_stream_eos"); g_handle->ogg_stream_reset_serialno = dlsym(g_handle->handle, "ogg_stream_reset_serialno"); g_handle->ogg_sync_clear = dlsym(g_handle->handle, "ogg_sync_clear"); diff --git a/components/squeezelite/slimproto.c b/components/squeezelite/slimproto.c index 5cbc78b02..f053684ed 100644 --- a/components/squeezelite/slimproto.c +++ b/components/squeezelite/slimproto.c @@ -984,8 +984,8 @@ void slimproto(log_level level, char *server, u8_t mac[6], const char *name, con // in embedded we give up after a while no matter what if (++failed_connect > MAX_SERVER_RETRIES && !server) { slimproto_ip = serv_addr.sin_addr.s_addr = discover_server(NULL, MAX_SERVER_RETRIES); - if (!slimproto_ip) return; - } else if (reconnect && MAX_SERVER_RETRIES && failed_connect > 5 * MAX_SERVER_RETRIES) return; + if (!slimproto_ip && !output.external) return; + } else if (reconnect && MAX_SERVER_RETRIES && failed_connect > 5 * MAX_SERVER_RETRIES && !output.external) return; #else // rediscover server if it was not set at startup or exit if (!server && ++failed_connect > 5) { diff --git a/components/squeezelite/vorbis.c b/components/squeezelite/vorbis.c index 5c1ebeb81..1a3f6e80f 100644 --- a/components/squeezelite/vorbis.c +++ b/components/squeezelite/vorbis.c @@ -72,6 +72,13 @@ static struct vorbis { // vorbis symbols to be dynamically loaded - from either vorbisfile or vorbisidec (tremor) version of library vorbis_info *(* ov_info)(OggVorbis_File *vf, int link); int (* ov_clear)(OggVorbis_File *vf); + void (* ov_info_init)(vorbis_info* vi); + void (* ov_info_clear)(vorbis_info* vi); + void (* ov_comment_init)(vorbis_comment* vc); + void (* ov_comment_clear(vorbis_comment *vc); + int (* ov_block_init)(vorbis_dsp_state* v, vorbis_block* vb); + int (* ov_block_clear)(vorbis_block* vb); + void (* ov_vorbis_dsp_clear)(vorbis_dsp_state* v); long (* ov_read)(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream); long (* ov_read_tremor)(OggVorbis_File *vf, char *buffer, int length, int *bitstream); int (* ov_open_callbacks)(void *datasource, OggVorbis_File *vf, const char *initial, long ibytes, ov_callbacks callbacks); @@ -396,33 +403,32 @@ static decode_state vorbis_decode(void) { } static void vorbis_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { - LOG_INFO("OPENING CODEC"); if (v->opened) { - OV(&go, block_clear, &v->block); - OV(&go, info_clear, &v->info); - OV(&go, dsp_clear, &v->decoder); + OV(&gv, block_clear, &v->block); + OV(&gv, dsp_clear, &v->decoder); + OV(&gv, info_clear, &v->info); } v->opened = false; v->status = OGG_SYNC; v->overflow = 0; - - OG(&gu, sync_clear, &v->sync); - OG(&gu, stream_clear, &v->state); - OG(&gu, stream_init, &v->state, -1); + + OG(&go, stream_clear, &v->state); + OG(&go, sync_clear, &v->sync); + OG(&go, stream_init, &v->state, -1); } static void vorbis_close() { - return; - LOG_INFO("CLOSING CODEC"); if (v->opened) { - OV(&go, block_clear, &v->block); - OV(&go, info_clear, &v->info); - OV(&go, dsp_clear, &v->decoder); + OV(&gv, block_clear, &v->block); + OV(&gv, dsp_clear, &v->decoder); + // info must be last otherwise there is memory leak (where is it said... nowhere) + OV(&gv, info_clear, &v->info); + // we don' t have comments to free } v->opened = false; - + OG(&go, stream_clear, &v->state); OG(&go, sync_clear, &v->sync); } @@ -469,6 +475,11 @@ static bool load_vorbis() { v_handle.ov_read = dlsym(handle, "ov_read"); v_handle.ov_info = dlsym(handle, "ov_info"); v_handle.ov_clear = dlsym(handle, "ov_clear"); + v.handle.ov_info_clear = dlsym(gv.handle, "vorbis_info_clear"); + v.handle.ov_comment_init = dlsym(gv.handle, "vorbis_comment_init"); + v.handle.ov_comment_clear = dlsym(gv.handle, "vorbis_comment_clear"); + v.handle.ov_block_init = dlsym(gv.handle, "vorbis_block_init"); + v.handle.ov_block_clear = dlsym(gv.handle, "vorbis_block_clear"); v_handle.ov_open_callbacks = dlsym(handle, "ov_open_callbacks"); if ((err = dlerror()) != NULL) { diff --git a/components/wifi-manager/webapp/src/bootswatch b/components/wifi-manager/webapp/src/bootswatch deleted file mode 160000 index 3038872b8..000000000 --- a/components/wifi-manager/webapp/src/bootswatch +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3038872b8389763b64857bac00e102a71251a331 diff --git a/docker/ToggleGitTracking.ps1 b/docker/ToggleGitTracking.ps1 new file mode 100644 index 000000000..73c5c9b73 --- /dev/null +++ b/docker/ToggleGitTracking.ps1 @@ -0,0 +1,91 @@ +param ( + [Parameter(Position=0, Mandatory=$false)] + [ValidateSet("t", "u", "d")] + [string]$option +) + +# Get the current directory +$currentDir = Get-Location + +# Define target directories +$targetDir = "components\wifi-manager\webapp" +$distDir = "$targetDir\dist" + +# Get list of files from the 'dist' directory +$fsFiles = Get-ChildItem -Recurse $distDir -File | ForEach-Object { + $_.FullName.Substring($currentDir.Path.Length + 1).Replace("\", "/") +} + +# Define additional files to include +$additionalFiles = @("webpack.c", "webpack.h", "webapp.cmake") + +# Check if additional files exist in $targetDir and format them +$additionalFilesFormatted = @() +Get-ChildItem $targetDir -File | ForEach-Object { + if ($additionalFiles -contains $_.Name) { + $formatted = $_.FullName.Substring($currentDir.Path.Length + 1).Replace("\", "/") + $additionalFilesFormatted += $formatted + Write-Host "Found $formatted" + } +} + +# Get list of files from the Git index +$indexFiles = git ls-files -s $distDir | ForEach-Object { + ($_ -split "\s+")[3] +} + +# Combine and remove duplicates +$allFiles = $fsFiles + $additionalFilesFormatted + $indexFiles | Sort-Object -Unique +# ... (previous code remains unchanged) + +# Apply the git command based on the option +$allFiles | ForEach-Object { + $relativePath = $_ + $isInIndex = $indexFiles -contains $relativePath + + if ($null -eq $option) { + $gitStatus = & git status --porcelain -- $relativePath + if ($gitStatus) { + $status = ($gitStatus -split "\s")[0] + Write-Host "$relativePath has Git status: $status" + } else { + Write-Host "$relativePath is not tracked" + } + } + elseif ($isInIndex) { + if ($option -eq "d") { + $resetResult = & git reset -- $relativePath 2>&1 + if ($resetResult -match 'error:') { + Write-Host "Error resetting ${relativePath}: $resetResult" + + continue + } + $checkoutResult = & git checkout -- $relativePath 2>&1 + if ($checkoutResult -match 'error:') { + Write-Host "Error checking out ${relativePath}: $checkoutResult" + + continue + } + Write-Host "Discarded changes in $relativePath" + } + # ... (rest of the code remains unchanged) + } + # else { + # # if ($option -eq "d") { + # # Remove-Item -Path $relativePath -Force + # # Write-Host "Removed untracked file $relativePath" + # # } else { + # # Write-Host "File $relativePath is not tracked." + # # } + + # } + else { + if ($option -eq "t") { + git add $relativePath + git update-index --no-skip-worktree $relativePath + Write-Host "Started tracking changes in $relativePath" + } else { + Write-Host "File $relativePath is not tracked." + } + } +} diff --git a/main/esp_app_main.c b/main/esp_app_main.c index 0b805169b..7f3d6a408 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -297,7 +297,6 @@ void register_default_nvs(){ else { register_default_string_val("cspot_config", ""); } - } #endif @@ -309,7 +308,7 @@ void register_default_nvs(){ #endif register_default_with_mac("host_name", DEFAULT_HOST_NAME); register_default_with_mac("ap_ssid", CONFIG_DEFAULT_AP_SSID); -for (int i = 0; i < sizeof(defaultStringVals) / sizeof(DefaultStringVal); ++i) { + for (int i = 0; i < sizeof(defaultStringVals) / sizeof(DefaultStringVal); ++i) { register_default_string_val(defaultStringVals[i].key, defaultStringVals[i].value); } for (int i = 0; i < sizeof(defaultNumVals) / sizeof(DefaultNumVal); ++i) { diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip index 45851b1b3c71cab65364908ae1e35540bdd257c1..155aea376c567cb71bc943d7cc00ef71fffc0198 100644 GIT binary patch delta 9404 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 I@t;-yKZTfucK`qY delta 9226 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 diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml index 278a50b34..ce8c682c1 100644 --- a/plugin/SqueezeESP32/install.xml +++ b/plugin/SqueezeESP32/install.xml @@ -10,6 +10,6 @@ PLUGIN_SQUEEZEESP32 PLUGIN_SQUEEZEESP32_DESC Plugins::SqueezeESP32::Plugin - 0.501 + 0.600 Philippe diff --git a/plugin/repo.xml b/plugin/repo.xml index 132d4a8ca..df5527bef 100644 --- a/plugin/repo.xml +++ b/plugin/repo.xml @@ -1,10 +1,10 @@ - + https://github.com/sle118/squeezelite-esp32 Philippe - 842ee0f7b8ccaf2e6df4a741565068f9e4c7a27e + 335b585e22eddbddacce00f34001d8bf2ee0f54f philippe_44@outlook.com SqueezeESP32 additional player id (100/101) http://raw.githubusercontent.com/sle118/squeezelite-esp32/master-v4.3/plugin/SqueezeESP32.zip