mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-18 16:57:13 +00:00
JACK: fix playback glitchfest
This commit is contained in:
parent
754343bba6
commit
97ee72ce5f
|
@ -241,13 +241,12 @@ view `coverage/index.html` in a browser.
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
0. JACK: input
|
0. Integrate into libgroove and test with Groove Basin
|
||||||
0. JACK: implement prebuffering
|
|
||||||
0. why does pulseaudio microphone use up all the CPU?
|
|
||||||
0. merge in/out stream structures and functions?
|
|
||||||
0. implement CoreAudio (OSX) backend, get examples working
|
0. implement CoreAudio (OSX) backend, get examples working
|
||||||
0. implement WASAPI (Windows) backend, get examples working
|
0. implement WASAPI (Windows) backend, get examples working
|
||||||
0. implement ASIO (Windows) backend, get examples working
|
0. implement ASIO (Windows) backend, get examples working
|
||||||
|
0. JACK: implement prebuffering
|
||||||
|
0. why does pulseaudio microphone use up all the CPU?
|
||||||
0. Avoid calling `soundio_panic` in PulseAudio.
|
0. Avoid calling `soundio_panic` in PulseAudio.
|
||||||
0. Figure out a way to test prebuf. I suspect prebuf not working for ALSA
|
0. Figure out a way to test prebuf. I suspect prebuf not working for ALSA
|
||||||
which is why we have to pre-fill the ring buffer with silence for
|
which is why we have to pre-fill the ring buffer with silence for
|
||||||
|
@ -282,7 +281,6 @@ view `coverage/index.html` in a browser.
|
||||||
0. use a documentation generator and host the docs somewhere
|
0. use a documentation generator and host the docs somewhere
|
||||||
0. -fvisibility=hidden and then explicitly export stuff, or
|
0. -fvisibility=hidden and then explicitly export stuff, or
|
||||||
explicitly make the unexported stuff private
|
explicitly make the unexported stuff private
|
||||||
0. Integrate into libgroove and test with Groove Basin
|
|
||||||
0. look at microphone example and determine if fewer memcpys can be done
|
0. look at microphone example and determine if fewer memcpys can be done
|
||||||
with the audio data
|
with the audio data
|
||||||
- test that sending the frame count to begin read works with PulseAudio
|
- test that sending the frame count to begin read works with PulseAudio
|
||||||
|
@ -295,6 +293,7 @@ view `coverage/index.html` in a browser.
|
||||||
0. make rtprio warning a callback and have existing behavior be the default callback
|
0. make rtprio warning a callback and have existing behavior be the default callback
|
||||||
0. write detailed docs on buffer underflows explaining when they occur, what state
|
0. write detailed docs on buffer underflows explaining when they occur, what state
|
||||||
changes are related to them, and how to recover from them.
|
changes are related to them, and how to recover from them.
|
||||||
|
0. API to trigger playback even if prebuf condition isn't met yet.
|
||||||
0. Consider testing on FreeBSD
|
0. Consider testing on FreeBSD
|
||||||
|
|
||||||
## Planned Uses for libsoundio
|
## Planned Uses for libsoundio
|
||||||
|
|
28
src/jack.cpp
28
src/jack.cpp
|
@ -81,8 +81,14 @@ static void wakeup_jack(struct SoundIoPrivate *si) {
|
||||||
|
|
||||||
static int outstream_process_callback(jack_nframes_t nframes, void *arg) {
|
static int outstream_process_callback(jack_nframes_t nframes, void *arg) {
|
||||||
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||||
|
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||||
SoundIoOutStream *outstream = &os->pub;
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
outstream->write_callback(outstream, nframes);
|
osj->frames_left = nframes;
|
||||||
|
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
|
||||||
|
SoundIoOutStreamJackPort *osjp = &osj->ports[ch];
|
||||||
|
osj->buf_ptrs[ch] = (char*)jack_port_get_buffer(osjp->source_port, osj->frames_left);
|
||||||
|
}
|
||||||
|
outstream->write_callback(outstream, osj->frames_left);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,14 +274,11 @@ static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoO
|
||||||
{
|
{
|
||||||
SoundIoOutStream *outstream = &os->pub;
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||||
SoundIoJack *sij = &si->backend_data.jack;
|
|
||||||
assert(*frame_count <= sij->period_size);
|
*frame_count = min(*frame_count, osj->frames_left);
|
||||||
|
|
||||||
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
|
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
|
||||||
SoundIoOutStreamJackPort *osjp = &osj->ports[ch];
|
osj->areas[ch].ptr = osj->buf_ptrs[ch];
|
||||||
if (!(osj->areas[ch].ptr = (char*)jack_port_get_buffer(osjp->source_port, *frame_count)))
|
|
||||||
return SoundIoErrorStreaming;
|
|
||||||
|
|
||||||
osj->areas[ch].step = outstream->bytes_per_sample;
|
osj->areas[ch].step = outstream->bytes_per_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +290,17 @@ static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoO
|
||||||
static int outstream_end_write_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os,
|
static int outstream_end_write_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os,
|
||||||
int frame_count)
|
int frame_count)
|
||||||
{
|
{
|
||||||
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
|
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||||
|
assert(frame_count <= osj->frames_left);
|
||||||
|
|
||||||
|
osj->frames_left -= frame_count;
|
||||||
|
if (osj->frames_left > 0) {
|
||||||
|
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
|
||||||
|
osj->buf_ptrs[ch] += frame_count * outstream->bytes_per_sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,10 @@ struct SoundIoOutStreamJackPort {
|
||||||
struct SoundIoOutStreamJack {
|
struct SoundIoOutStreamJack {
|
||||||
jack_client_t *client;
|
jack_client_t *client;
|
||||||
int period_size;
|
int period_size;
|
||||||
|
int frames_left;
|
||||||
SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS];
|
SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS];
|
||||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||||
|
char *buf_ptrs[SOUNDIO_MAX_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SoundIoInStreamJackPort {
|
struct SoundIoInStreamJackPort {
|
||||||
|
|
Loading…
Reference in a new issue