Using Theora Play audio into FMOD (C++)

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);
}

I would recommend checking out a project in our examples, user_created_sound, that shows how to create a sound with data filled by the user.