mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-13 07:21:31 +00:00
* 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:
parent
a99bea5110
commit
aad0ec327a
7 changed files with 51 additions and 35 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue