diff options
Diffstat (limited to 'src/output')
-rw-r--r-- | src/output/jack_output_plugin.c | 16 | ||||
-rw-r--r-- | src/output/osx_output_plugin.c | 94 | ||||
-rw-r--r-- | src/output/recorder_output_plugin.c | 2 | ||||
-rw-r--r-- | src/output/shout_output_plugin.c | 2 |
4 files changed, 55 insertions, 59 deletions
diff --git a/src/output/jack_output_plugin.c b/src/output/jack_output_plugin.c index cd769088b..a24cb8557 100644 --- a/src/output/jack_output_plugin.c +++ b/src/output/jack_output_plugin.c @@ -146,6 +146,13 @@ mpd_jack_process(jack_nframes_t nframes, void *arg) for (unsigned i = 0; i < jd->audio_format.channels; ++i) { out = jack_port_get_buffer(jd->ports[i], nframes); + if (out == NULL) + /* workaround for libjack1 bug: if the server + connection fails, the process callback is + invoked anyway, but unable to get a + buffer */ + continue; + jack_ringbuffer_read(jd->ringbuffer[i], (char *)out, available * jack_sample_size); @@ -159,6 +166,12 @@ mpd_jack_process(jack_nframes_t nframes, void *arg) for (unsigned i = jd->audio_format.channels; i < jd->num_source_ports; ++i) { out = jack_port_get_buffer(jd->ports[i], nframes); + if (out == NULL) + /* workaround for libjack1 bug: if the server + connection fails, the process callback is + invoked anyway, but unable to get a + buffer */ + continue; for (jack_nframes_t f = 0; f < nframes; ++f) out[f] = 0.0; @@ -572,6 +585,9 @@ mpd_jack_open(struct audio_output *ao, struct audio_format *audio_format, jd->pause = false; + if (jd->client != NULL && jd->shutdown) + mpd_jack_disconnect(jd); + if (jd->client == NULL && !mpd_jack_connect(jd, error_r)) return false; diff --git a/src/output/osx_output_plugin.c b/src/output/osx_output_plugin.c index 3f1af821b..fbba81749 100644 --- a/src/output/osx_output_plugin.c +++ b/src/output/osx_output_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2012 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,6 +20,7 @@ #include "config.h" #include "osx_output_plugin.h" #include "output_api.h" +#include "fifo_buffer.h" #include <glib.h> #include <CoreAudio/AudioHardware.h> @@ -40,10 +41,8 @@ struct osx_output { AudioUnit au; GMutex *mutex; GCond *condition; - char *buffer; - size_t buffer_size; - size_t pos; - size_t len; + + struct fifo_buffer *buffer; }; /** @@ -96,11 +95,6 @@ osx_output_init(const struct config_param *param, GError **error_r) oo->mutex = g_mutex_new(); oo->condition = g_cond_new(); - oo->pos = 0; - oo->len = 0; - oo->buffer = NULL; - oo->buffer_size = 0; - return &oo->base; } @@ -109,7 +103,6 @@ osx_output_finish(struct audio_output *ao) { struct osx_output *od = (struct osx_output *)ao; - g_free(od->buffer); g_mutex_free(od->mutex); g_cond_free(od->condition); g_free(od); @@ -215,37 +208,29 @@ osx_render(void *vdata, struct osx_output *od = (struct osx_output *) vdata; AudioBuffer *buffer = &buffer_list->mBuffers[0]; size_t buffer_size = buffer->mDataByteSize; - size_t bytes_to_copy; - size_t trailer_length; - size_t dest_pos = 0; - g_mutex_lock(od->mutex); + assert(od->buffer != NULL); - bytes_to_copy = MIN(od->len, buffer_size); - od->len -= bytes_to_copy; + g_mutex_lock(od->mutex); - trailer_length = od->buffer_size - od->pos; - if (bytes_to_copy > trailer_length) { - memcpy((unsigned char*)buffer->mData + dest_pos, - od->buffer + od->pos, trailer_length); - od->pos = 0; - dest_pos += trailer_length; - bytes_to_copy -= trailer_length; - } + size_t nbytes; + const void *src = fifo_buffer_read(od->buffer, &nbytes); - memcpy((unsigned char*)buffer->mData + dest_pos, - od->buffer + od->pos, bytes_to_copy); - od->pos += bytes_to_copy; + if (src != NULL) { + if (nbytes > buffer_size) + nbytes = buffer_size; - if (od->pos >= od->buffer_size) - od->pos = 0; + memcpy(buffer->mData, src, nbytes); + fifo_buffer_consume(od->buffer, nbytes); + } else + nbytes = 0; g_cond_signal(od->condition); g_mutex_unlock(od->mutex); - if (bytes_to_copy < buffer_size) - memset((unsigned char*)buffer->mData + bytes_to_copy, 0, - buffer_size - bytes_to_copy); + if (nbytes < buffer_size) + memset((unsigned char*)buffer->mData + nbytes, 0, + buffer_size - nbytes); return 0; } @@ -315,7 +300,7 @@ osx_output_cancel(struct audio_output *ao) struct osx_output *od = (struct osx_output *)ao; g_mutex_lock(od->mutex); - od->len = 0; + fifo_buffer_clear(od->buffer); g_mutex_unlock(od->mutex); } @@ -326,6 +311,8 @@ osx_output_close(struct audio_output *ao) AudioOutputUnitStop(od->au); AudioUnitUninitialize(od->au); + + fifo_buffer_free(od->buffer); } static bool @@ -387,12 +374,8 @@ osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GErr } /* create a buffer of 1s */ - od->buffer_size = (audio_format->sample_rate) * - audio_format_frame_size(audio_format); - od->buffer = g_realloc(od->buffer, od->buffer_size); - - od->pos = 0; - od->len = 0; + od->buffer = fifo_buffer_new(audio_format->sample_rate * + audio_format_frame_size(audio_format)); status = AudioOutputUnitStart(od->au); if (status != 0) { @@ -411,33 +394,30 @@ osx_output_play(struct audio_output *ao, const void *chunk, size_t size, G_GNUC_UNUSED GError **error) { struct osx_output *od = (struct osx_output *)ao; - size_t start, nbytes; g_mutex_lock(od->mutex); - while (od->len >= od->buffer_size) - /* wait for some free space in the buffer */ - g_cond_wait(od->condition, od->mutex); + void *dest; + size_t max_length; - start = od->pos + od->len; - if (start >= od->buffer_size) - start -= od->buffer_size; - - nbytes = start < od->pos - ? od->pos - start - : od->buffer_size - start; + while (true) { + dest = fifo_buffer_write(od->buffer, &max_length); + if (dest != NULL) + break; - assert(nbytes > 0); + /* wait for some free space in the buffer */ + g_cond_wait(od->condition, od->mutex); + } - if (nbytes > size) - nbytes = size; + if (size > max_length) + size = max_length; - memcpy(od->buffer + start, chunk, nbytes); - od->len += nbytes; + memcpy(dest, chunk, size); + fifo_buffer_append(od->buffer, size); g_mutex_unlock(od->mutex); - return nbytes; + return size; } const struct audio_output_plugin osx_output_plugin = { diff --git a/src/output/recorder_output_plugin.c b/src/output/recorder_output_plugin.c index 00adc5d19..ea299468b 100644 --- a/src/output/recorder_output_plugin.c +++ b/src/output/recorder_output_plugin.c @@ -202,7 +202,7 @@ recorder_output_close(struct audio_output *ao) /* flush the encoder and write the rest to the file */ - if (encoder_flush(recorder->encoder, NULL)) + if (encoder_end(recorder->encoder, NULL)) recorder_output_encoder_to_file(recorder, NULL); /* now really close everything */ diff --git a/src/output/shout_output_plugin.c b/src/output/shout_output_plugin.c index 35356d659..7867ae63c 100644 --- a/src/output/shout_output_plugin.c +++ b/src/output/shout_output_plugin.c @@ -376,7 +376,7 @@ static void close_shout_conn(struct shout_data * sd) sd->buf.len = 0; if (sd->encoder != NULL) { - if (encoder_flush(sd->encoder, NULL)) + if (encoder_end(sd->encoder, NULL)) write_page(sd, NULL); encoder_close(sd->encoder); |