diff options
-rw-r--r-- | src/pipe.c | 78 | ||||
-rw-r--r-- | src/pipe.h | 18 |
2 files changed, 64 insertions, 32 deletions
diff --git a/src/pipe.c b/src/pipe.c index a11cfb4c5..b2680e37c 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -207,25 +207,49 @@ tail_chunk(size_t frame_size) return chunk; } -static size_t -music_chunk_append(struct music_chunk *chunk, const void *data, size_t length, - size_t frame_size) +void * +music_pipe_write(const struct audio_format *audio_format, + float data_time, uint16_t bit_rate, + size_t *max_length_r) { - size_t rest = sizeof(chunk->data) - chunk->length; + const size_t frame_size = audio_format_frame_size(audio_format); + struct music_chunk *chunk; + size_t num_frames; + + chunk = tail_chunk(frame_size); + if (chunk == NULL) + return NULL; - assert(rest >= frame_size); + if (chunk->length == 0) { + /* if the chunk is empty, nobody has set bitRate and + times yet */ - if (length > rest) - length = rest; + chunk->bit_rate = bit_rate; + chunk->times = data_time; + } - /* don't split frames */ - length /= frame_size; - length *= frame_size; + num_frames = (sizeof(chunk->data) - chunk->length) / frame_size; + *max_length_r = num_frames * frame_size; + return chunk->data + chunk->length; +} + +void +music_pipe_expand(const struct audio_format *audio_format, size_t length) +{ + const size_t frame_size = audio_format_frame_size(audio_format); + struct music_chunk *chunk; + + /* no partial frames allowed */ + assert(length % frame_size == 0); + + chunk = tail_chunk(frame_size); + assert(chunk != NULL); + assert(chunk->length + length <= sizeof(chunk->data)); - memcpy(chunk->data + chunk->length, data, length); chunk->length += length; - return length; + if (chunk->length + frame_size > sizeof(chunk->data)) + music_pipe_flush(); } size_t music_pipe_append(const void *data0, size_t datalen, @@ -233,38 +257,28 @@ size_t music_pipe_append(const void *data0, size_t datalen, float data_time, uint16_t bit_rate) { const unsigned char *data = data0; - const size_t frame_size = audio_format_frame_size(audio_format); size_t ret = 0, nbytes; - struct music_chunk *chunk = NULL; - - /* no partial frames allowed */ - assert((datalen % frame_size) == 0); + void *dest; while (datalen) { - chunk = tail_chunk(frame_size); - if (chunk == NULL) - return ret; + dest = music_pipe_write(audio_format, data_time, bit_rate, + &nbytes); + if (dest == NULL) + break; - if (chunk->length == 0) { - /* if the chunk is empty, nobody has set bitRate and - times yet */ + assert(nbytes > 0); - chunk->bit_rate = bit_rate; - chunk->times = data_time; - } + if (nbytes > datalen) + nbytes = datalen; - nbytes = music_chunk_append(chunk, data, datalen, - frame_size); - assert(nbytes > 0); + memcpy(dest, data, nbytes); + music_pipe_expand(audio_format, nbytes); datalen -= nbytes; data += nbytes; ret += nbytes; } - if (chunk != NULL && chunk->length == sizeof(chunk->data)) - music_pipe_flush(); - return ret; } diff --git a/src/pipe.h b/src/pipe.h index 7d82c1693..526bedb26 100644 --- a/src/pipe.h +++ b/src/pipe.h @@ -148,6 +148,24 @@ music_pipe_peek(void) } /** + * Prepares appending to the music pipe. Returns a buffer where you + * may write into. After you are finished, call music_pipe_expand(). + * + * @return a writable buffer + */ +void * +music_pipe_write(const struct audio_format *audio_format, + float data_time, uint16_t bit_rate, + size_t *max_length_r); + +/** + * Tells the music pipe to move the end pointer, after you have + * written to the buffer returned by music_pipe_write(). + */ +void +music_pipe_expand(const struct audio_format *audio_format, size_t length); + +/** * Append a data block to the buffer. * * @return the number of bytes actually written |