# If fmod can play the audio in a video file?

**URL:** <https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252>\
**Category:** FMOD Studio\
**Created:** [December 30, 2013, 1:10am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252 "2013-12-30T01:10:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [December 30, 2013, 1:10am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/1 "2013-12-30T01:10:42Z")

</div>

We use webm video format in our game,which the audio part of it is ogg.  
I separatede the video and audio data by using libwebm.  
Can I use fmod to play the audio data?  
libwebm parse the file piece by piece. So I can’t get the whole audio data at the beginnning.  
Is there any examples if fmod support this?

---

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [January 13, 2014, 11:09am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/2 "2014-01-13T11:09:52Z")

</div>

Oh,There do have a race condition. It’s my fault.  
I have fixed this error and play both sounds and pictures.  
Thanks for your help.

---

<div class="post-metadata">

**Author:** ![nick1](https://avatars.discourse-cdn.com/v4/letter/n/47e85d/32.png) [@nick1](https://qa.fmod.com/u/nick1)\
**Post date:** [January 12, 2014, 10:53pm UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/3 "2014-01-12T22:53:31Z")

</div>

This is off-topic, but there is a race condition in the code sample you posted. You should be calling ResetEvent inside the first critical section block e.g. if ( bAudioFrameQueueEmpty ) ResetEvent(…);

For the second question, createStream() is the correct function to be calling.

---

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [January 9, 2014, 5:27am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/4 "2014-01-09T05:27:41Z")

</div>

Thanks for your reply.  
I have played the sound in this way.  
But I met another problem when I try to play both pictures and sounds.  
Don’t consider synching picture with sound.Main thread decode the image and display it.  
When meeting a audio frame,it put the audio frame into a queue.  
PCMCALLBACK pick data from the queue.It will wait if there is not enough data in the queue.

```auto
			
//put the audio frame in a std::deque (main thread)
else if(pTrack->GetType() == mkvparser::Track::kAudio)
{
				const mkvparser::Block::Frame& Frame = block_ptr->GetFrame(m_frame_state.m_frame_idx);
				const mkvparser::Block::Frame* pFrame = &Frame;
				
				EnterCriticalSection(&g_AudioC_S);
				m_AudioFrameDeque.push_back(pFrame);

				std::deque<const mkvparser::Block::Frame*>::size_type size = m_AudioFrameDeque.size();

				if (size > 20)
				{
					SetEvent(g_hAudioDequeEvent);
				}

				LeaveCriticalSection(&g_AudioC_S);
}//kAudio
```

```auto
// pick data from deque (PCMCALLBACK)
	while ( datalen > 0 )
	{
		EnterCriticalSection(&g_AudioC_S);

		bAudioFrameQueueEmpty = m_AudioFrameDeque.empty();

		LeaveCriticalSection(&g_AudioC_S);
		
		if ( bAudioFrameQueueEmpty )
		{
			WaitForSingleObject(g_hAudioDequeEvent, INFINITE);

			ResetEvent(g_hAudioDequeEvent);

			if (g_bQuit)
			{
				return -1;
			}
		}

		EnterCriticalSection(&g_AudioC_S);

		std::deque<const mkvparser::Block::Frame*>::size_type size = m_AudioFrameDeque.size();
		if ( size <= 0 )
		{
		}

		const mkvparser::Block::Frame* pFrame = m_AudioFrameDeque.front();
		m_AudioFrameDeque.pop_front();

		LeaveCriticalSection(&g_AudioC_S);
             
               ...

         }

```

But sometimes WaitForSingleObject can’t block the thread when g\_hAudioDequeEvent is non-signaled, even through the return value is WAIT\_OBJECT\_0. Then lead to an error.  
This is only two place used the deque and g\_hAudioDequeEvent EVENT.

Another question is

Here is how I create the Sound

```auto
	FMOD_CREATESOUNDEXINFO infopcm;
	memset(&infopcm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
	infopcm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
	infopcm.numchannels = 2;
	infopcm.defaultfrequency = 44100;
	infopcm.decodebuffersize = 0;
	infopcm.length = infopcm.defaultfrequency * infopcm.numchannels * 4 * kvm_r.GetAudioDurationInSecond();
	infopcm.format = FMOD_SOUND_FORMAT_PCMFLOAT;
	infopcm.pcmreadcallback = pcmreadcallback;
	infopcm.pcmsetposcallback = pcmsetposcallback;

	result = g_pFmodSystem->createStream(0, 
		FMOD_OPENUSER | FMOD_LOOP_OFF | FMOD_2D | FMOD_OPENONLY, &infopcm, &sound);
	if ( result != FMOD_OK )
	{
		printf("FMOD::System::createStream failed");
	}
	result = g_pFmodSystem->playSound(sound, 0, false, &channel);
	if ( result != FMOD_OK )
	{
		printf("FMOD::System::playSound failed");
	}

```

After turn result = g\_pFmodSystem-\>createStream(…) to  
result = g\_pFmodSystem-\>createSound(…)

PCMCALLBACK is not invoked anymore.

---

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [December 30, 2013, 1:33am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/5 "2013-12-30T01:33:50Z")

</div>

And The audio data parsed by libwebm is still ogg data,not decoded.  
thanks in advance

---

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [December 30, 2013, 6:58am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/6 "2013-12-30T06:58:08Z")

</div>

I have a look at user\_created\_sound example. Looks like FMOD\_SOUND\_PCMREADCALLBACK can achieve what I want.  
But I have two questions here.  
I read a ogg file into memory and want to use PCMREADCALLBACK to play it.I do this just want to learn how to use PCMREADCALLBACK.  
It can be played in FMOD\_OPENMEMORY mode with nothing wrong.  
But there is only noise in FMOD\_OPENUSER mode.

```auto
//read the file into memory
BYTE* bufferpcm = 0;
unsigned int havereadpcm = 0;
	FILE* filepcm = NULL;
	fopen_s( &filepcm, "20_cairo.ogg", "rb" );
	fseek( filepcm, 0, SEEK_END );
	long lenpcm = ftell( filepcm );
	fseek( filepcm, 0, SEEK_SET );
	bufferpcm = (BYTE*)malloc( lenpcm );
	fread( bufferpcm, 1, lenpcm, filepcm );
	fclose( filepcm );

	FMOD_CREATESOUNDEXINFO infopcm;
	memset(&infopcm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
	infopcm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
	infopcm.numchannels = 2;
	infopcm.defaultfrequency = 44100;
	infopcm.decodebuffersize = 44100;
	infopcm.length = (unsigned int)lenpcm;
	infopcm.format = FMOD_SOUND_FORMAT_PCM16;
	infopcm.pcmreadcallback = pcmreadcallback;
	infopcm.pcmsetposcallback = pcmsetposcallback;
	infopcm.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS;

	FMOD::Sound* pPCMSound = NULL;
	FMOD::Channel* pPCMChannel = NULL;
	FMOD_RESULT result;
	result = m_pFmodSystem->createSound(0, FMOD_OPENUSER|FMOD_CREATESTREAM, &infopcm, &pPCMSound);
	if ( FMOD_OK == result )
	{		
		result = m_pFmodSystem->playSound(pPCMSound, 0, false, &pPCMChannel);
		if (result != FMOD_OK)
		{
			return -1;
		}
	}

//PCMREADCALLBACK
FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND* sound, void* data, unsigned int datalen)
{
	memcpy(data, (bufferpcm + havereadpcm), datalen);
	havereadpcm += datalen;
	return FMOD_OK;
}

FMOD_RESULT F_CALLBACK pcmsetposcallback(FMOD_SOUND* sound, int subsound, unsigned int position, FMOD_TIMEUNIT posttype)
{
	return FMOD_OK;
}
```

I don’t understand where’s wrong.

And the other qustion, I notice that the first param of createSound is 0 in FMOD\_OPENUSER.  
But sometimes it play more than one video at the same time in our game.  
what should I do?

---

<div class="post-metadata">

**Author:** ![gdkid1412](https://avatars.discourse-cdn.com/v4/letter/g/898d66/32.png) [@gdkid1412](https://qa.fmod.com/u/gdkid1412)\
**Post date:** [December 31, 2013, 2:14am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/7 "2013-12-31T02:14:00Z")

</div>

I have a look at manaualdecode example in fmodex sdk.(Just a suggestion, please supplement examples in fmod api sdk if you have time.Newbie like me which never use fmodex before don’t even know there are so many examples)  
My understanding is I can’t pass encoded data to PCMREADCALLBACK, data come from Sound::readData have been decoded by fmod.So my previous code is wrong.  
But libwebm parse the video file piece by piece so I can’t get the whole audio file at the beginning.  
Because fmod can decode a ogg file and play it, I think I do not must use libvorbis to decode the data then pass it to PCMREADCALLBACK.  
But how to do?  
I believe that someone here must have this kind of experience.  
Any advice is appreciated.

---

<div class="post-metadata">

**Author:** ![nick1](https://avatars.discourse-cdn.com/v4/letter/n/47e85d/32.png) [@nick1](https://qa.fmod.com/u/nick1)\
**Post date:** [January 8, 2014, 12:06am UTC](https://qa.fmod.com/t/if-fmod-can-play-the-audio-in-a-video-file/11252/8 "2014-01-08T00:06:32Z")

</div>

WebM does not contain ogg data, it contains vorbis data. Ogg is a container format, vorbis is an audio codec. FMOD cannot decode raw vorbis data, it can only decode it from within a container such as ogg or fsb (our own container format).

If you use libvorbis to decode vorbis to PCM you can feed it to FMOD piece-wise using the PCMREADCALLBACK.
