aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/output/plugins/JackOutputPlugin.cxx30
2 files changed, 21 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 3be4a58d0..835775766 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ ver 0.20 (not yet released)
- ffmpeg: support ReplayGain and MixRamp
- ffmpeg: support stream tags
* output
+ - jack: reduce CPU usage
- pulse: set channel map to WAVE-EX
* mixer
- null: new plugin
diff --git a/src/output/plugins/JackOutputPlugin.cxx b/src/output/plugins/JackOutputPlugin.cxx
index 653a73328..854d2536f 100644
--- a/src/output/plugins/JackOutputPlugin.cxx
+++ b/src/output/plugins/JackOutputPlugin.cxx
@@ -647,13 +647,20 @@ JackOutput::WriteSamples(const float *src, size_t n_frames)
const unsigned n_channels = audio_format.channels;
- size_t space = jack_ringbuffer_write_space(ringbuffer[0]);
- for (unsigned i = 1; i < n_channels; ++i) {
- size_t space1 =
- jack_ringbuffer_write_space(ringbuffer[i]);
- if (space1 < space)
+ float *dest[MAX_CHANNELS];
+ size_t space = -1;
+ for (unsigned i = 0; i < n_channels; ++i) {
+ jack_ringbuffer_data_t d[2];
+ jack_ringbuffer_get_write_vector(ringbuffer[i], d);
+
+ /* choose the first non-empty writable area */
+ const jack_ringbuffer_data_t &e = d[d[0].len == 0];
+
+ if (e.len < space)
/* send data symmetrically */
- space = space1;
+ space = e->len;
+
+ dest[i] = (float *)e.buf;
}
space /= jack_sample_size;
@@ -663,10 +670,13 @@ JackOutput::WriteSamples(const float *src, size_t n_frames)
const size_t result = n_frames = std::min(space, n_frames);
while (n_frames-- > 0)
- for (unsigned i = 0; i < n_channels; ++i, ++src)
- jack_ringbuffer_write(ringbuffer[i],
- (const char *)src,
- sizeof(*src));
+ for (unsigned i = 0; i < n_channels; ++i)
+ *dest[i]++ = *src++;
+
+ const size_t per_channel_advance = result * jack_sample_size;
+ for (unsigned i = 0; i < n_channels; ++i)
+ jack_ringbuffer_write_advance(ringbuffer[i],
+ per_channel_advance);
return result;
}