diff --git a/components/raop/raop_sink.c b/components/raop/raop_sink.c index f5dec762..f87071e7 100644 --- a/components/raop/raop_sink.c +++ b/components/raop/raop_sink.c @@ -170,7 +170,7 @@ static void raop_sink_start(nm_state_t state_id, int sub_state) { esp_netif_get_mac(netif, mac); cmd_handler_chain = raop_cbs.cmd; - LOG_INFO( "Starting Airplay for ip %s with servicename %s", inet_ntoa(ipInfo.ip.addr), sink_name); + LOG_INFO( "starting Airplay for ip %s with servicename %s", inet_ntoa(ipInfo.ip.addr), sink_name); raop = raop_create(ipInfo.ip.addr, sink_name, mac, 0, cmd_handler, raop_cbs.data); free(sink_name); } diff --git a/components/spotify/Shim.cpp b/components/spotify/Shim.cpp index 014d2f0d..c70ec18f 100644 --- a/components/spotify/Shim.cpp +++ b/components/spotify/Shim.cpp @@ -77,7 +77,7 @@ cspotPlayer::cspotPlayer(const char* name, httpd_handle_t server, int port, cspo cJSON *item, *config = config_alloc_get_cjson("cspot_config"); if ((item = cJSON_GetObjectItem(config, "volume")) != NULL) volume = item->valueint; - if ((item = cJSON_GetObjectItem(config, "bitrate")) != NULL) bitrate = item->valueint; + if ((item = cJSON_GetObjectItem(config, "bitrate")) != NULL) bitrate = item->valueint; if ((item = cJSON_GetObjectItem(config, "deviceName") ) != NULL) this->name = item->valuestring; else this->name = name; cJSON_Delete(config); @@ -306,8 +306,9 @@ void cspotPlayer::runTask() { // Register mdns service, for spotify to find us bell::MDNSService::registerService( blob->getDeviceName(), "_spotify-connect", "_tcp", "", serverPort, { {"VERSION", "1.0"}, {"CPath", "/spotify_info"}, {"Stack", "SP"} }); + + CSPOT_LOG(info, "CSpot instance service name %s (id %s)", blob->getDeviceName().c_str(), blob->getDeviceId().c_str()); - static int count = 0; // gone with the wind... while (1) { clientConnected.wait(); diff --git a/components/spotify/cspot_sink.c b/components/spotify/cspot_sink.c index 64d112a5..90340824 100644 --- a/components/spotify/cspot_sink.c +++ b/components/spotify/cspot_sink.c @@ -163,15 +163,11 @@ static bool cmd_handler(cspot_event_t event, ...) { */ static void cspot_sink_start(nm_state_t state_id, int sub_state) { const char *hostname; - uint8_t mac[6]; cmd_handler_chain = cspot_cbs.cmd; network_get_hostname(&hostname); - esp_netif_get_mac(network_get_active_interface(), mac); - for (int i = 0; i < 6; i++) sprintf(deviceId + 2*i, "%02x", mac[i]); - - ESP_LOGI(TAG, "Starting Spotify (CSpot) servicename %s with id %s", hostname, deviceId); + ESP_LOGI(TAG, "starting Spotify on host %s", hostname); int port; httpd_handle_t server = http_get_server(&port); diff --git a/components/squeezelite/equalizer.c b/components/squeezelite/equalizer.c index 371894c4..f823fe19 100644 --- a/components/squeezelite/equalizer.c +++ b/components/squeezelite/equalizer.c @@ -64,13 +64,17 @@ static const float loudness_envelope_coefficients[EQ_BANDS][POLYNOME_COUNT] = { * calculate loudness gains */ static void calculate_loudness(void) { + char trace[EQ_BANDS * 5 + 1]; + size_t n = 0; for (int i = 0; i < EQ_BANDS; i++) { for (int j = 0; j < POLYNOME_COUNT && equalizer.loudness != 0; j++) { equalizer.loudness_gain[i] += loudness_envelope_coefficients[i][j] * pow(equalizer.volume, j); } equalizer.loudness_gain[i] *= equalizer.loudness / 2; + n += sprintf(trace + n, "%.2g%c", equalizer.loudness_gain[i], i < EQ_BANDS ? ',' : '\0'); } + LOG_INFO("loudness %s", trace); } /**************************************************************************************** @@ -211,7 +215,6 @@ void equalizer_process(uint8_t *buf, uint32_t bytes) { esp_equalizer_set_band_value(equalizer.handle, gain, i, 0); esp_equalizer_set_band_value(equalizer.handle, gain, i, 1); active |= gain != 0; - LOG_INFO("EQUALIZER INDEX %u => gain:%.2f, loudness:%.2f,", i, equalizer.gain[i], equalizer.loudness_gain[i]); } // at the end do not activate equalizer if all gain are 0 diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index a0183da8..60335eb1 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -54,11 +54,22 @@ sure that using rate_delay would fix that #define FRAME_BLOCK MAX_SILENCE_FRAMES #define SPDIF_BLOCK 256 -// must have an integer ratio with FRAME_BLOCK (see spdif comment) -#define DMA_SIZE 6144 -// FRAME_BLOCK must be a multiple of DMA_BUF_LEN no matter what -#define DMA_BUF_LEN FRAME_BLOCK -#define DMA_BUF_COUNT (DMA_SIZE / DMA_BUF_LEN) +/* we produce FRAME_BLOCK (2048) per loop of the i2s thread so it's better if they fit + * inside a set of DMA buffer nicely, i.e. DMA_BUF_FRAMES * DMA_BUF_COUNT is a multiple + * of FRAME_BLOCK so that each DMA buffer is filled and we fully empty a FRAME_BLOCK at + * each loop. Because one DMA buffer in esp32 is 4092 or below, when using 16 bits + * samples and 2 channels, the best multiple is 512 (512*2*2=2048) and we use 6 of these. + * In SPDIF, as we virtually use 32 bits per sample, the next proper multiple would + * be 256 but such DMA buffers are too small and this causes stuttering. So we will use + * non-multiples which means that at every loop one DMA buffer will be not fully filled. + * At least, let's make sure it's not a too small amount of samples so 450*4*2=3600 fits + * nicely in one DMA buffer and 2048/450 = 4 buffers + ~1/2 buffer which is acceptable. + */ +#define DMA_BUF_FRAMES 512 +#define DMA_BUF_COUNT 12 + +#define DMA_BUF_FRAMES_SPDIF 450 +#define DMA_BUF_COUNT_SPDIF 7 #define DECLARE_ALL_MIN_MAX \ DECLARE_MIN_MAX(o); \ @@ -262,6 +273,8 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch i2s_config.use_apll = true; #endif i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1 + i2s_config.dma_buf_len = DMA_BUF_FRAMES; + i2s_config.dma_buf_count = DMA_BUF_COUNT; if (strcasestr(device, "spdif")) { spdif.enabled = true; @@ -278,14 +291,14 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch i2s_config.sample_rate = output.current_sample_rate * 2; i2s_config.bits_per_sample = 32; // Normally counted in frames, but 16 sample are transformed into 32 bits in spdif - i2s_config.dma_buf_len = DMA_BUF_LEN / 2; - i2s_config.dma_buf_count = DMA_BUF_COUNT * 2; + i2s_config.dma_buf_len = DMA_BUF_FRAMES_SPDIF; + i2s_config.dma_buf_count = DMA_BUF_COUNT_SPDIF; /* In DMA, we have room for (LEN * COUNT) frames of 32 bits samples that we push at sample_rate * 2. Each of these pseudo-frames is a single true audio frame. So the real depth in true frames is (LEN * COUNT / 2) */ - dma_buf_frames = DMA_BUF_COUNT * DMA_BUF_LEN / 2; + dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count / 2; // silence DAC output if sharing the same ws/bck if (i2s_dac_pin.ws_io_num == i2s_spdif_pin.ws_io_num && i2s_dac_pin.bck_io_num == i2s_spdif_pin.bck_io_num) silent_do = i2s_dac_pin.data_out_num; @@ -297,9 +310,9 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch i2s_config.sample_rate = output.current_sample_rate; i2s_config.bits_per_sample = BYTES_PER_FRAME * 8 / 2; // Counted in frames (but i2s allocates a buffer <= 4092 bytes) - i2s_config.dma_buf_len = DMA_BUF_LEN; + i2s_config.dma_buf_len = DMA_BUF_FRAMES; i2s_config.dma_buf_count = DMA_BUF_COUNT; - dma_buf_frames = DMA_BUF_COUNT * DMA_BUF_LEN; + dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count; // silence SPDIF output silent_do = i2s_spdif_pin.data_out_num;