music_chunk: added assertions on the audio format

In !NDEBUG, remember which audio_format is stored in every chunk and
every pipe.  Check the audio_format of every new data block appended
to the music_chunk, and the format of every new chunk appended to the
music_pipe.
This commit is contained in:
Max Kellermann 2009-03-08 13:45:24 +01:00
parent 359f9871b2
commit 94d1a87d04
5 changed files with 89 additions and 0 deletions

View File

@ -36,6 +36,19 @@ music_chunk_free(struct music_chunk *chunk)
tag_free(chunk->tag); tag_free(chunk->tag);
} }
#ifndef NDEBUG
bool
music_chunk_check_format(const struct music_chunk *chunk,
const struct audio_format *audio_format)
{
assert(chunk != NULL);
assert(audio_format != NULL);
return chunk->length == 0 ||
audio_format_equals(&chunk->audio_format, audio_format);
}
#endif
void * void *
music_chunk_write(struct music_chunk *chunk, music_chunk_write(struct music_chunk *chunk,
const struct audio_format *audio_format, const struct audio_format *audio_format,
@ -45,6 +58,8 @@ music_chunk_write(struct music_chunk *chunk,
const size_t frame_size = audio_format_frame_size(audio_format); const size_t frame_size = audio_format_frame_size(audio_format);
size_t num_frames; size_t num_frames;
assert(music_chunk_check_format(chunk, audio_format));
if (chunk->length == 0) { if (chunk->length == 0) {
/* if the chunk is empty, nobody has set bitRate and /* if the chunk is empty, nobody has set bitRate and
times yet */ times yet */
@ -57,6 +72,10 @@ music_chunk_write(struct music_chunk *chunk,
if (num_frames == 0) if (num_frames == 0)
return NULL; return NULL;
#ifndef NDEBUG
chunk->audio_format = *audio_format;
#endif
*max_length_r = num_frames * frame_size; *max_length_r = num_frames * frame_size;
return chunk->data + chunk->length; return chunk->data + chunk->length;
} }
@ -69,6 +88,7 @@ music_chunk_expand(struct music_chunk *chunk,
assert(chunk != NULL); assert(chunk != NULL);
assert(chunk->length + length <= sizeof(chunk->data)); assert(chunk->length + length <= sizeof(chunk->data));
assert(audio_format_equals(&chunk->audio_format, audio_format));
chunk->length += length; chunk->length += length;

View File

@ -19,6 +19,10 @@
#ifndef MPD_CHUNK_H #ifndef MPD_CHUNK_H
#define MPD_CHUNK_H #define MPD_CHUNK_H
#ifndef NDEBUG
#include "audio_format.h"
#endif
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
@ -57,6 +61,10 @@ struct music_chunk {
/** the data (probably PCM) */ /** the data (probably PCM) */
char data[CHUNK_SIZE]; char data[CHUNK_SIZE];
#ifndef NDEBUG
struct audio_format audio_format;
#endif
}; };
void void
@ -71,6 +79,16 @@ music_chunk_is_empty(const struct music_chunk *chunk)
return chunk->length == 0 && chunk->tag == NULL; return chunk->length == 0 && chunk->tag == NULL;
} }
#ifndef NDEBUG
/**
* Checks if the audio format if the chunk is equal to the specified
* audio_format.
*/
bool
music_chunk_check_format(const struct music_chunk *chunk,
const struct audio_format *audio_format);
#endif
/** /**
* Prepares appending to the music chunk. Returns a buffer where you * Prepares appending to the music chunk. Returns a buffer where you
* may write into. After you are finished, call music_chunk_expand(). * may write into. After you are finished, call music_chunk_expand().

View File

@ -36,6 +36,10 @@ struct music_pipe {
/** a mutex which protects #head and #tail_r */ /** a mutex which protects #head and #tail_r */
GMutex *mutex; GMutex *mutex;
#ifndef NDEBUG
struct audio_format audio_format;
#endif
}; };
struct music_pipe * struct music_pipe *
@ -48,6 +52,10 @@ music_pipe_new(void)
mp->size = 0; mp->size = 0;
mp->mutex = g_mutex_new(); mp->mutex = g_mutex_new();
#ifndef NDEBUG
audio_format_clear(&mp->audio_format);
#endif
return mp; return mp;
} }
@ -61,6 +69,19 @@ music_pipe_free(struct music_pipe *mp)
g_free(mp); g_free(mp);
} }
#ifndef NDEBUG
bool
music_pipe_check_format(const struct music_pipe *pipe,
const struct audio_format *audio_format)
{
assert(pipe != NULL);
assert(audio_format != NULL);
return !audio_format_defined(&pipe->audio_format) ||
audio_format_equals(&pipe->audio_format, audio_format);
}
#endif
const struct music_chunk * const struct music_chunk *
music_pipe_peek(const struct music_pipe *mp) music_pipe_peek(const struct music_pipe *mp)
{ {
@ -94,6 +115,9 @@ music_pipe_shift(struct music_pipe *mp)
#ifndef NDEBUG #ifndef NDEBUG
/* poison the "next" reference */ /* poison the "next" reference */
chunk->next = (void*)0x01010101; chunk->next = (void*)0x01010101;
if (mp->size == 0)
audio_format_clear(&mp->audio_format);
#endif #endif
} }
@ -118,6 +142,15 @@ music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk)
g_mutex_lock(mp->mutex); g_mutex_lock(mp->mutex);
assert(mp->size > 0 || !audio_format_defined(&mp->audio_format));
assert(!audio_format_defined(&mp->audio_format) ||
music_chunk_check_format(chunk, &mp->audio_format));
#ifndef NDEBUG
if (!audio_format_defined(&mp->audio_format) && chunk->length > 0)
mp->audio_format = chunk->audio_format;
#endif
chunk->next = NULL; chunk->next = NULL;
*mp->tail_r = chunk; *mp->tail_r = chunk;
mp->tail_r = &chunk->next; mp->tail_r = &chunk->next;

View File

@ -19,6 +19,12 @@
#ifndef MPD_PIPE_H #ifndef MPD_PIPE_H
#define MPD_PIPE_H #define MPD_PIPE_H
#ifndef NDEBUG
#include <stdbool.h>
struct audio_format;
#endif
struct music_chunk; struct music_chunk;
struct music_buffer; struct music_buffer;
@ -40,6 +46,16 @@ music_pipe_new(void);
void void
music_pipe_free(struct music_pipe *mp); music_pipe_free(struct music_pipe *mp);
#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,
const struct audio_format *audio_format);
#endif
/** /**
* Returns the first #music_chunk from the pipe. Returns NULL if the * Returns the first #music_chunk from the pipe. Returns NULL if the
* pipe is empty. * pipe is empty.

View File

@ -313,6 +313,8 @@ play_chunk(struct song *song, struct music_chunk *chunk,
{ {
bool success; bool success;
assert(music_chunk_check_format(chunk, format));
pc.elapsed_time = chunk->times; pc.elapsed_time = chunk->times;
pc.bit_rate = chunk->bit_rate; pc.bit_rate = chunk->bit_rate;