For decoding video files I managed to get Theora Play working in my project, but right now it feeds though SDL and I want to instead stream it into FMOD. I am suspecting it is similar, in FMOD, but I haven’t dug that low level in it just yet.
The way it currently flows starts simply by setting up the SDL audio system, including passing it a audio_callback function as well to use. Then as the decoder works it pulls out the audio per frame, and stuffs it into a “THEORAPLAY_AudioPacket” that is stored within a linked list. The list itself is used by the SDL library whenever it is calling the function it was linked before.
I have an FMOD framework I use already, but would love some tips, most notably any examples how to inject streaming audio. Would love if fmod supports Theora Play naively, but seems unlikely after trying a bit of searching the forum.
For a lark, tried something different, to read the ogv file raw for the heck of it. Not working yet, but not giving the error I expected, rather then invalid format I am getting “FMOD_ERR_FILE_COULDNOTSEEK”
Could be it just is unhappy with trying to read a video file, but I found this curious and something else a tad tricky to track down.
So for reference, and what I am trying to transfer over is this. This is a function that SDL’s audio library is passed during setup, and calls on its own. audio_queue is a linked list that is filled with each frame pulled from the decoder, and then passed though.
The code is a little off and I am trying to rework it for FMOD, but struggling to find ways to pump raw data into FMOD effectively.
static void SDLCALL audio_callback(void* userdata, Uint8* stream, int len)
{
Sint16* dst = (Sint16*)stream;
while (audio_queue && (len > 0)) {
volatile AudioQueue* item = audio_queue;
AudioQueue* next = item->next;
const int channels = item->audio->channels;
const float* src = item->audio->samples + (item->offset * channels);
int cpy = (item->audio->frames - item->offset) * channels;
int i;
if (cpy > (len / sizeof(Sint16)))
cpy = len / sizeof(Sint16);
for (i = 0; i < cpy; i++) {
const float val = *(src++);
if (val < -1.0f)
*(dst++) = -32768;
else if (val > 1.0f)
*(dst++) = 32767;
else
*(dst++) = (Sint16)(val * 32767.0f);
}
item->offset += (cpy / channels);
len -= cpy * sizeof(Sint16);
if (item->offset >= item->audio->frames) {
THEORAPLAY_freeAudio(item->audio);
SDL_free((void*)item);
audio_queue = next;
}
}
if (!audio_queue)
audio_queue_tail = NULL;
if (len > 0)
memset(dst, '\0', len);
}