mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 13:52:57 +00:00
[client] audio: allow the audiodev to determine the start fill level
This commit is contained in:
parent
46da447429
commit
04ae9217e8
4 changed files with 36 additions and 23 deletions
|
@ -53,6 +53,7 @@ struct PipeWire
|
|||
int sampleRate;
|
||||
int stride;
|
||||
LG_AudioPullFn pullFn;
|
||||
int startFrames;
|
||||
|
||||
StreamState state;
|
||||
}
|
||||
|
@ -224,17 +225,17 @@ static void pipewire_playbackSetup(int channels, int sampleRate,
|
|||
pipewire_playbackStopStream();
|
||||
|
||||
int bufferFrames = sampleRate / 10;
|
||||
|
||||
pw.playback.channels = channels;
|
||||
pw.playback.sampleRate = sampleRate;
|
||||
pw.playback.stride = sizeof(uint16_t) * channels;
|
||||
pw.playback.pullFn = pullFn;
|
||||
|
||||
int maxLatencyFrames = bufferFrames / 2;
|
||||
char maxLatency[32];
|
||||
snprintf(maxLatency, sizeof(maxLatency), "%d/%d", maxLatencyFrames,
|
||||
sampleRate);
|
||||
|
||||
pw.playback.channels = channels;
|
||||
pw.playback.sampleRate = sampleRate;
|
||||
pw.playback.stride = sizeof(uint16_t) * channels;
|
||||
pw.playback.pullFn = pullFn;
|
||||
pw.playback.startFrames = maxLatencyFrames;
|
||||
|
||||
pw_thread_loop_lock(pw.thread);
|
||||
pw.playback.stream = pw_stream_new_simple(
|
||||
pw.loop,
|
||||
|
@ -278,10 +279,12 @@ static void pipewire_playbackSetup(int channels, int sampleRate,
|
|||
pw_thread_loop_unlock(pw.thread);
|
||||
}
|
||||
|
||||
static void pipewire_playbackStart(void)
|
||||
static bool pipewire_playbackStart(int framesBuffered)
|
||||
{
|
||||
if (!pw.playback.stream)
|
||||
return;
|
||||
return false;
|
||||
|
||||
bool start = false;
|
||||
|
||||
if (pw.playback.state != STREAM_STATE_ACTIVE &&
|
||||
pw.playback.state != STREAM_STATE_RESTARTING)
|
||||
|
@ -291,13 +294,18 @@ static void pipewire_playbackStart(void)
|
|||
switch (pw.playback.state)
|
||||
{
|
||||
case STREAM_STATE_INACTIVE:
|
||||
pw_stream_set_active(pw.playback.stream, true);
|
||||
pw.playback.state = STREAM_STATE_ACTIVE;
|
||||
if (framesBuffered >= pw.playback.startFrames)
|
||||
{
|
||||
pw_stream_set_active(pw.playback.stream, true);
|
||||
pw.playback.state = STREAM_STATE_ACTIVE;
|
||||
start = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_STATE_FLUSHING:
|
||||
// We were preparing to stop; just carry on as if nothing happened
|
||||
pw.playback.state = STREAM_STATE_ACTIVE;
|
||||
start = true;
|
||||
break;
|
||||
|
||||
case STREAM_STATE_DRAINING:
|
||||
|
@ -312,6 +320,8 @@ static void pipewire_playbackStart(void)
|
|||
|
||||
pw_thread_loop_unlock(pw.thread);
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static void pipewire_playbackStop(void)
|
||||
|
|
|
@ -288,15 +288,20 @@ static void pulseaudio_setup(int channels, int sampleRate,
|
|||
pa_threaded_mainloop_unlock(pa.loop);
|
||||
}
|
||||
|
||||
static void pulseaudio_start(void)
|
||||
static bool pulseaudio_start(int framesBuffered)
|
||||
{
|
||||
if (!pa.sink)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (framesBuffered < pa.sinkStart)
|
||||
return false;
|
||||
|
||||
pa_threaded_mainloop_lock(pa.loop);
|
||||
pa_stream_cork(pa.sink, 0, NULL, NULL);
|
||||
pa.sinkCorked = false;
|
||||
pa_threaded_mainloop_unlock(pa.loop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pulseaudio_stop(void)
|
||||
|
|
|
@ -49,8 +49,9 @@ struct LG_AudioDevOps
|
|||
*/
|
||||
void (*setup)(int channels, int sampleRate, LG_AudioPullFn pullFn);
|
||||
|
||||
/* called when playback is about to start */
|
||||
void (*start)(void);
|
||||
/* called when there is data available to start playback
|
||||
* return true if playback should start */
|
||||
bool (*start)(int framesBuffered);
|
||||
|
||||
/* called when SPICE reports the audio stream has stopped */
|
||||
void (*stop)(void);
|
||||
|
|
|
@ -167,7 +167,7 @@ void audio_playbackStart(int channels, int sampleRate, PSAudioFormat format,
|
|||
playbackStopNL();
|
||||
}
|
||||
|
||||
const int bufferFrames = sampleRate / 10;
|
||||
const int bufferFrames = sampleRate;
|
||||
audio.playback.buffer = ringbuffer_new(bufferFrames,
|
||||
channels * sizeof(uint16_t));
|
||||
|
||||
|
@ -247,17 +247,14 @@ void audio_playbackData(uint8_t * data, size_t size)
|
|||
if (!STREAM_ACTIVE(audio.playback.state))
|
||||
return;
|
||||
|
||||
const int frames = size / audio.playback.stride;
|
||||
int frames = size / audio.playback.stride;
|
||||
ringbuffer_append(audio.playback.buffer, data, frames);
|
||||
|
||||
// don't start playback until the buffer is sifficiently full to avoid
|
||||
// glitches
|
||||
if (audio.playback.state == STREAM_STATE_SETUP &&
|
||||
ringbuffer_getCount(audio.playback.buffer) >=
|
||||
ringbuffer_getLength(audio.playback.buffer) / 4)
|
||||
if (audio.playback.state == STREAM_STATE_SETUP)
|
||||
{
|
||||
audio.playback.state = STREAM_STATE_RUN;
|
||||
audio.audioDev->playback.start();
|
||||
frames = ringbuffer_getLength(audio.playback.buffer);
|
||||
if (audio.audioDev->playback.start(frames))
|
||||
audio.playback.state = STREAM_STATE_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue