* 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
This commit is contained in:
sezero 2013-07-22 11:41:14 +00:00
parent a99bea5110
commit aad0ec327a
7 changed files with 51 additions and 35 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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 ");

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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)