diff options
author | Max Kellermann <max@duempel.org> | 2008-10-23 16:48:49 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-10-23 16:48:49 +0200 |
commit | 980f2ca56dbedb60aa3f880f66a97d151a107e62 (patch) | |
tree | ea209a4c759052d0fba121939edb2b0de9bdb7fc /src/outputBuffer.c | |
parent | 4f807b3aaa9617dfc35fb73ec898c8c9a22fded4 (diff) | |
download | mpd-980f2ca56dbedb60aa3f880f66a97d151a107e62.tar.gz mpd-980f2ca56dbedb60aa3f880f66a97d151a107e62.tar.xz mpd-980f2ca56dbedb60aa3f880f66a97d151a107e62.zip |
output_buffer: don't split frames
Splitting a frame between two buffer chunks causes distortion in the
output. MPD used to assume that the chunk size 1020 would never cause
splitted frames, but that isn't the case for 24 bit stereo (127.5
frames), and even less for files with even more channels.
Diffstat (limited to '')
-rw-r--r-- | src/outputBuffer.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/outputBuffer.c b/src/outputBuffer.c index 88191fd18..932ffd032 100644 --- a/src/outputBuffer.c +++ b/src/outputBuffer.c @@ -154,12 +154,13 @@ ob_chunk * ob_get_chunk(const unsigned i) */ static ob_chunk *tail_chunk(float data_time, uint16_t bitRate) { + const size_t frame_size = audio_format_frame_size(&ob.audioFormat); unsigned int next; ob_chunk *chunk; chunk = ob_get_chunk(ob.end); assert(chunk->chunkSize <= sizeof(chunk->data)); - if (chunk->chunkSize == sizeof(chunk->data)) { + if (chunk->chunkSize + frame_size > sizeof(chunk->data)) { /* this chunk is full; allocate a new chunk */ next = successor(ob.end); if (ob.begin == next) @@ -186,9 +187,13 @@ size_t ob_append(const void *data0, size_t datalen, float data_time, uint16_t bitRate) { const unsigned char *data = data0; + const size_t frame_size = audio_format_frame_size(&ob.audioFormat); size_t ret = 0, dataToSend; ob_chunk *chunk = NULL; + /* no partial frames allowed */ + assert((datalen % frame_size) == 0); + while (datalen) { chunk = tail_chunk(data_time, bitRate); if (chunk == NULL) @@ -198,6 +203,10 @@ size_t ob_append(const void *data0, size_t datalen, if (dataToSend > datalen) dataToSend = datalen; + /* don't split frames */ + dataToSend /= frame_size; + dataToSend *= frame_size; + memcpy(chunk->data + chunk->chunkSize, data, dataToSend); chunk->chunkSize += dataToSend; datalen -= dataToSend; |