mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 06:11:46 +00:00
[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.
This commit is contained in:
parent
a0477466d2
commit
22b968ff53
7 changed files with 25 additions and 56 deletions
|
@ -116,7 +116,7 @@ typedef const char * (*GraphFormatFn)(const char * name,
|
||||||
GraphHandle app_registerGraph(const char * name, RingBuffer buffer,
|
GraphHandle app_registerGraph(const char * name, RingBuffer buffer,
|
||||||
float min, float max, GraphFormatFn formatFn);
|
float min, float max, GraphFormatFn formatFn);
|
||||||
void app_unregisterGraph(GraphHandle handle);
|
void app_unregisterGraph(GraphHandle handle);
|
||||||
void app_invalidateGraphs(void);
|
void app_invalidateGraph(GraphHandle handle);
|
||||||
|
|
||||||
void app_overlayConfigRegister(const char * title,
|
void app_overlayConfigRegister(const char * title,
|
||||||
void (*callback)(void * udata, int * id), void * udata);
|
void (*callback)(void * udata, int * id), void * udata);
|
||||||
|
|
|
@ -706,9 +706,9 @@ void app_unregisterGraph(GraphHandle handle)
|
||||||
overlayGraph_unregister(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)
|
void app_registerOverlay(const struct LG_OverlayOps * ops, const void * params)
|
||||||
|
|
|
@ -100,7 +100,6 @@ typedef struct
|
||||||
RingBuffer buffer;
|
RingBuffer buffer;
|
||||||
RingBuffer deviceTiming;
|
RingBuffer deviceTiming;
|
||||||
|
|
||||||
LG_Lock lock;
|
|
||||||
RingBuffer timings;
|
RingBuffer timings;
|
||||||
GraphHandle graph;
|
GraphHandle graph;
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ typedef struct
|
||||||
}
|
}
|
||||||
PlaybackDeviceTick;
|
PlaybackDeviceTick;
|
||||||
|
|
||||||
static void playbackStopNL(void);
|
static void playbackStop(void);
|
||||||
|
|
||||||
void audio_init(void)
|
void audio_init(void)
|
||||||
{
|
{
|
||||||
|
@ -143,7 +142,6 @@ void audio_init(void)
|
||||||
if (LG_AudioDevs[i]->init())
|
if (LG_AudioDevs[i]->init())
|
||||||
{
|
{
|
||||||
audio.audioDev = LG_AudioDevs[i];
|
audio.audioDev = LG_AudioDevs[i];
|
||||||
LG_LOCK_INIT(audio.playback.lock);
|
|
||||||
DEBUG_INFO("Using AudioDev: %s", audio.audioDev->name);
|
DEBUG_INFO("Using AudioDev: %s", audio.audioDev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -157,15 +155,11 @@ void audio_free(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// immediate stop of the stream, do not wait for drain
|
// immediate stop of the stream, do not wait for drain
|
||||||
LG_LOCK(audio.playback.lock);
|
playbackStop();
|
||||||
playbackStopNL();
|
|
||||||
LG_UNLOCK(audio.playback.lock);
|
|
||||||
|
|
||||||
audio_recordStop();
|
audio_recordStop();
|
||||||
|
|
||||||
audio.audioDev->free();
|
audio.audioDev->free();
|
||||||
audio.audioDev = NULL;
|
audio.audioDev = NULL;
|
||||||
LG_LOCK_FREE(audio.playback.lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool audio_supportsPlayback(void)
|
bool audio_supportsPlayback(void)
|
||||||
|
@ -183,7 +177,7 @@ static const char * audioGraphFormatFn(const char * name,
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void playbackStopNL(void)
|
static void playbackStop(void)
|
||||||
{
|
{
|
||||||
if (audio.playback.state == STREAM_STATE_STOP)
|
if (audio.playback.state == STREAM_STATE_STOP)
|
||||||
return;
|
return;
|
||||||
|
@ -274,11 +268,8 @@ static int playbackPullFrames(uint8_t * dst, int frames)
|
||||||
|
|
||||||
if (audio.playback.state == STREAM_STATE_DRAIN &&
|
if (audio.playback.state == STREAM_STATE_DRAIN &&
|
||||||
ringbuffer_getCount(audio.playback.buffer) <= 0)
|
ringbuffer_getCount(audio.playback.buffer) <= 0)
|
||||||
{
|
playbackStop();
|
||||||
LG_LOCK(audio.playback.lock);
|
|
||||||
playbackStopNL();
|
|
||||||
LG_UNLOCK(audio.playback.lock);
|
|
||||||
}
|
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,13 +279,11 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format,
|
||||||
if (!audio.audioDev)
|
if (!audio.audioDev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LG_LOCK(audio.playback.lock);
|
|
||||||
|
|
||||||
if (audio.playback.state != STREAM_STATE_STOP)
|
if (audio.playback.state != STREAM_STATE_STOP)
|
||||||
{
|
{
|
||||||
// Stop the current playback immediately. Even if the format is compatible,
|
// Stop the current playback immediately. Even if the format is compatible,
|
||||||
// we may not have enough data left in the buffers to avoid underrunning
|
// we may not have enough data left in the buffers to avoid underrunning
|
||||||
playbackStopNL();
|
playbackStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int srcError;
|
int srcError;
|
||||||
|
@ -303,7 +292,7 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format,
|
||||||
if (!audio.playback.spiceData.src)
|
if (!audio.playback.spiceData.src)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to create resampler: %s", src_strerror(srcError));
|
DEBUG_ERROR("Failed to create resampler: %s", src_strerror(srcError));
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int bufferFrames = sampleRate;
|
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.timings, 0.0f, 100.0f, audioGraphFormatFn);
|
||||||
|
|
||||||
audio.playback.state = STREAM_STATE_SETUP;
|
audio.playback.state = STREAM_STATE_SETUP;
|
||||||
|
|
||||||
done:
|
|
||||||
LG_UNLOCK(audio.playback.lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_playbackStop(void)
|
void audio_playbackStop(void)
|
||||||
|
@ -418,7 +404,7 @@ void audio_playbackData(uint8_t * data, size_t size)
|
||||||
if (!spiceData->framesIn)
|
if (!spiceData->framesIn)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to malloc framesIn");
|
DEBUG_ERROR("Failed to malloc framesIn");
|
||||||
playbackStopNL();
|
playbackStop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +414,7 @@ void audio_playbackData(uint8_t * data, size_t size)
|
||||||
if (!spiceData->framesOut)
|
if (!spiceData->framesOut)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to malloc framesOut");
|
DEBUG_ERROR("Failed to malloc framesOut");
|
||||||
playbackStopNL();
|
playbackStop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,6 +557,15 @@ void audio_playbackData(uint8_t * data, size_t size)
|
||||||
if (audio.audioDev->playback.start(frames))
|
if (audio.audioDev->playback.start(frames))
|
||||||
audio.playback.state = STREAM_STATE_RUN;
|
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)
|
bool audio_supportsRecord(void)
|
||||||
|
@ -655,26 +650,4 @@ void audio_recordMute(bool mute)
|
||||||
audio.audioDev->record.mute(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
|
#endif
|
||||||
|
|
|
@ -40,12 +40,9 @@ void audio_recordStop(void);
|
||||||
void audio_recordVolume(int channels, const uint16_t volume[]);
|
void audio_recordVolume(int channels, const uint16_t volume[]);
|
||||||
void audio_recordMute(bool mute);
|
void audio_recordMute(bool mute);
|
||||||
|
|
||||||
void audio_tick(unsigned long long tickCount);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline void audio_init(void) {}
|
static inline void audio_init(void) {}
|
||||||
static inline void audio_free(void) {}
|
static inline void audio_free(void) {}
|
||||||
static inline void audio_tick(unsigned long long tickCount) {}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -155,8 +155,6 @@ static bool tickTimerFn(void * unused)
|
||||||
if (needsRender)
|
if (needsRender)
|
||||||
app_invalidateWindow(false);
|
app_invalidateWindow(false);
|
||||||
|
|
||||||
audio_tick(tickCount);
|
|
||||||
|
|
||||||
++tickCount;
|
++tickCount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,10 +245,11 @@ void overlayGraph_iterate(void (*callback)(GraphHandle handle, const char * name
|
||||||
ll_unlock(gs.graphs);
|
ll_unlock(gs.graphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlayGraph_invalidate(void)
|
void overlayGraph_invalidate(GraphHandle handle)
|
||||||
{
|
{
|
||||||
if (!gs.show)
|
if (!gs.show)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
app_invalidateWindow(false);
|
if (handle->enabled)
|
||||||
|
app_invalidateWindow(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ GraphHandle overlayGraph_register(const char * name, RingBuffer buffer,
|
||||||
void overlayGraph_unregister();
|
void overlayGraph_unregister();
|
||||||
void overlayGraph_iterate(void (*callback)(GraphHandle handle, const char * name,
|
void overlayGraph_iterate(void (*callback)(GraphHandle handle, const char * name,
|
||||||
bool * enabled, void * udata), void * udata);
|
bool * enabled, void * udata), void * udata);
|
||||||
void overlayGraph_invalidate(void);
|
void overlayGraph_invalidate(GraphHandle handle);
|
||||||
|
|
||||||
void overlayConfig_register(const char * title,
|
void overlayConfig_register(const char * title,
|
||||||
void (*callback)(void * udata, int * id), void * udata);
|
void (*callback)(void * udata, int * id), void * udata);
|
||||||
|
|
Loading…
Reference in a new issue