From 97ee72ce5fbc319ef0dff96e3b62abe1cd951c76 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 Jul 2015 23:20:30 -0700 Subject: [PATCH] JACK: fix playback glitchfest --- README.md | 9 ++++----- src/jack.cpp | 28 +++++++++++++++++++++------- src/jack.hpp | 2 ++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cc458a8..27872b5 100644 --- a/README.md +++ b/README.md @@ -241,13 +241,12 @@ view `coverage/index.html` in a browser. ## Roadmap - 0. JACK: input - 0. JACK: implement prebuffering - 0. why does pulseaudio microphone use up all the CPU? - 0. merge in/out stream structures and functions? + 0. Integrate into libgroove and test with Groove Basin 0. implement CoreAudio (OSX) backend, get examples working 0. implement WASAPI (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. 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 @@ -282,7 +281,6 @@ view `coverage/index.html` in a browser. 0. use a documentation generator and host the docs somewhere 0. -fvisibility=hidden and then explicitly export stuff, or 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 with the audio data - 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. write detailed docs on buffer underflows explaining when they occur, what state 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 ## Planned Uses for libsoundio diff --git a/src/jack.cpp b/src/jack.cpp index 8084058..06d4c77 100644 --- a/src/jack.cpp +++ b/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) { SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; + SoundIoOutStreamJack *osj = &os->backend_data.jack; 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; } @@ -268,14 +274,11 @@ static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoO { SoundIoOutStream *outstream = &os->pub; 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) { - SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; - if (!(osj->areas[ch].ptr = (char*)jack_port_get_buffer(osjp->source_port, *frame_count))) - return SoundIoErrorStreaming; - + osj->areas[ch].ptr = osj->buf_ptrs[ch]; 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, 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; } diff --git a/src/jack.hpp b/src/jack.hpp index 2f2046d..e8d7b84 100644 --- a/src/jack.hpp +++ b/src/jack.hpp @@ -48,8 +48,10 @@ struct SoundIoOutStreamJackPort { struct SoundIoOutStreamJack { jack_client_t *client; int period_size; + int frames_left; SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS]; SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + char *buf_ptrs[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamJackPort {