diff options
-rw-r--r-- | src/chunk.c | 42 | ||||
-rw-r--r-- | src/chunk.h | 36 | ||||
-rw-r--r-- | src/pipe.c | 21 |
3 files changed, 83 insertions, 16 deletions
diff --git a/src/chunk.c b/src/chunk.c index 8a91a1d11..65894f733 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -17,8 +17,11 @@ */ #include "chunk.h" +#include "audio_format.h" #include "tag.h" +#include <assert.h> + void music_chunk_init(struct music_chunk *chunk) { @@ -32,3 +35,42 @@ music_chunk_free(struct music_chunk *chunk) if (chunk->tag != NULL) tag_free(chunk->tag); } + +void * +music_chunk_write(struct music_chunk *chunk, + const struct audio_format *audio_format, + float data_time, uint16_t bit_rate, + size_t *max_length_r) +{ + const size_t frame_size = audio_format_frame_size(audio_format); + size_t num_frames; + + if (chunk->length == 0) { + /* if the chunk is empty, nobody has set bitRate and + times yet */ + + chunk->bit_rate = bit_rate; + chunk->times = data_time; + } + + num_frames = (sizeof(chunk->data) - chunk->length) / frame_size; + if (num_frames == 0) + return NULL; + + *max_length_r = num_frames * frame_size; + return chunk->data + chunk->length; +} + +bool +music_chunk_expand(struct music_chunk *chunk, + const struct audio_format *audio_format, size_t length) +{ + const size_t frame_size = audio_format_frame_size(audio_format); + + assert(chunk != NULL); + assert(chunk->length + length <= sizeof(chunk->data)); + + chunk->length += length; + + return chunk->length + frame_size > sizeof(chunk->data); +} diff --git a/src/chunk.h b/src/chunk.h index 747d018ca..58ed7be6f 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -19,13 +19,17 @@ #ifndef MPD_CHUNK_H #define MPD_CHUNK_H +#include <stdbool.h> #include <stdint.h> +#include <stddef.h> enum { /* pick 1020 since its devisible for 8,16,24, and 32-bit audio */ CHUNK_SIZE = 1020, }; +struct audio_format; + /** * A chunk of music data. Its format is defined by the * music_pipe_append() caller. @@ -58,4 +62,36 @@ music_chunk_init(struct music_chunk *chunk); void music_chunk_free(struct music_chunk *chunk); +/** + * Prepares appending to the music chunk. Returns a buffer where you + * may write into. After you are finished, call music_chunk_expand(). + * + * @param chunk the music_chunk object + * @param audio_format the audio format for the appended data; must + * stay the same for the life cycle of this chunk + * @param data_time the time within the song + * @param bit_rate the current bit rate of the source file + * @param max_length_r the maximum write length is returned here + * @return a writable buffer, or NULL if the chunk is full + */ +void * +music_chunk_write(struct music_chunk *chunk, + const struct audio_format *audio_format, + float data_time, uint16_t bit_rate, + size_t *max_length_r); + +/** + * Increases the length of the chunk after the caller has written to + * the buffer returned by music_chunk_write(). + * + * @param chunk the music_chunk object + * @param audio_format the audio format for the appended data; must + * stay the same for the life cycle of this chunk + * @param length the number of bytes which were appended + * @return true if the chunk is full + */ +bool +music_chunk_expand(struct music_chunk *chunk, + const struct audio_format *audio_format, size_t length); + #endif diff --git a/src/pipe.c b/src/pipe.c index 0c393c0b1..5aa931bd9 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -201,23 +201,13 @@ music_pipe_write(const struct audio_format *audio_format, { 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; - if (chunk->length == 0) { - /* if the chunk is empty, nobody has set bitRate and - times yet */ - - chunk->bit_rate = bit_rate; - chunk->times = data_time; - } - - num_frames = (sizeof(chunk->data) - chunk->length) / frame_size; - *max_length_r = num_frames * frame_size; - return chunk->data + chunk->length; + return music_chunk_write(chunk, audio_format, data_time, bit_rate, + max_length_r); } void @@ -225,17 +215,16 @@ 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; + bool full; /* no partial frames allowed */ assert(length % frame_size == 0); chunk = tail_chunk(frame_size); assert(chunk != NULL); - assert(chunk->length + length <= sizeof(chunk->data)); - - chunk->length += length; - if (chunk->length + frame_size > sizeof(chunk->data)) + full = music_chunk_expand(chunk, audio_format, length); + if (full) music_pipe_flush(); } |