Decoder interface additions and changes

in preparation for the upcoming CDP architecture --
support for registering external decoders


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1279 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2003-10-19 11:33:31 +00:00
parent c4fc899bcf
commit c5071bbaae
6 changed files with 178 additions and 53 deletions
+140 -29
View File
@@ -36,11 +36,12 @@
extern bool fileExists2(uio_DirHandle *dir, const char *fileName);
// Can't '#include "libs/file.h"' due to some type conflicts.
#define MAX_REG_DECODERS 31
#define THIS_PTR TFB_SoundDecoder*
static const char* bufa_GetName (void);
static bool bufa_InitModule (int flags);
static bool bufa_InitModule (int flags, const TFB_DecoderFormats*);
static void bufa_TermModule ();
static uint32 bufa_GetStructSize (void);
static int bufa_GetError (THIS_PTR);
@@ -83,7 +84,7 @@ typedef struct tfb_bufsounddecoder
#define SD_MIN_SIZE (sizeof (TFB_BufSoundDecoder))
static const char* nula_GetName (void);
static bool nula_InitModule (int flags);
static bool nula_InitModule (int flags, const TFB_DecoderFormats*);
static void nula_TermModule ();
static uint32 nula_GetStructSize (void);
static int nula_GetError (THIS_PTR);
@@ -124,22 +125,24 @@ typedef struct tfb_nullsounddecoder
#undef THIS_PTR
static struct sd_DecoderInfo
struct TFB_RegSoundDecoder
{
bool builtin;
bool used; // ever used indicator
const char* ext;
TFB_SoundDecoderFuncs* funcs;
}
sd_decoders[] =
const TFB_SoundDecoderFuncs* funcs;
};
static TFB_RegSoundDecoder sd_decoders[MAX_REG_DECODERS + 1] =
{
{"wav", &wava_DecoderVtbl},
{"mod", &moda_DecoderVtbl},
{"ogg", &ova_DecoderVtbl},
{"duk", &duka_DecoderVtbl},
{NULL, NULL} // null term
{true, true, "wav", &wava_DecoderVtbl},
{true, true, "mod", &moda_DecoderVtbl},
{true, true, "ogg", &ova_DecoderVtbl},
{true, true, "duk", &duka_DecoderVtbl},
{false, false, NULL, NULL}, // null term
};
TFB_DecoderFormats decoder_formats;
static TFB_DecoderFormats decoder_formats;
static int sd_flags = 0;
/* change endianness of 16bit words
* Only works optimal when 'data' is aligned on a 32 bits boundary.
@@ -175,7 +178,7 @@ SoundDecoder_GetName (TFB_SoundDecoder *decoder)
sint32
SoundDecoder_Init (int flags, TFB_DecoderFormats *formats)
{
struct sd_DecoderInfo* info;
TFB_RegSoundDecoder* info;
sint32 ret = 0;
if (!formats)
@@ -185,26 +188,133 @@ SoundDecoder_Init (int flags, TFB_DecoderFormats *formats)
}
decoder_formats = *formats;
// init built-in decoders
for (info = sd_decoders; info->ext; info++)
{
if (!info->funcs->InitModule (flags))
if (!info->funcs->InitModule (flags, &decoder_formats))
{
fprintf (stderr, "SoundDecoder_Init(): %s audio decoder init failed\n",
fprintf (stderr, "SoundDecoder_Init(): "
"%s audio decoder init failed\n",
info->funcs->GetName ());
ret = 1;
}
}
return 0;
sd_flags = flags;
return ret;
}
void
SoundDecoder_Uninit (void)
{
struct sd_DecoderInfo* info;
TFB_RegSoundDecoder* info;
for (info = sd_decoders; info->ext; info++)
info->funcs->TermModule ();
// uninit all decoders
// and unregister loaded decoders
for (info = sd_decoders; info->used; info++)
{
if (info->ext) // check if present
info->funcs->TermModule ();
if (!info->builtin)
{
info->used = false;
info->ext = NULL;
}
}
}
TFB_RegSoundDecoder*
SoundDecoder_Register (const char* fileext, TFB_SoundDecoderFuncs* decvtbl)
{
TFB_RegSoundDecoder* info;
TFB_RegSoundDecoder* newslot = NULL;
if (!decvtbl)
{
fprintf (stderr, "SoundDecoder_Register(): Null decoder table\n");
return NULL;
}
if (!fileext)
{
fprintf (stderr, "SoundDecoder_Register(): Bad file type for %s\n",
decvtbl->GetName ());
return NULL;
}
// check if extension already registered
for (info = sd_decoders; info->used &&
(!info->ext || strcmp (info->ext, fileext) != 0);
++info)
{
// and pick up an empty slot (where available)
if (!newslot && !info->ext)
newslot = info;
}
if (info >= sd_decoders + MAX_REG_DECODERS)
{
fprintf (stderr, "SoundDecoder_Register(): Decoders limit reached\n");
return NULL;
}
else if (info->ext)
{
fprintf (stderr, "SoundDecoder_Register(): "
"'%s' decoder already registered (%s denied)\n",
fileext, decvtbl->GetName ());
return NULL;
}
if (!decvtbl->InitModule (sd_flags, &decoder_formats))
{
fprintf (stderr, "SoundDecoder_Register(): %s decoder init failed\n",
decvtbl->GetName ());
return NULL;
}
if (!newslot)
{
newslot = info;
newslot->used = true;
// make next one a term
info[1].builtin = false;
info[1].used = false;
info[1].ext = NULL;
}
newslot->ext = fileext;
newslot->funcs = decvtbl;
return newslot;
}
void
SoundDecoder_Unregister (TFB_RegSoundDecoder* regdec)
{
if (regdec < sd_decoders || regdec >= sd_decoders + MAX_REG_DECODERS ||
!regdec->ext || !regdec->funcs)
{
fprintf (stderr, "SoundDecoder_Unregister(): "
"Invalid or expired decoder passed\n");
return;
}
regdec->funcs->TermModule ();
regdec->ext = NULL;
regdec->funcs = NULL;
}
const TFB_SoundDecoderFuncs*
SoundDecoder_Lookup (const char* fileext)
{
TFB_RegSoundDecoder* info;
for (info = sd_decoders; info->used &&
(!info->ext || strcmp (info->ext, fileext) != 0);
++info)
;
return info->ext ? info->funcs : NULL;
}
TFB_SoundDecoder*
@@ -212,8 +322,8 @@ SoundDecoder_Load (uio_DirHandle *dir, char *filename,
uint32 buffer_size, uint32 startTime, sint32 runTime)
{
const char* pext;
struct sd_DecoderInfo* info;
TFB_SoundDecoderFuncs* funcs;
TFB_RegSoundDecoder* info;
const TFB_SoundDecoderFuncs* funcs;
TFB_SoundDecoder* decoder;
uint32 struct_size;
@@ -226,8 +336,8 @@ SoundDecoder_Load (uio_DirHandle *dir, char *filename,
}
++pext;
for (info = sd_decoders;
info->ext && strcmp (info->ext, pext) != 0;
for (info = sd_decoders; info->used &&
(!info->ext || strcmp (info->ext, pext) != 0);
++info)
;
if (!info->ext)
@@ -364,7 +474,8 @@ SoundDecoder_Decode (TFB_SoundDecoder *decoder)
if (decoder->error)
{
fprintf (stderr, "SoundDecoder_Decode(): "
"tried to loop %s but couldn't rewind, error code %d\n",
"tried to loop %s but couldn't rewind, "
"error code %d\n",
decoder->filename, decoder->error);
}
else
@@ -571,13 +682,13 @@ bufa_GetName (void)
}
static bool
bufa_InitModule (int flags)
bufa_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
// this should never be called
fprintf (stderr, "bufa_InitModule(): dead function called\n");
return false;
(void)flags; // laugh at compiler warning
(void)flags; (void)fmts; // laugh at compiler warning
}
static void
@@ -699,13 +810,13 @@ nula_GetName (void)
}
static bool
nula_InitModule (int flags)
nula_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
// this should never be called
fprintf (stderr, "nula_InitModule(): dead function called\n");
return false;
(void)flags; // laugh at compiler warning
(void)flags; (void)fmts; // laugh at compiler warning
}
static void
@@ -47,7 +47,7 @@ typedef struct tfb_sounddecoder TFB_SoundDecoder;
typedef struct tfb_sounddecoderfunc
{
const char* (* GetName) (void);
bool (* InitModule) (int flags);
bool (* InitModule) (int flags, const TFB_DecoderFormats*);
void (* TermModule) ();
uint32 (* GetStructSize) (void);
int (* GetError) (THIS_PTR);
@@ -103,7 +103,13 @@ enum
SOUNDDECODER_EOF,
};
extern TFB_DecoderFormats decoder_formats;
typedef struct TFB_RegSoundDecoder TFB_RegSoundDecoder;
TFB_RegSoundDecoder* SoundDecoder_Register (const char* fileext,
TFB_SoundDecoderFuncs* decvtbl);
void SoundDecoder_Unregister (TFB_RegSoundDecoder* regdec);
const TFB_SoundDecoderFuncs* SoundDecoder_Lookup (const char* fileext);
void SoundDecoder_SwapWords (uint16* data, uint32 size);
sint32 SoundDecoder_Init (int flags, TFB_DecoderFormats* formats);
void SoundDecoder_Uninit (void);
+7 -5
View File
@@ -35,7 +35,7 @@
#define THIS_PTR TFB_SoundDecoder* This
static const char* duka_GetName (void);
static bool duka_InitModule (int flags);
static bool duka_InitModule (int flags, const TFB_DecoderFormats*);
static void duka_TermModule ();
static uint32 duka_GetStructSize (void);
static int duka_GetError (THIS_PTR);
@@ -103,6 +103,8 @@ typedef struct
uint16 indices[2]; // initial indices for channels
} DukAud_AudSubframe;
static const TFB_DecoderFormats* duka_formats = NULL;
sint32
duka_readAudFrameHeader (TFB_DuckSoundDecoder* duka, uint32 iframe,
DukAud_AudSubframe* aud)
@@ -338,9 +340,9 @@ duka_GetName (void)
}
static bool
duka_InitModule (int flags)
duka_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
// no specific module init
duka_formats = fmts;
return true;
(void)flags; // laugh at compiler warning
@@ -372,7 +374,7 @@ duka_Init (THIS_PTR)
{
//TFB_DuckSoundDecoder* duka = (TFB_DuckSoundDecoder*) This;
This->need_swap =
decoder_formats.big_endian != decoder_formats.want_big_endian;
duka_formats->big_endian != duka_formats->want_big_endian;
return true;
}
@@ -449,7 +451,7 @@ duka_Open (THIS_PTR, uio_DirHandle *dir, const char *file)
}
This->frequency = 22050;
This->format = decoder_formats.stereo16;
This->format = duka_formats->stereo16;
duka->channels = 2;
duka->pcm_frame = aud.numsamples;
duka->data = HMalloc (DATA_BUF_SIZE);
+7 -5
View File
@@ -32,7 +32,7 @@
#define THIS_PTR TFB_SoundDecoder* This
static const char* moda_GetName (void);
static bool moda_InitModule (int flags);
static bool moda_InitModule (int flags, const TFB_DecoderFormats*);
static void moda_TermModule ();
static uint32 moda_GetStructSize (void);
static int moda_GetError (THIS_PTR);
@@ -72,7 +72,7 @@ typedef struct tfb_modsounddecoder
} TFB_ModSoundDecoder;
MIKMODAPI extern struct MDRIVER drv_openal;
static const TFB_DecoderFormats* moda_formats = NULL;
static const char*
moda_GetName (void)
@@ -81,7 +81,7 @@ moda_GetName (void)
}
static bool
moda_InitModule (int flags)
moda_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
MikMod_RegisterDriver (&drv_openal);
MikMod_RegisterAllLoaders ();
@@ -114,6 +114,8 @@ moda_InitModule (int flags)
return false;
}
moda_formats = fmts;
return true;
}
@@ -143,7 +145,7 @@ moda_Init (THIS_PTR)
{
//TFB_ModSoundDecoder* moda = (TFB_ModSoundDecoder*) This;
This->need_swap =
decoder_formats.big_endian != decoder_formats.want_big_endian;
moda_formats->big_endian != moda_formats->want_big_endian;
return true;
}
@@ -173,7 +175,7 @@ moda_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
mod->wrap = 0;
mod->loop = 1;
This->format = decoder_formats.stereo16;
This->format = moda_formats->stereo16;
This->frequency = md_mixfreq;
This->length = 0; // FIXME way to obtain this from mikmod?
+8 -6
View File
@@ -33,7 +33,7 @@
#define THIS_PTR TFB_SoundDecoder* This
static const char* ova_GetName (void);
static bool ova_InitModule (int flags);
static bool ova_InitModule (int flags, const TFB_DecoderFormats*);
static void ova_TermModule ();
static uint32 ova_GetStructSize (void);
static int ova_GetError (THIS_PTR);
@@ -72,6 +72,8 @@ typedef struct tfb_oggsounddecoder
} TFB_OggSoundDecoder;
static const TFB_DecoderFormats* ova_formats = NULL;
static size_t
ogg_read (void *ptr, size_t size, size_t nmemb, void *datasource)
{
@@ -112,9 +114,9 @@ ova_GetName (void)
}
static bool
ova_InitModule (int flags)
ova_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
// no specific module init
ova_formats = fmts;
return true;
(void)flags; // laugh at compiler warning
@@ -195,9 +197,9 @@ ova_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
This->length = (float) ov_time_total (&ova->vf, -1);
if (vinfo->channels == 1)
This->format = decoder_formats.mono16;
This->format = ova_formats->mono16;
else
This->format = decoder_formats.stereo16;
This->format = ova_formats->stereo16;
ova->last_error = 0;
@@ -219,7 +221,7 @@ ova_Decode (THIS_PTR, void* buf, sint32 bufsize)
long rc;
int bitstream;
rc = ov_read (&ova->vf, buf, bufsize, decoder_formats.want_big_endian,
rc = ov_read (&ova->vf, buf, bufsize, ova_formats->want_big_endian,
2, 1, &bitstream);
if (rc < 0)
+8 -6
View File
@@ -60,7 +60,7 @@ typedef struct
#define THIS_PTR TFB_SoundDecoder* This
static const char* wava_GetName (void);
static bool wava_InitModule (int flags);
static bool wava_InitModule (int flags, const TFB_DecoderFormats*);
static void wava_TermModule ();
static uint32 wava_GetStructSize (void);
static int wava_GetError (THIS_PTR);
@@ -104,6 +104,8 @@ typedef struct tfb_wavesounddecoder
} TFB_WaveSoundDecoder;
static const TFB_DecoderFormats* wava_formats = NULL;
static const char*
wava_GetName (void)
@@ -112,9 +114,9 @@ wava_GetName (void)
}
static bool
wava_InitModule (int flags)
wava_InitModule (int flags, const TFB_DecoderFormats* fmts)
{
// no specific module init
wava_formats = fmts;
return true;
(void)flags; // laugh at compiler warning
@@ -145,7 +147,7 @@ static bool
wava_Init (THIS_PTR)
{
//TFB_WaveSoundDecoder* wava = (TFB_WaveSoundDecoder*) This;
This->need_swap = decoder_formats.want_big_endian;
This->need_swap = wava_formats->want_big_endian;
return true;
}
@@ -284,10 +286,10 @@ wava_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
{
This->format = (wava->FmtHdr.Channels == 1 ?
(wava->FmtHdr.BitsPerSample == 8 ?
decoder_formats.mono8 : decoder_formats.mono16)
wava_formats->mono8 : wava_formats->mono16)
:
(wava->FmtHdr.BitsPerSample == 8 ?
decoder_formats.stereo8 : decoder_formats.stereo16)
wava_formats->stereo8 : wava_formats->stereo16)
);
This->frequency = wava->FmtHdr.SamplesPerSec;
}