From 22b968ff53de5095d5b86ed09b291312e68b5bad Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 28 Jan 2022 10:59:12 +1100 Subject: [PATCH] [client] audio: change the audio latency graph sample point This removes the need for locking while also giving a better result in the graph output. Also when the graph is disabled via the overlay options it will no longer cause redraws. --- client/include/app.h | 2 +- client/src/app.c | 4 +-- client/src/audio.c | 63 +++++++++++-------------------------- client/src/audio.h | 3 -- client/src/main.c | 2 -- client/src/overlay/graphs.c | 5 +-- client/src/overlays.h | 2 +- 7 files changed, 25 insertions(+), 56 deletions(-) diff --git a/client/include/app.h b/client/include/app.h index f1e979cb..46c2df9e 100644 --- a/client/include/app.h +++ b/client/include/app.h @@ -116,7 +116,7 @@ typedef const char * (*GraphFormatFn)(const char * name, GraphHandle app_registerGraph(const char * name, RingBuffer buffer, float min, float max, GraphFormatFn formatFn); void app_unregisterGraph(GraphHandle handle); -void app_invalidateGraphs(void); +void app_invalidateGraph(GraphHandle handle); void app_overlayConfigRegister(const char * title, void (*callback)(void * udata, int * id), void * udata); diff --git a/client/src/app.c b/client/src/app.c index 4dbdc519..a4ebbc17 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -706,9 +706,9 @@ void app_unregisterGraph(GraphHandle handle) overlayGraph_unregister(handle); } -void app_invalidateGraphs(void) +void app_invalidateGraph(GraphHandle handle) { - overlayGraph_invalidate(); + overlayGraph_invalidate(handle); } void app_registerOverlay(const struct LG_OverlayOps * ops, const void * params) diff --git a/client/src/audio.c b/client/src/audio.c index af1bff9c..827ba38d 100644 --- a/client/src/audio.c +++ b/client/src/audio.c @@ -100,7 +100,6 @@ typedef struct RingBuffer buffer; RingBuffer deviceTiming; - LG_Lock lock; RingBuffer timings; GraphHandle graph; @@ -134,7 +133,7 @@ typedef struct } PlaybackDeviceTick; -static void playbackStopNL(void); +static void playbackStop(void); void audio_init(void) { @@ -143,7 +142,6 @@ void audio_init(void) if (LG_AudioDevs[i]->init()) { audio.audioDev = LG_AudioDevs[i]; - LG_LOCK_INIT(audio.playback.lock); DEBUG_INFO("Using AudioDev: %s", audio.audioDev->name); return; } @@ -157,15 +155,11 @@ void audio_free(void) return; // immediate stop of the stream, do not wait for drain - LG_LOCK(audio.playback.lock); - playbackStopNL(); - LG_UNLOCK(audio.playback.lock); - + playbackStop(); audio_recordStop(); audio.audioDev->free(); audio.audioDev = NULL; - LG_LOCK_FREE(audio.playback.lock); } bool audio_supportsPlayback(void) @@ -183,7 +177,7 @@ static const char * audioGraphFormatFn(const char * name, return title; } -static void playbackStopNL(void) +static void playbackStop(void) { if (audio.playback.state == STREAM_STATE_STOP) return; @@ -274,11 +268,8 @@ static int playbackPullFrames(uint8_t * dst, int frames) if (audio.playback.state == STREAM_STATE_DRAIN && ringbuffer_getCount(audio.playback.buffer) <= 0) - { - LG_LOCK(audio.playback.lock); - playbackStopNL(); - LG_UNLOCK(audio.playback.lock); - } + playbackStop(); + return frames; } @@ -288,13 +279,11 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format, if (!audio.audioDev) return; - LG_LOCK(audio.playback.lock); - if (audio.playback.state != STREAM_STATE_STOP) { // Stop the current playback immediately. Even if the format is compatible, // we may not have enough data left in the buffers to avoid underrunning - playbackStopNL(); + playbackStop(); } int srcError; @@ -303,7 +292,7 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format, if (!audio.playback.spiceData.src) { DEBUG_ERROR("Failed to create resampler: %s", src_strerror(srcError)); - goto done; + return; } const int bufferFrames = sampleRate; @@ -346,9 +335,6 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format, audio.playback.timings, 0.0f, 100.0f, audioGraphFormatFn); audio.playback.state = STREAM_STATE_SETUP; - -done: - LG_UNLOCK(audio.playback.lock); } void audio_playbackStop(void) @@ -418,7 +404,7 @@ void audio_playbackData(uint8_t * data, size_t size) if (!spiceData->framesIn) { DEBUG_ERROR("Failed to malloc framesIn"); - playbackStopNL(); + playbackStop(); return; } @@ -428,7 +414,7 @@ void audio_playbackData(uint8_t * data, size_t size) if (!spiceData->framesOut) { DEBUG_ERROR("Failed to malloc framesOut"); - playbackStopNL(); + playbackStop(); return; } } @@ -571,6 +557,15 @@ void audio_playbackData(uint8_t * data, size_t size) if (audio.audioDev->playback.start(frames)) audio.playback.state = STREAM_STATE_RUN; } + + int latencyFrames = ringbuffer_getCount(audio.playback.buffer); + if (audio.audioDev->playback.latency) + latencyFrames += audio.audioDev->playback.latency(); + + const float latency = latencyFrames / + (float)(audio.playback.sampleRate / 1000); + ringbuffer_push(audio.playback.timings, &latency); + app_invalidateGraph(audio.playback.graph); } bool audio_supportsRecord(void) @@ -655,26 +650,4 @@ void audio_recordMute(bool mute) audio.audioDev->record.mute(mute); } -void audio_tick(unsigned long long tickCount) -{ - LG_LOCK(audio.playback.lock); - if (!audio.playback.buffer) - { - LG_UNLOCK(audio.playback.lock); - return; - } - - int frames = ringbuffer_getCount(audio.playback.buffer); - if (audio.audioDev->playback.latency) - frames += audio.audioDev->playback.latency(); - - const float latency = frames / (float)(audio.playback.sampleRate / 1000); - - ringbuffer_push(audio.playback.timings, &latency); - - LG_UNLOCK(audio.playback.lock); - - app_invalidateGraphs(); -} - #endif diff --git a/client/src/audio.h b/client/src/audio.h index 6e256130..38a51d3d 100644 --- a/client/src/audio.h +++ b/client/src/audio.h @@ -40,12 +40,9 @@ void audio_recordStop(void); void audio_recordVolume(int channels, const uint16_t volume[]); void audio_recordMute(bool mute); -void audio_tick(unsigned long long tickCount); - #else static inline void audio_init(void) {} static inline void audio_free(void) {} -static inline void audio_tick(unsigned long long tickCount) {} #endif diff --git a/client/src/main.c b/client/src/main.c index ec22f15b..bd45069a 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -155,8 +155,6 @@ static bool tickTimerFn(void * unused) if (needsRender) app_invalidateWindow(false); - audio_tick(tickCount); - ++tickCount; return true; } diff --git a/client/src/overlay/graphs.c b/client/src/overlay/graphs.c index 3a3396d9..a131c6f5 100644 --- a/client/src/overlay/graphs.c +++ b/client/src/overlay/graphs.c @@ -245,10 +245,11 @@ void overlayGraph_iterate(void (*callback)(GraphHandle handle, const char * name ll_unlock(gs.graphs); } -void overlayGraph_invalidate(void) +void overlayGraph_invalidate(GraphHandle handle) { if (!gs.show) return; - app_invalidateWindow(false); + if (handle->enabled) + app_invalidateWindow(false); } diff --git a/client/src/overlays.h b/client/src/overlays.h index 6cc899d5..67bcb40d 100644 --- a/client/src/overlays.h +++ b/client/src/overlays.h @@ -47,7 +47,7 @@ GraphHandle overlayGraph_register(const char * name, RingBuffer buffer, void overlayGraph_unregister(); void overlayGraph_iterate(void (*callback)(GraphHandle handle, const char * name, bool * enabled, void * udata), void * udata); -void overlayGraph_invalidate(void); +void overlayGraph_invalidate(GraphHandle handle); void overlayConfig_register(const char * title, void (*callback)(void * udata, int * id), void * udata);