From aad0ec327a99c8e2feaeddcced5590b0d34bcf02 Mon Sep 17 00:00:00 2001 From: sezero Date: Mon, 22 Jul 2013 11:41:14 +0000 Subject: [PATCH] * snd_codec: store the samplebits value in the snd_info_t struct, and add a new blocksize field to it which the flac decoder can use. updated decoder sources for the snd_info_t changes, where I made minor tidy-ups too, tightening several format checks and fixing a few gotchas in snd_wave.c and snd_mem.c. * snd_flac.c: adjusted for snd_info_t changes. no longed storing metadata->data.stream_info in our private data, but just storing a pointer to the stream->info structure. No longer checking the metadata total_samples field (the FLAC__StreamMetadata_StreamInfo doesn't seem to have any alignment or pack attributes and I don't safe with its offset across different compilers), but added check to make sure that we hit and parsed a STREAMINFO metadata instead, and our new state seems just fine for validating the file. git-svn-id: http://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@859 af15c1b1-3010-417e-b628-4374ebc0bcbd --- Quake/snd_codec.h | 3 ++- Quake/snd_flac.c | 49 ++++++++++++++++++++++++++-------------------- Quake/snd_mem.c | 5 ++++- Quake/snd_mpg123.c | 4 ++++ Quake/snd_opus.c | 1 + Quake/snd_vorbis.c | 5 +++-- Quake/snd_wave.c | 19 +++++++++--------- 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/Quake/snd_codec.h b/Quake/snd_codec.h index f7580599..c38d7bf3 100644 --- a/Quake/snd_codec.h +++ b/Quake/snd_codec.h @@ -29,9 +29,10 @@ typedef struct snd_info_s { int rate; - int width; + int bits, width; int channels; int samples; + int blocksize; int size; int dataofs; } snd_info_t; diff --git a/Quake/snd_flac.c b/Quake/snd_flac.c index 36500eb7..0bcce00b 100644 --- a/Quake/snd_flac.c +++ b/Quake/snd_flac.c @@ -68,7 +68,7 @@ typedef struct { FLAC__StreamDecoder *decoder; fshandle_t *file; - FLAC__StreamMetadata_StreamInfo info; + snd_info_t *info; byte *buffer; int size, pos, error; } flacfile_t; @@ -144,26 +144,25 @@ flac_write_func (const FLAC__StreamDecoder *decoder, void *client_data) { flacfile_t *ff = (flacfile_t *) client_data; - int bps = ff->info.bits_per_sample / 8; if (!ff->buffer) { #if 1 /*!defined(CODECS_USE_ZONE)*/ - ff->buffer = (byte *) malloc (ff->info.max_blocksize * ff->info.channels * bps); + ff->buffer = (byte *) malloc (ff->info->blocksize * ff->info->channels * ff->info->width); if (!ff->buffer) { ff->error = -1; /* needn't set this here, but... */ Con_Printf("Insufficient memory for fLaC audio\n"); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } #else - ff->buffer = (byte *) Z_Malloc (ff->info.max_blocksize * ff->info.channels * bps); + ff->buffer = (byte *) Z_Malloc (ff->info->blocksize * ff->info->channels * ff->info->width); #endif } - if (ff->info.channels == 1) + if (ff->info->channels == 1) { unsigned i; const FLAC__int32 *in = buffer[0]; - if (ff->info.bits_per_sample == 8) + if (ff->info->bits == 8) { byte *out = ff->buffer; for (i = 0; i < frame->header.blocksize; i++) @@ -182,7 +181,7 @@ flac_write_func (const FLAC__StreamDecoder *decoder, const FLAC__int32 *li = buffer[0]; const FLAC__int32 *ri = buffer[1]; - if (ff->info.bits_per_sample == 8) + if (ff->info->bits == 8) { char *lo = (char *) ff->buffer + 0; char *ro = (char *) ff->buffer + 1; @@ -204,7 +203,7 @@ flac_write_func (const FLAC__StreamDecoder *decoder, } } - ff->size = frame->header.blocksize * bps * ff->info.channels; + ff->size = frame->header.blocksize * ff->info->width * ff->info->channels; ff->pos = 0; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } @@ -215,7 +214,14 @@ flac_meta_func (const FLAC__StreamDecoder *decoder, { flacfile_t *ff = (flacfile_t *) client_data; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) - ff->info = metadata->data.stream_info; + { + ff->info->rate = metadata->data.stream_info.sample_rate; + ff->info->bits = metadata->data.stream_info.bits_per_sample; + ff->info->width = ff->info->bits / 8; + ff->info->channels = metadata->data.stream_info.channels; + ff->info->blocksize = metadata->data.stream_info.max_blocksize; + ff->info->dataofs = 0; /* got the STREAMINFO metadata */ + } } @@ -248,7 +254,9 @@ static snd_stream_t *S_FLAC_CodecOpenStream (const char *filename) } stream->priv = ff; + ff->info = & stream->info; ff->file = & stream->fh; + ff->info->dataofs = -1; /* check for STREAMINFO metadata existence */ #ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_set_error_callback (ff->decoder, flac_error_func); @@ -280,32 +288,31 @@ static snd_stream_t *S_FLAC_CodecOpenStream (const char *filename) } rc = FLAC__stream_decoder_process_until_end_of_metadata (ff->decoder); - if (rc == false) + if (rc == false || ff->error) { rc = FLAC__stream_decoder_get_state(ff->decoder); - Con_Printf("%s not a valid fLaC file? (error %i)\n", + Con_Printf("%s not a valid flac file? (decoder state %i)\n", filename, rc); goto _fail; } - if (ff->error) /* set by flac_error_func(). can we hit it here?? */ - goto _fail; - if (ff->info.total_samples == 0) + if (ff->info->dataofs < 0) { - Con_Printf("Zero sample count in %s\n", filename); + Con_Printf("%s has no STREAMINFO\n", filename); goto _fail; } - if (ff->info.channels != 1 && ff->info.channels != 2) + if (ff->info->bits != 8 && ff->info->bits != 16) + { + Con_Printf("%s is not 8 or 16 bit\n", filename); + goto _fail; + } + if (ff->info->channels != 1 && ff->info->channels != 2) { Con_Printf("Unsupported number of channels %d in %s\n", - ff->info.channels, filename); + ff->info->channels, filename); goto _fail; } - stream->info.rate = ff->info.sample_rate; - stream->info.width = ff->info.bits_per_sample / 8; - stream->info.channels = ff->info.channels; - return stream; _fail: if (ff->decoder) diff --git a/Quake/snd_mem.c b/Quake/snd_mem.c index e7970a19..bb2ab473 100644 --- a/Quake/snd_mem.c +++ b/Quake/snd_mem.c @@ -297,7 +297,10 @@ wavinfo_t GetWavinfo (const char *name, byte *wav, int wavlength) info.channels = GetLittleShort(); info.rate = GetLittleLong(); data_p += 4 + 2; - info.width = GetLittleShort() / 8; + i = GetLittleShort(); + if (i != 8 && i != 16) + return info; + info.width = i / 8; // get cue chunk FindChunk("cue "); diff --git a/Quake/snd_mpg123.c b/Quake/snd_mpg123.c index b9c3a4c8..c34c0048 100644 --- a/Quake/snd_mpg123.c +++ b/Quake/snd_mpg123.c @@ -139,19 +139,23 @@ static snd_stream_t *S_MP3_CodecOpenStream (const char *filename) switch (encoding) { case MPG123_ENC_UNSIGNED_8: + stream->info.bits = 8; stream->info.width = 1; break; case MPG123_ENC_SIGNED_8: /* unsupported: force mpg123 to convert */ + stream->info.bits = 8; stream->info.width = 1; encoding = MPG123_ENC_UNSIGNED_8; break; case MPG123_ENC_SIGNED_16: + stream->info.bits = 16; stream->info.width = 2; break; case MPG123_ENC_UNSIGNED_16: default: /* unsupported: force mpg123 to convert */ + stream->info.bits = 16; stream->info.width = 2; encoding = MPG123_ENC_SIGNED_16; break; diff --git a/Quake/snd_opus.c b/Quake/snd_opus.c index c901ae2c..09282c19 100644 --- a/Quake/snd_opus.c +++ b/Quake/snd_opus.c @@ -141,6 +141,7 @@ static snd_stream_t *S_OPUS_CodecOpenStream (const char *filename) stream->info.rate = 48000; stream->info.channels = op_info->channel_count; /* op_read() yields 16-bit output using native endian ordering: */ + stream->info.bits = 16; stream->info.width = 2; return stream; diff --git a/Quake/snd_vorbis.c b/Quake/snd_vorbis.c index e7017e69..c677ebc5 100644 --- a/Quake/snd_vorbis.c +++ b/Quake/snd_vorbis.c @@ -39,6 +39,7 @@ /* Vorbis codec can return the samples in a number of different * formats, we use the standard signed short format. */ +#define VORBIS_SAMPLEBITS 16 #define VORBIS_SAMPLEWIDTH 2 #define VORBIS_SIGNED_DATA 1 @@ -87,6 +88,7 @@ static snd_stream_t *S_VORBIS_CodecOpenStream (const char *filename) return NULL; ovFile = (OggVorbis_File *) Z_Malloc(sizeof(OggVorbis_File)); + stream->priv = ovFile; res = OV_OPEN_CALLBACKS(&stream->fh, ovFile, NULL, 0, ovc_qfs); if (res != 0) { @@ -95,8 +97,6 @@ static snd_stream_t *S_VORBIS_CodecOpenStream (const char *filename) goto _fail; } - stream->priv = ovFile; - if (!ov_seekable(ovFile)) { Con_Printf("Stream %s not seekable.\n", filename); @@ -128,6 +128,7 @@ static snd_stream_t *S_VORBIS_CodecOpenStream (const char *filename) stream->info.rate = ovf_info->rate; stream->info.channels = ovf_info->channels; + stream->info.bits = VORBIS_SAMPLEBITS; stream->info.width = VORBIS_SAMPLEWIDTH; return stream; diff --git a/Quake/snd_wave.c b/Quake/snd_wave.c index 1f09c4d3..c08b9435 100644 --- a/Quake/snd_wave.c +++ b/Quake/snd_wave.c @@ -117,7 +117,6 @@ static qboolean WAV_ReadRIFFHeader(const char *name, FILE *file, snd_info_t *inf { char dump[16]; int wav_format; - int bits; int fmtlen = 0; if (fread(dump, 1, 12, file) < 12 || @@ -147,15 +146,15 @@ static qboolean WAV_ReadRIFFHeader(const char *name, FILE *file, snd_info_t *inf info->rate = FGetLittleLong(file); FGetLittleLong(file); FGetLittleShort(file); - bits = FGetLittleShort(file); + info->bits = FGetLittleShort(file); - if (bits != 8 && bits != 16) + if (info->bits != 8 && info->bits != 16) { Con_Printf("%s is not 8 or 16 bit\n", name); return false; } - info->width = bits / 8; + info->width = info->bits / 8; info->dataofs = 0; /* Skip the rest of the format chunk if required */ @@ -172,6 +171,12 @@ static qboolean WAV_ReadRIFFHeader(const char *name, FILE *file, snd_info_t *inf return false; } + if (info->channels != 1 && info->channels != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + info->channels, name); + return false; + } info->samples = (info->size / info->width) / info->channels; if (info->samples == 0) { @@ -204,12 +209,6 @@ snd_stream_t *S_WAV_CodecOpenStream(const char *filename) * file by ourselves from now on. */ if (!WAV_ReadRIFFHeader(filename, stream->fh.file, &stream->info)) goto _fail; - if (stream->info.channels != 1 && stream->info.channels != 2) - { - Con_Printf("Unsupported number of channels %d in %s\n", - stream->info.channels, filename); - goto _fail; - } stream->fh.start = ftell(stream->fh.file); /* reset to data position */ if (stream->fh.start - start + stream->info.size > stream->fh.length)