diff --git a/output_pa.c b/output_pa.c index 8d02791..46e1cc8 100644 --- a/output_pa.c +++ b/output_pa.c @@ -58,13 +58,15 @@ LOG_WARN("error initialising port audio: %s", Pa_GetErrorText(err)); return; } - + printf("Output devices:\n"); for (i = 0; i < Pa_GetDeviceCount(); ++i) { - printf(" %i - %s [%s]\n", i, Pa_GetDeviceInfo(i)->name, Pa_GetHostApiInfo(Pa_GetDeviceInfo(i)->hostApi)->name); + if (Pa_GetDeviceInfo(i)->maxOutputChannels) { + printf(" %i - %s [%s]\n", i, Pa_GetDeviceInfo(i)->name, Pa_GetHostApiInfo(Pa_GetDeviceInfo(i)->hostApi)->name); + } } printf("\n"); - + if ((err = Pa_Terminate()) != paNoError) { LOG_WARN("error closing port audio: %s", Pa_GetErrorText(err)); } @@ -328,13 +330,22 @@ static int pa_callback(const void *pa_input, void *pa_output, unsigned long pa_frames_wanted, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags statusFlags, void *userData) { int ret; + double stream_time; frames_t frames; optr = (u8_t *)pa_output; LOCK; - output.device_frames = (unsigned)((time_info->outputBufferDacTime - Pa_GetStreamTime(pa.stream)) * output.current_sample_rate); + stream_time = Pa_GetStreamTime(pa.stream); + + if (time_info->outputBufferDacTime > stream_time) { + // workaround for wdm-ks which can return outputBufferDacTime with a different epoch + output.device_frames = (unsigned)((time_info->outputBufferDacTime - stream_time) * output.current_sample_rate); + } else { + output.device_frames = 0; + } + output.updated = gettime_ms(); frames = _output_frames(pa_frames_wanted); diff --git a/slimproto.c b/slimproto.c index 629cec4..da0cc9d 100644 --- a/slimproto.c +++ b/slimproto.c @@ -132,7 +132,12 @@ if (status.current_sample_rate && status.frames_played && status.frames_played > status.device_frames) { ms_played = (u32_t)(((u64_t)(status.frames_played - status.device_frames) * (u64_t)1000) / (u64_t)status.current_sample_rate); if (now > status.updated) ms_played += (now - status.updated); + LOG_SDEBUG("ms_played: %u (frames_played: %u device_frames: %u)", ms_played, status.frames_played, status.device_frames); + } else if (status.frames_played && now > status.stream_start) { + ms_played = now - status.stream_start; + LOG_SDEBUG("ms_played: %u using elapsed time (frames_played: %u device_frames: %u)", ms_played, status.frames_played, status.device_frames); } else { + LOG_SDEBUG("ms_played: 0"); ms_played = 0; } @@ -159,7 +164,7 @@ LOG_INFO("STAT: %s", event); if (loglevel == lSDEBUG) { - LOG_SDEBUG("received bytesL: %u streambuf: %u outputbuf: %u calc elapsed: %u real elapsed: %u (diff: %u) device: %u delay: %d", + LOG_SDEBUG("received bytesL: %u streambuf: %u outputbuf: %u calc elapsed: %u real elapsed: %u (diff: %d) device: %u delay: %d", (u32_t)status.stream_bytes, status.stream_full, status.output_full, ms_played, now - status.stream_start, ms_played - now + status.stream_start, status.device_frames * 1000 / status.current_sample_rate, now - status.updated); }