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