From ce1d8975751251d49581129193e09490ca650a8b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 26 Sep 2013 21:51:45 +0200 Subject: [PATCH] MusicPipe: expose the C++ API --- src/DecoderAPI.cxx | 4 +- src/DecoderControl.cxx | 7 +- src/DecoderControl.hxx | 5 +- src/DecoderInternal.cxx | 2 +- src/MusicChunk.hxx | 2 +- src/MusicPipe.cxx | 138 +++++++++--------------------------- src/MusicPipe.hxx | 151 +++++++++++++++++++++++----------------- src/OutputAll.cxx | 37 +++++----- src/OutputAll.hxx | 6 +- src/OutputControl.cxx | 13 ++-- src/OutputControl.hxx | 4 +- src/OutputInternal.hxx | 3 +- src/OutputThread.cxx | 6 +- src/PlayerThread.cxx | 49 +++++++------ src/PlayerThread.hxx | 2 +- 15 files changed, 187 insertions(+), 242 deletions(-) diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx index 9af2ef49d..68ccd524c 100644 --- a/src/DecoderAPI.cxx +++ b/src/DecoderAPI.cxx @@ -164,7 +164,7 @@ decoder_command_finished(struct decoder *decoder) if (decoder->initial_seek_running) { assert(!decoder->seeking); assert(decoder->chunk == NULL); - assert(music_pipe_empty(dc->pipe)); + assert(dc->pipe->IsEmpty()); decoder->initial_seek_running = false; decoder->timestamp = dc->start_ms / 1000.; @@ -182,7 +182,7 @@ decoder_command_finished(struct decoder *decoder) decoder->chunk = NULL; } - music_pipe_clear(dc->pipe, dc->buffer); + dc->pipe->Clear(dc->buffer); decoder->timestamp = dc->seek_where; } diff --git a/src/DecoderControl.cxx b/src/DecoderControl.cxx index 6721bd55a..8643bb916 100644 --- a/src/DecoderControl.cxx +++ b/src/DecoderControl.cxx @@ -105,12 +105,11 @@ decoder_control::IsCurrentSong(const Song *_song) const void decoder_control::Start(Song *_song, unsigned _start_ms, unsigned _end_ms, - music_buffer *_buffer, music_pipe *_pipe) + music_buffer *_buffer, MusicPipe &_pipe) { assert(_song != NULL); assert(_buffer != NULL); - assert(_pipe != NULL); - assert(music_pipe_empty(_pipe)); + assert(_pipe.IsEmpty()); if (song != nullptr) song->Free(); @@ -119,7 +118,7 @@ decoder_control::Start(Song *_song, start_ms = _start_ms; end_ms = _end_ms; buffer = _buffer; - pipe = _pipe; + pipe = &_pipe; dc_command(this, DECODE_COMMAND_START); } diff --git a/src/DecoderControl.hxx b/src/DecoderControl.hxx index 98492c450..7f827d996 100644 --- a/src/DecoderControl.hxx +++ b/src/DecoderControl.hxx @@ -31,6 +31,7 @@ #include struct Song; +class MusicPipe; enum decoder_state { DECODE_STATE_STOP = 0, @@ -127,7 +128,7 @@ struct decoder_control { * The destination pipe for decoded chunks. The caller thread * owns this object, and is responsible for freeing it. */ - struct music_pipe *pipe; + MusicPipe *pipe; float replay_gain_db; float replay_gain_prev_db; @@ -287,7 +288,7 @@ struct decoder_control { * the caller) */ void Start(Song *song, unsigned start_ms, unsigned end_ms, - music_buffer *buffer, music_pipe *pipe); + music_buffer *buffer, MusicPipe &pipe); void Stop(); diff --git a/src/DecoderInternal.cxx b/src/DecoderInternal.cxx index c16124c3e..4d1e9a3d3 100644 --- a/src/DecoderInternal.cxx +++ b/src/DecoderInternal.cxx @@ -100,7 +100,7 @@ decoder_flush_chunk(struct decoder *decoder) if (decoder->chunk->IsEmpty()) music_buffer_return(dc->buffer, decoder->chunk); else - music_pipe_push(dc->pipe, decoder->chunk); + dc->pipe->Push(decoder->chunk); decoder->chunk = NULL; } diff --git a/src/MusicChunk.hxx b/src/MusicChunk.hxx index 87821fe1c..5eb1d619b 100644 --- a/src/MusicChunk.hxx +++ b/src/MusicChunk.hxx @@ -36,7 +36,7 @@ struct Tag; /** * A chunk of music data. Its format is defined by the - * music_pipe_append() caller. + * MusicPipe::Push() caller. */ struct music_chunk { /** the next chunk in a linked list */ diff --git a/src/MusicPipe.cxx b/src/MusicPipe.cxx index 5da56cd0c..2ff45748f 100644 --- a/src/MusicPipe.cxx +++ b/src/MusicPipe.cxx @@ -21,74 +21,15 @@ #include "MusicPipe.hxx" #include "MusicBuffer.hxx" #include "MusicChunk.hxx" -#include "thread/Mutex.hxx" - -#include - -#include - -struct music_pipe { - /** the first chunk */ - struct music_chunk *head; - - /** a pointer to the tail of the chunk */ - struct music_chunk **tail_r; - - /** the current number of chunks */ - unsigned size; - - /** a mutex which protects #head and #tail_r */ - mutable Mutex mutex; - -#ifndef NDEBUG - AudioFormat audio_format; -#endif - - music_pipe() - :head(nullptr), tail_r(&head), size(0) { -#ifndef NDEBUG - audio_format.Clear(); -#endif - } - - ~music_pipe() { - assert(head == nullptr); - assert(tail_r == &head); - } -}; - -struct music_pipe * -music_pipe_new(void) -{ - return new music_pipe(); -} - -void -music_pipe_free(struct music_pipe *mp) -{ - delete mp; -} #ifndef NDEBUG bool -music_pipe_check_format(const struct music_pipe *pipe, - const AudioFormat audio_format) +MusicPipe::Contains(const music_chunk *chunk) const { - assert(pipe != NULL); + const ScopeLock protect(mutex); - return !pipe->audio_format.IsDefined() || - pipe->audio_format == audio_format; -} - -bool -music_pipe_contains(const struct music_pipe *mp, - const struct music_chunk *chunk) -{ - const ScopeLock protect(mp->mutex); - - for (const struct music_chunk *i = mp->head; - i != NULL; i = i->next) + for (const struct music_chunk *i = head; i != nullptr; i = i->next) if (i == chunk) return true; @@ -97,40 +38,34 @@ music_pipe_contains(const struct music_pipe *mp, #endif -const struct music_chunk * -music_pipe_peek(const struct music_pipe *mp) +music_chunk * +MusicPipe::Shift() { - return mp->head; -} + const ScopeLock protect(mutex); -struct music_chunk * -music_pipe_shift(struct music_pipe *mp) -{ - const ScopeLock protect(mp->mutex); - - struct music_chunk *chunk = mp->head; - if (chunk != NULL) { + music_chunk *chunk = head; + if (chunk != nullptr) { assert(!chunk->IsEmpty()); - mp->head = chunk->next; - --mp->size; + head = chunk->next; + --size; - if (mp->head == NULL) { - assert(mp->size == 0); - assert(mp->tail_r == &chunk->next); + if (head == nullptr) { + assert(size == 0); + assert(tail_r == &chunk->next); - mp->tail_r = &mp->head; + tail_r = &head; } else { - assert(mp->size > 0); - assert(mp->tail_r != &chunk->next); + assert(size > 0); + assert(tail_r != &chunk->next); } #ifndef NDEBUG /* poison the "next" reference */ - chunk->next = (struct music_chunk *)(void *)0x01010101; + chunk->next = (music_chunk *)(void *)0x01010101; - if (mp->size == 0) - mp->audio_format.Clear(); + if (size == 0) + audio_format.Clear(); #endif } @@ -138,41 +73,34 @@ music_pipe_shift(struct music_pipe *mp) } void -music_pipe_clear(struct music_pipe *mp, struct music_buffer *buffer) +MusicPipe::Clear(music_buffer *buffer) { - struct music_chunk *chunk; + music_chunk *chunk; - while ((chunk = music_pipe_shift(mp)) != NULL) + while ((chunk = Shift()) != nullptr) music_buffer_return(buffer, chunk); } void -music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk) +MusicPipe::Push(music_chunk *chunk) { assert(!chunk->IsEmpty()); assert(chunk->length == 0 || chunk->audio_format.IsValid()); - const ScopeLock protect(mp->mutex); + const ScopeLock protect(mutex); - assert(mp->size > 0 || !mp->audio_format.IsDefined()); - assert(!mp->audio_format.IsDefined() || - chunk->CheckFormat(mp->audio_format)); + assert(size > 0 || !audio_format.IsDefined()); + assert(!audio_format.IsDefined() || + chunk->CheckFormat(audio_format)); #ifndef NDEBUG - if (!mp->audio_format.IsDefined() && chunk->length > 0) - mp->audio_format = chunk->audio_format; + if (!audio_format.IsDefined() && chunk->length > 0) + audio_format = chunk->audio_format; #endif - chunk->next = NULL; - *mp->tail_r = chunk; - mp->tail_r = &chunk->next; + chunk->next = nullptr; + *tail_r = chunk; + tail_r = &chunk->next; - ++mp->size; -} - -unsigned -music_pipe_size(const struct music_pipe *mp) -{ - const ScopeLock protect(mp->mutex); - return mp->size; + ++size; } diff --git a/src/MusicPipe.hxx b/src/MusicPipe.hxx index 39ad8e981..3d2e69d8d 100644 --- a/src/MusicPipe.hxx +++ b/src/MusicPipe.hxx @@ -20,12 +20,15 @@ #ifndef MPD_PIPE_H #define MPD_PIPE_H +#include "thread/Mutex.hxx" #include "gcc.h" #ifndef NDEBUG -struct AudioFormat; +#include "AudioFormat.hxx" #endif +#include + struct music_chunk; struct music_buffer; @@ -33,80 +36,98 @@ struct music_buffer; * A queue of #music_chunk objects. One party appends chunks at the * tail, and the other consumes them from the head. */ -struct music_pipe; +class MusicPipe { + /** the first chunk */ + music_chunk *head; -/** - * Creates a new #music_pipe object. It is empty. - */ -gcc_malloc -struct music_pipe * -music_pipe_new(void); + /** a pointer to the tail of the chunk */ + music_chunk **tail_r; -/** - * Frees the object. It must be empty now. - */ -void -music_pipe_free(struct music_pipe *mp); + /** the current number of chunks */ + unsigned size; + + /** a mutex which protects #head and #tail_r */ + mutable Mutex mutex; #ifndef NDEBUG - -/** - * Checks if the audio format if the chunk is equal to the specified - * audio_format. - */ -bool -music_pipe_check_format(const struct music_pipe *pipe, - AudioFormat audio_format); - -/** - * Checks if the specified chunk is enqueued in the music pipe. - */ -bool -music_pipe_contains(const struct music_pipe *mp, - const struct music_chunk *chunk); - + AudioFormat audio_format; #endif -/** - * Returns the first #music_chunk from the pipe. Returns NULL if the - * pipe is empty. - */ -gcc_pure -const struct music_chunk * -music_pipe_peek(const struct music_pipe *mp); +public: + /** + * Creates a new #MusicPipe object. It is empty. + */ + MusicPipe() + :head(nullptr), tail_r(&head), size(0) { +#ifndef NDEBUG + audio_format.Clear(); +#endif + } -/** - * Removes the first chunk from the head, and returns it. - */ -struct music_chunk * -music_pipe_shift(struct music_pipe *mp); + /** + * Frees the object. It must be empty now. + */ + ~MusicPipe() { + assert(head == nullptr); + assert(tail_r == &head); + } -/** - * Clears the whole pipe and returns the chunks to the buffer. - * - * @param buffer the buffer object to return the chunks to - */ -void -music_pipe_clear(struct music_pipe *mp, struct music_buffer *buffer); +#ifndef NDEBUG + /** + * Checks if the audio format if the chunk is equal to the specified + * audio_format. + */ + gcc_pure + bool CheckFormat(AudioFormat other) const { + return !audio_format.IsDefined() || + audio_format == other; + } -/** - * Pushes a chunk to the tail of the pipe. - */ -void -music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk); + /** + * Checks if the specified chunk is enqueued in the music pipe. + */ + gcc_pure + bool Contains(const music_chunk *chunk) const; +#endif -/** - * Returns the number of chunks currently in this pipe. - */ -gcc_pure -unsigned -music_pipe_size(const struct music_pipe *mp); + /** + * Returns the first #music_chunk from the pipe. Returns + * nullptr if the pipe is empty. + */ + gcc_pure + const music_chunk *Peek() const { + return head; + } -gcc_pure -static inline bool -music_pipe_empty(const struct music_pipe *mp) -{ - return music_pipe_size(mp) == 0; -} + /** + * Removes the first chunk from the head, and returns it. + */ + music_chunk *Shift(); + + /** + * Clears the whole pipe and returns the chunks to the buffer. + * + * @param buffer the buffer object to return the chunks to + */ + void Clear(music_buffer *buffer); + + /** + * Pushes a chunk to the tail of the pipe. + */ + void Push(music_chunk *chunk); + + /** + * Returns the number of chunks currently in this pipe. + */ + gcc_pure + unsigned GetSize() const { + return size; + } + + gcc_pure + bool IsEmpty() const { + return GetSize() == 0; + } +}; #endif diff --git a/src/OutputAll.cxx b/src/OutputAll.cxx index 49505323c..928a64a91 100644 --- a/src/OutputAll.cxx +++ b/src/OutputAll.cxx @@ -50,10 +50,10 @@ static unsigned int num_audio_outputs; static struct music_buffer *g_music_buffer; /** - * The #music_pipe object which feeds all audio outputs. It is filled + * The #MusicPipe object which feeds all audio outputs. It is filled * by audio_output_all_play(). */ -static struct music_pipe *g_mp; +static MusicPipe *g_mp; /** * The "elapsed_time" stamp of the most recently finished chunk. @@ -262,7 +262,7 @@ audio_output_all_update(void) for (i = 0; i < num_audio_outputs; ++i) ret = audio_output_update(audio_outputs[i], - input_audio_format, g_mp) || ret; + input_audio_format, *g_mp) || ret; return ret; } @@ -292,7 +292,7 @@ audio_output_all_play(struct music_chunk *chunk, Error &error) return false; } - music_pipe_push(g_mp, chunk); + g_mp->Push(chunk); for (i = 0; i < num_audio_outputs; ++i) audio_output_play(audio_outputs[i]); @@ -316,15 +316,14 @@ audio_output_all_open(const AudioFormat audio_format, /* the audio format must be the same as existing chunks in the pipe */ - assert(g_mp == NULL || music_pipe_check_format(g_mp, audio_format)); + assert(g_mp == NULL || g_mp->CheckFormat(audio_format)); if (g_mp == NULL) - g_mp = music_pipe_new(); + g_mp = new MusicPipe(); else /* if the pipe hasn't been cleared, the the audio format must not have changed */ - assert(music_pipe_empty(g_mp) || - audio_format == input_audio_format); + assert(g_mp->IsEmpty() || audio_format == input_audio_format); input_audio_format = audio_format; @@ -366,7 +365,7 @@ chunk_is_consumed_in(const struct audio_output *ao, if (ao->chunk == NULL) return false; - assert(chunk == ao->chunk || music_pipe_contains(g_mp, ao->chunk)); + assert(chunk == ao->chunk || g_mp->Contains(ao->chunk)); if (chunk != ao->chunk) { assert(chunk->next != NULL); @@ -401,7 +400,7 @@ static void clear_tail_chunk(gcc_unused const struct music_chunk *chunk, bool *locked) { assert(chunk->next == NULL); - assert(music_pipe_contains(g_mp, chunk)); + assert(g_mp->Contains(chunk)); for (unsigned i = 0; i < num_audio_outputs; ++i) { struct audio_output *ao = audio_outputs[i]; @@ -433,13 +432,13 @@ audio_output_all_check(void) assert(g_music_buffer != NULL); assert(g_mp != NULL); - while ((chunk = music_pipe_peek(g_mp)) != NULL) { - assert(!music_pipe_empty(g_mp)); + while ((chunk = g_mp->Peek()) != nullptr) { + assert(!g_mp->IsEmpty()); if (!chunk_is_consumed(chunk)) /* at least one output is not finished playing this chunk */ - return music_pipe_size(g_mp); + return g_mp->GetSize(); if (chunk->length > 0 && chunk->times >= 0.0) /* only update elapsed_time if the chunk @@ -453,7 +452,7 @@ audio_output_all_check(void) clear_tail_chunk(chunk, locked); /* remove the chunk from the pipe */ - shifted = music_pipe_shift(g_mp); + shifted = g_mp->Shift(); assert(shifted == chunk); if (is_tail) @@ -523,7 +522,7 @@ audio_output_all_cancel(void) /* clear the music pipe and return all chunks to the buffer */ if (g_mp != NULL) - music_pipe_clear(g_mp, g_music_buffer); + g_mp->Clear(g_music_buffer); /* the audio outputs are now waiting for a signal, to synchronize the cleared music pipe */ @@ -546,8 +545,8 @@ audio_output_all_close(void) if (g_mp != NULL) { assert(g_music_buffer != NULL); - music_pipe_clear(g_mp, g_music_buffer); - music_pipe_free(g_mp); + g_mp->Clear(g_music_buffer); + delete g_mp; g_mp = NULL; } @@ -569,8 +568,8 @@ audio_output_all_release(void) if (g_mp != NULL) { assert(g_music_buffer != NULL); - music_pipe_clear(g_mp, g_music_buffer); - music_pipe_free(g_mp); + g_mp->Clear(g_music_buffer); + delete g_mp; g_mp = NULL; } diff --git a/src/OutputAll.hxx b/src/OutputAll.hxx index fc27a4c6e..d48c44690 100644 --- a/src/OutputAll.hxx +++ b/src/OutputAll.hxx @@ -104,7 +104,7 @@ audio_output_all_set_replay_gain_mode(enum replay_gain_mode mode); /** * Enqueue a #music_chunk object for playing, i.e. pushes it to a - * #music_pipe. + * #MusicPipe. * * @param chunk the #music_chunk object to be played * @return true on success, false if no audio output was able to play @@ -117,13 +117,13 @@ audio_output_all_play(struct music_chunk *chunk, Error &error); * Checks if the output devices have drained their music pipe, and * returns the consumed music chunks to the #music_buffer. * - * @return the number of chunks to play left in the #music_pipe + * @return the number of chunks to play left in the #MusicPipe */ unsigned audio_output_all_check(void); /** - * Checks if the size of the #music_pipe is below the #threshold. If + * Checks if the size of the #MusicPipe is below the #threshold. If * not, it attempts to synchronize with all output threads, and waits * until another #music_chunk is finished. * diff --git a/src/OutputControl.cxx b/src/OutputControl.cxx index 820713593..2b372c5b7 100644 --- a/src/OutputControl.cxx +++ b/src/OutputControl.cxx @@ -141,14 +141,13 @@ audio_output_disable(struct audio_output *ao) static bool audio_output_open(struct audio_output *ao, const AudioFormat audio_format, - const struct music_pipe *mp) + const MusicPipe &mp) { bool open; assert(ao != NULL); assert(ao->allow_play); assert(audio_format.IsValid()); - assert(mp != NULL); if (ao->fail_timer != NULL) { g_timer_destroy(ao->fail_timer); @@ -156,12 +155,12 @@ audio_output_open(struct audio_output *ao, } if (ao->open && audio_format == ao->in_audio_format) { - assert(ao->pipe == mp || + assert(ao->pipe == &mp || (ao->always_on && ao->pause)); if (ao->pause) { ao->chunk = NULL; - ao->pipe = mp; + ao->pipe = ∓ /* unpause with the CANCEL command; this is a hack, but suits well for forcing the thread @@ -179,7 +178,7 @@ audio_output_open(struct audio_output *ao, ao->in_audio_format = audio_format; ao->chunk = NULL; - ao->pipe = mp; + ao->pipe = ∓ if (ao->thread == NULL) audio_output_thread_start(ao); @@ -223,10 +222,8 @@ audio_output_close_locked(struct audio_output *ao) bool audio_output_update(struct audio_output *ao, const AudioFormat audio_format, - const struct music_pipe *mp) + const MusicPipe &mp) { - assert(mp != NULL); - const ScopeLock protect(ao->mutex); if (ao->enabled && ao->really_enabled) { diff --git a/src/OutputControl.hxx b/src/OutputControl.hxx index 373b1849c..165afb28c 100644 --- a/src/OutputControl.hxx +++ b/src/OutputControl.hxx @@ -27,7 +27,7 @@ struct audio_output; struct AudioFormat; struct config_param; -struct music_pipe; +class MusicPipe; struct player_control; void @@ -54,7 +54,7 @@ audio_output_disable(struct audio_output *ao); bool audio_output_update(struct audio_output *ao, AudioFormat audio_format, - const struct music_pipe *mp); + const MusicPipe &mp); void audio_output_play(struct audio_output *ao); diff --git a/src/OutputInternal.hxx b/src/OutputInternal.hxx index 188a56723..fac25aa3c 100644 --- a/src/OutputInternal.hxx +++ b/src/OutputInternal.hxx @@ -31,6 +31,7 @@ class Error; class Filter; +class MusicPipe; struct config_param; enum audio_output_command { @@ -209,7 +210,7 @@ struct audio_output { /** * The music pipe which provides music chunks to be played. */ - const struct music_pipe *pipe; + const MusicPipe *pipe; /** * This mutex protects #open, #fail_timer, #chunk and diff --git a/src/OutputThread.cxx b/src/OutputThread.cxx index fb73e158d..5f94e76d8 100644 --- a/src/OutputThread.cxx +++ b/src/OutputThread.cxx @@ -263,7 +263,7 @@ ao_reopen(struct audio_output *ao) { if (!ao->config_audio_format.IsFullyDefined()) { if (ao->open) { - const struct music_pipe *mp = ao->pipe; + const MusicPipe *mp = ao->pipe; ao_close(ao, true); ao->pipe = mp; } @@ -484,7 +484,7 @@ ao_next_chunk(struct audio_output *ao) /* continue the previous play() call */ ? ao->chunk->next /* get the first chunk from the pipe */ - : music_pipe_peek(ao->pipe); + : ao->pipe->Peek(); } /** @@ -621,7 +621,7 @@ static gpointer audio_output_task(gpointer arg) case AO_COMMAND_DRAIN: if (ao->open) { assert(ao->chunk == NULL); - assert(music_pipe_peek(ao->pipe) == NULL); + assert(ao->pipe->Peek() == nullptr); ao->mutex.unlock(); ao_plugin_drain(ao); diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx index 83d9f55bd..d8fe20cf5 100644 --- a/src/PlayerThread.cxx +++ b/src/PlayerThread.cxx @@ -54,7 +54,7 @@ struct player { struct decoder_control *dc; - struct music_pipe *pipe; + MusicPipe *pipe; /** * are we waiting for buffered_before_play? @@ -166,7 +166,7 @@ player_command_finished(struct player_control *pc) * Player lock is not held. */ static void -player_dc_start(struct player *player, struct music_pipe *pipe) +player_dc_start(struct player *player, MusicPipe &pipe) { struct player_control *pc = player->pc; struct decoder_control *dc = player->dc; @@ -224,10 +224,10 @@ player_dc_stop(struct player *player) if (dc->pipe != NULL) { /* clear and free the decoder pipe */ - music_pipe_clear(dc->pipe, player_buffer); + dc->pipe->Clear(player_buffer); if (dc->pipe != player->pipe) - music_pipe_free(dc->pipe); + delete dc->pipe; dc->pipe = NULL; } @@ -493,10 +493,10 @@ static bool player_seek_decoder(struct player *player) /* clear music chunks which might still reside in the pipe */ - music_pipe_clear(player->pipe, player_buffer); + player->pipe->Clear(player_buffer); /* re-start the decoder */ - player_dc_start(player, player->pipe); + player_dc_start(player, *player->pipe); if (!player_wait_for_decoder(player)) { /* decoder failure */ player_command_finished(pc); @@ -506,8 +506,8 @@ static bool player_seek_decoder(struct player *player) if (!player_dc_at_current_song(player)) { /* the decoder is already decoding the "next" song, but it is the same song file; exchange the pipe */ - music_pipe_clear(player->pipe, player_buffer); - music_pipe_free(player->pipe); + player->pipe->Clear(player_buffer); + delete player->pipe; player->pipe = dc->pipe; } @@ -734,11 +734,10 @@ play_next_chunk(struct player *player) struct music_chunk *chunk = NULL; if (player->xfade == XFADE_ENABLED && player_dc_at_next_song(player) && - (cross_fade_position = music_pipe_size(player->pipe)) + (cross_fade_position = player->pipe->GetSize()) <= player->cross_fade_chunks) { /* perform cross fade */ - struct music_chunk *other_chunk = - music_pipe_shift(dc->pipe); + music_chunk *other_chunk = dc->pipe->Shift(); if (!player->cross_fading) { /* beginning of the cross fade - adjust @@ -750,7 +749,7 @@ play_next_chunk(struct player *player) } if (other_chunk != NULL) { - chunk = music_pipe_shift(player->pipe); + chunk = player->pipe->Shift(); assert(chunk != NULL); assert(chunk->other == NULL); @@ -806,7 +805,7 @@ play_next_chunk(struct player *player) } if (chunk == NULL) - chunk = music_pipe_shift(player->pipe); + chunk = player->pipe->Shift(); assert(chunk != NULL); @@ -848,8 +847,8 @@ play_next_chunk(struct player *player) larger block at a time */ dc->Lock(); if (!dc->IsIdle() && - music_pipe_size(dc->pipe) <= (pc->buffered_before_play + - music_buffer_size(player_buffer) * 3) / 4) + dc->pipe->GetSize() <= (pc->buffered_before_play + + music_buffer_size(player_buffer) * 3) / 4) dc->Signal(); dc->Unlock(); @@ -874,7 +873,7 @@ player_song_border(struct player *player) g_message("played \"%s\"", uri); g_free(uri); - music_pipe_free(player->pipe); + delete player->pipe; player->pipe = player->dc->pipe; audio_output_all_song_border(); @@ -910,15 +909,15 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) pc->Unlock(); - player.pipe = music_pipe_new(); + player.pipe = new MusicPipe(); - player_dc_start(&player, player.pipe); + player_dc_start(&player, *player.pipe); if (!player_wait_for_decoder(&player)) { assert(player.song == NULL); player_dc_stop(&player); player_command_finished(pc); - music_pipe_free(player.pipe); + delete player.pipe; GlobalEvents::Emit(GlobalEvents::PLAYLIST); pc->Lock(); return; @@ -949,7 +948,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) until the buffer is large enough, to prevent stuttering on slow machines */ - if (music_pipe_size(player.pipe) < pc->buffered_before_play && + if (player.pipe->GetSize() < pc->buffered_before_play && !dc->LockIsIdle()) { /* not enough decoded buffer space yet */ @@ -996,7 +995,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) assert(dc->pipe == NULL || dc->pipe == player.pipe); - player_dc_start(&player, music_pipe_new()); + player_dc_start(&player, *new MusicPipe()); } if (/* no cross-fading if MPD is going to pause at the @@ -1035,7 +1034,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) if (pc->command == PLAYER_COMMAND_NONE) pc->Wait(); continue; - } else if (!music_pipe_empty(player.pipe)) { + } else if (!player.pipe->IsEmpty()) { /* at least one music chunk is ready - send it to the audio output */ @@ -1056,7 +1055,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) /* check the size of the pipe again, because the decoder thread may have added something since we last checked */ - if (music_pipe_empty(player.pipe)) { + if (player.pipe->IsEmpty()) { /* wait for the hardware to finish playback */ audio_output_all_drain(); @@ -1075,8 +1074,8 @@ static void do_play(struct player_control *pc, struct decoder_control *dc) player_dc_stop(&player); - music_pipe_clear(player.pipe, player_buffer); - music_pipe_free(player.pipe); + player.pipe->Clear(player_buffer); + delete player.pipe; delete player.cross_fade_tag; diff --git a/src/PlayerThread.hxx b/src/PlayerThread.hxx index 197669cd6..7ed03f55a 100644 --- a/src/PlayerThread.hxx +++ b/src/PlayerThread.hxx @@ -31,7 +31,7 @@ * * The player thread itself does not do any I/O. It synchronizes with * other threads via #GMutex and #GCond objects, and passes - * #music_chunk instances around in #music_pipe objects. + * #music_chunk instances around in #MusicPipe objects. */ #ifndef MPD_PLAYER_THREAD_HXX