diff --git a/components/raop/rtp.c b/components/raop/rtp.c index 9b797116..b97c3b62 100644 --- a/components/raop/rtp.c +++ b/components/raop/rtp.c @@ -551,7 +551,7 @@ static void *rtp_thread_func(void *arg) { socklen_t rtp_client_len = sizeof(struct sockaddr_storage); int idx = 0; char *pktp = packet; - struct timeval timeout = {0, 50*1000}; + struct timeval timeout = {0, 100*1000}; FD_ZERO(&fds); for (i = 0; i < 3; i++) { FD_SET(ctx->rtp_sockets[i].sock, &fds); } diff --git a/components/squeezelite/decode_external.c b/components/squeezelite/decode_external.c index 122c45e1..e25480e9 100644 --- a/components/squeezelite/decode_external.c +++ b/components/squeezelite/decode_external.c @@ -50,7 +50,7 @@ static struct { */ static void sink_data_handler(const uint8_t *data, uint32_t len) { - size_t bytes, space; + size_t bytes; // would be better to lock decoder, but really, it does not matter if (decode.state != DECODE_STOPPED) { @@ -75,7 +75,6 @@ static void sink_data_handler(const uint8_t *data, uint32_t len) } #endif _buf_inc_writep(outputbuf, bytes); - space = _buf_space(outputbuf); len -= bytes; data += bytes; @@ -83,7 +82,7 @@ static void sink_data_handler(const uint8_t *data, uint32_t len) UNLOCK_O; // allow i2s to empty the buffer if needed - if (len && !space) usleep(50000); + if (len) usleep(50000); } } @@ -190,7 +189,7 @@ void raop_sink_cmd_handler(raop_event_t event, void *param) // 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_DEBUG("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error); + LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error); LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process); } diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index 0cef203c..fbfd27c9 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -116,6 +116,7 @@ static i2s_config_t i2s_config; static int bytes_per_frame; static thread_type thread, stats_thread; static u8_t *obuf; +static frames_t oframes; static bool spdif; static size_t dma_buf_frames; @@ -315,7 +316,7 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch isI2SStarted=false; dac_cmd(DAC_OFF); - + esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); cfg.thread_name= "output_i2s"; @@ -381,13 +382,13 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32 _apply_gain(outputbuf, out_frames, gainL, gainR); } - memcpy(obuf, outputbuf->readp, out_frames * bytes_per_frame); + 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, silencebuf, out_frames * bytes_per_frame); + memcpy(obuf + oframes * bytes_per_frame, silencebuf, out_frames * bytes_per_frame); #else optr = (s32_t*) silencebuf; #endif @@ -401,9 +402,11 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32 dsd_invert((u32_t *) optr, out_frames); ) - _scale_and_pack_frames(obuf, optr, out_frames, gainL, gainR, output.format); + _scale_and_pack_frames(obuf + oframes * bytes_per_frame, optr, out_frames, gainL, gainR, output.format); #endif + oframes += out_frames; + return out_frames; } @@ -412,7 +415,7 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32 */ static void *output_thread_i2s() { size_t count = 0, bytes; - frames_t iframes = FRAME_BLOCK, oframes; + frames_t iframes = FRAME_BLOCK; uint32_t timer_start = 0; int discard = 0; uint32_t fullness = gettime_ms(); @@ -458,9 +461,10 @@ static void *output_thread_i2s() { output.frames_played_dmp = output.frames_played; // try to estimate how much we have consumed from the DMA buffer (calculation is incorrect at the very beginning ...) output.device_frames = dma_buf_frames - ((output.updated - fullness) * output.current_sample_rate) / 1000; - oframes = _output_frames( iframes ); + _output_frames( iframes ); + // oframes must be a global updated by the write callback output.frames_in_process = oframes; - + SET_MIN_MAX_SIZED(oframes,rec,iframes); SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size); SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size); @@ -475,6 +479,7 @@ static void *output_thread_i2s() { } else if (discard) { discard -= oframes; iframes = discard ? min(FRAME_BLOCK, discard) : FRAME_BLOCK; + oframes = 0; UNLOCK; continue; } @@ -521,6 +526,8 @@ static void *output_thread_i2s() { if (bytes != oframes * bytes_per_frame) { LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", oframes * bytes_per_frame, bytes); } + + oframes = 0; SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);