diff --git a/README.md b/README.md index 73b17b7a..9cf1f058 100644 --- a/README.md +++ b/README.md @@ -147,3 +147,4 @@ See squeezlite command line, but keys options are - LINKALL (mandatory) - NO_FAAD unless you want to us faad, which currently overloads the CPU - TREMOR_ONLY (mandatory) + diff --git a/components/cmd_system/cmd_system.c b/components/cmd_system/cmd_system.c index b73e845a..6ccb04c5 100644 --- a/components/cmd_system/cmd_system.c +++ b/components/cmd_system/cmd_system.c @@ -102,6 +102,9 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype) #if RECOVERY_APPLICATION if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){ ESP_LOGW(TAG,"RECOVERY application is already active"); + if(!wait_for_commit()){ + ESP_LOGW(TAG,"Unable to commit configuration. "); + } ESP_LOGW(TAG, "Restarting after tx complete"); uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); esp_restart(); @@ -110,6 +113,9 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype) #else if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){ ESP_LOGW(TAG,"SQUEEZELITE application is already active"); + if(!wait_for_commit()){ + ESP_LOGW(TAG,"Unable to commit configuration. "); + } ESP_LOGW(TAG, "Restarting after tx complete"); uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); esp_restart(); diff --git a/components/squeezelite-ota/squeezelite-ota.c b/components/squeezelite-ota/squeezelite-ota.c index 4f9dcbd7..af5f150f 100644 --- a/components/squeezelite-ota/squeezelite-ota.c +++ b/components/squeezelite-ota/squeezelite-ota.c @@ -284,7 +284,7 @@ static bool process_again(int status_code) } static esp_err_t _http_handle_response_code(esp_http_client_handle_t http_client, int status_code) { - esp_err_t err; + esp_err_t err=ESP_OK; if (status_code == HttpStatus_MovedPermanently || status_code == HttpStatus_Found) { ESP_LOGW(TAG, "Handling HTTP redirection. "); err = esp_http_client_set_redirection(http_client); diff --git a/components/squeezelite/decode_external.c b/components/squeezelite/decode_external.c index 13240138..211b775e 100644 --- a/components/squeezelite/decode_external.c +++ b/components/squeezelite/decode_external.c @@ -41,15 +41,16 @@ extern log_level loglevel; bool enable_bt_sink = false; bool enable_airplay = false; -#define RAOP_OUTPUT_SIZE (RAOP_SAMPLE_RATE * 2 * 2 * 2 * 1.2) +#define RAOP_OUTPUT_SIZE (RAOP_SAMPLE_RATE * 2 * 2 * 2 * 1.2) +#define SYNC_NB 5 static raop_event_t raop_state; static bool raop_expect_stop = false; static struct { bool enabled, start; - s32_t error; - u32_t start_time; - u32_t playtime, len; + s32_t error[SYNC_NB]; + u32_t idx, len; + u32_t start_time, playtime; } raop_sync; /**************************************************************************************** @@ -185,7 +186,7 @@ void raop_sink_cmd_handler(raop_event_t event, void *param) switch (event) { case RAOP_TIMING: { u32_t ms, now = gettime_ms(); - s32_t error; + s32_t sync_nb, error = 0; if (!raop_sync.enabled || output.state < OUTPUT_RUNNING || output.frames_played_dmp < output.device_frames) break; @@ -193,31 +194,39 @@ void raop_sink_cmd_handler(raop_event_t event, void *param) if (raop_sync.start) { // how many ms have we really played ms = now - output.updated + ((u64_t) (output.frames_played_dmp - output.device_frames) * 1000) / RAOP_SAMPLE_RATE; - error = ms - (now - raop_sync.start_time); - LOG_DEBUG("backend played %u, desired %u, (delta:%d)", ms, now - raop_sync.start_time, error); - if (abs(error) < 10 && abs(raop_sync.error) < 10) raop_sync.start = false; + raop_sync.error[raop_sync.idx] = ms - (now - raop_sync.start_time); + sync_nb = 2; + LOG_INFO("backend played %u, desired %u, (delta:%d)", ms, now - raop_sync.start_time, raop_sync.error[raop_sync.idx]); } else { // in how many ms will the most recent block play ms = ((u64_t) ((_buf_used(outputbuf) - raop_sync.len) / BYTES_PER_FRAME + output.device_frames + output.frames_in_process) * 1000) / RAOP_SAMPLE_RATE - (now - output.updated); - error = (raop_sync.playtime - now) - ms; - LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error); + raop_sync.error[raop_sync.idx] = (raop_sync.playtime - now) - ms; + sync_nb = SYNC_NB; + LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, raop_sync.error[raop_sync.idx]); LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process); } - // TODO: better sync logic - if (error < -10 && raop_sync.error < -10) { - output.skip_frames = (abs(error + raop_sync.error) / 2 * RAOP_SAMPLE_RATE) / 1000; + // calculate the average error + for (int i = 0; i < sync_nb; i++) error += raop_sync.error[i]; + error /= sync_nb; + raop_sync.idx = (raop_sync.idx + 1) % sync_nb; + + // need at least nb_sync measures done to exit quick mode + if (raop_sync.start && !raop_sync.idx && abs(error) < 10) raop_sync.start = false; + + // correct if needed + if (error < -10) { + output.skip_frames = (abs(error) * RAOP_SAMPLE_RATE) / 1000; output.state = OUTPUT_SKIP_FRAMES; - raop_sync.error = 0; + memset(raop_sync.error, 0, sizeof(raop_sync.error)); LOG_INFO("skipping %u frames", output.skip_frames); - } else if (error > 10 && raop_sync.error > 10) { - output.pause_frames = (abs(error + raop_sync.error) / 2 * RAOP_SAMPLE_RATE) / 1000; + } else if (error > 10) { + output.pause_frames = (abs(error) * RAOP_SAMPLE_RATE) / 1000; output.state = OUTPUT_PAUSE_FRAMES; - raop_sync.error = 0; + memset(raop_sync.error, 0, sizeof(raop_sync.error)); LOG_INFO("pausing for %u frames", output.pause_frames); } - raop_sync.error = error; break; } case RAOP_SETUP: @@ -228,7 +237,8 @@ void raop_sink_cmd_handler(raop_event_t event, void *param) case RAOP_STREAM: LOG_INFO("Stream", NULL); raop_state = event; - raop_sync.error = 0; + memset(raop_sync.error, 0, sizeof(raop_sync.error)); + raop_sync.idx = 0; raop_sync.start = true; raop_sync.enabled = !strcasestr(output.device, "BT"); output.external = DECODE_AIRPLAY; diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index 719c0d46..047b9122 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -452,7 +452,7 @@ static void *output_thread_i2s() { while (running) { TIME_MEASUREMENT_START(timer_start); - +#ifdef TAS57xx // handle jack insertion as a polling function (to avoid to have to do de-bouncing) if (gpio_get_level(JACK_GPIO) != jack_status) { jack_status = gpio_get_level(JACK_GPIO); @@ -461,7 +461,7 @@ static void *output_thread_i2s() { LOG_INFO("Changing jack status %d", jack_status); } } - +#endif LOCK; // manage led display @@ -644,20 +644,22 @@ void dac_cmd(dac_cmd_e cmd, ...) { /**************************************************************************************** * Analogue mute */ +#ifdef TAS57xx static void set_analogue(bool active) { -#ifdef TAS57xx + dac_cmd(DAC_STANDBY); // need to wait a bit for TAS to execute standby before sending backend-down command usleep(50*1000); dac_cmd(active ? DAC_ANALOG_UP : DAC_ANALOG_DOWN); dac_cmd(DAC_ACTIVE); -#endif } - +#endif /**************************************************************************************** * TAS57 detection */ +#ifdef TAS57xx static int tas57_detect(void) { + u8_t data, addr[] = {0x90, 0x98}; int ret; @@ -681,9 +683,10 @@ static int tas57_detect(void) { return addr[i]; } } - + return 0; -} +} +#endif /**************************************************************************************** * SPDIF support diff --git a/components/wifi-manager/code.js b/components/wifi-manager/code.js index 7036e470..d14c2914 100644 --- a/components/wifi-manager/code.js +++ b/components/wifi-manager/code.js @@ -343,7 +343,7 @@ $(document).ready(function(){ }); $("#generate-command").on("click", function() { - var commandLine = commandHeader + '-n ' + $("#player").val(); + var commandLine = commandHeader + '-n "' + $("#player").val() + '"'; if (output == 'bt') { commandLine += ' -o "BT -n \'' + $("#btsink").val() + '\'" -R -Z 192000'; diff --git a/main/console.c b/main/console.c index e5c4ad41..6ccd2e0a 100644 --- a/main/console.c +++ b/main/console.c @@ -57,7 +57,7 @@ void process_autoexec(){ char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec"); if(!bypass_wifi_manager){ - ESP_LOGW(TAG, "Procesing autoexec commands while wifi_manager active. Wifi related commands will be ignored."); + ESP_LOGW(TAG, "Processing autoexec commands while wifi_manager active. Wifi related commands will be ignored."); } #if RECOVERY_APPLICATION ESP_LOGD(TAG, "Processing autoexec commands in recovery mode. Squeezelite commands will be ignored.");