Issues with XAudio2 & mono Ogg Vorbis

Started by
6 comments, last by Soul Reaver 11 years, 6 months ago
Hi,
some time ago I have written a C++ class, which utilizes XAudio2 to play *.wav and *.ogg files. Recently I wanted to debug it and found out that it cannot play single channel Ogg Vorbis files, when XAUDIO_DEBUG_ENGINE was specified to create the XAudio2-Interface. This message is shown in the output window:


OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc (null)izeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}
[/quote]

When I saw this, I tried to play a stereo Ogg Vorbis and it worked. So I guess something is wrong with my WAVEFORMATEX but I still don't know why this only happens, when I use the debug runtime of XAudio2. I have got the code for loading Ogg Vorbis from this topic:

[source lang="cpp"]
vorbis_info* vi = ov_info(&m_vorbisFile, -1);
m_format.cbSize = sizeof(WAVEFORMATEX);
m_format.nChannels = vi->channels;
m_format.wBitsPerSample = 16; // Always 2 bytes
m_format.nSamplesPerSec = vi->rate;
m_format.nAvgBytesPerSec = m_format.nSamplesPerSec * m_format.nChannels * 2;
m_format.nBlockAlign = 2 * m_format.nChannels;
m_format.wFormatTag = 1;
[/source]

I would be grateful if someone could tell what I am doing wrong.

Thanks in advance.

EDIT: Solution is in my last post. Thanks SHilbert for the help.
Advertisement

Hi,
some time ago I have written a C++ class, which utilizes XAudio2 to play *.wav and *.ogg files. Recently I wanted to debug it and found out that it cannot play single channel Ogg Vorbis files, when XAUDIO_DEBUG_ENGINE was specified to create the XAudio2-Interface. This message is shown in the output window:


OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc (null)izeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}


When I saw this, I tried to play a stereo Ogg Vorbis and it worked. So I guess something is wrong with my WAVEFORMATEX but I still don't know why this only happens, when I use the debug runtime of XAudio2. I have got the code for loading Ogg Vorbis from this topic:

[source lang="cpp"]
vorbis_info* vi = ov_info(&m_vorbisFile, -1);
m_format.cbSize = sizeof(WAVEFORMATEX);
m_format.nChannels = vi->channels;
m_format.wBitsPerSample = 16; // Always 2 bytes
m_format.nSamplesPerSec = vi->rate;
m_format.nAvgBytesPerSec = m_format.nSamplesPerSec * m_format.nChannels * 2;
m_format.nBlockAlign = 2 * m_format.nChannels;
m_format.wFormatTag = 1;
[/source]

I would be grateful if someone could tell what I am doing wrong.

Thanks in advance.
[/quote]

I was done with waves but looking at your struct, are you sure it's 16 bit audio?
Yes it's a Ogg Vorbis and I read it as a 16bit as specified by passing 2 as the "word"-parameter in


long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream);[/quote]

OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc (null)izeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

Given the position of that (null), it looks like it's meant to be:

OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc %sizeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

That is, it's checking if pSRCParameters->pvSrc is aligned to 16-bit boundaries. Perhaps a buffer you are passing in is not aligned this way -- that is, the buffer's address is not divisible by 2. That doesn't explain why it worked with stereo, because that probably requires even more strict alignment, but it might be worth checking out.

[quote name='Soul Reaver' timestamp='1305578678' post='4811624']
OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc (null)izeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

Given the position of that (null), it looks like it's meant to be:

OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc %sizeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

That is, it's checking if pSRCParameters->pvSrc is aligned to 16-bit boundaries. Perhaps a buffer you are passing in is not aligned this way -- that is, the buffer's address is not divisible by 2. That doesn't explain why it worked with stereo, because that probably requires even more strict alignment, but it might be worth checking out.
[/quote]

Okay I'm confused now.
I opened the audio file in an editor and resampled it to 16bit, which was displayed before already. Now it's played without any issues, even in debug mode.
What strikes me, is that I thought Vorbis uses a float format internally and the returned format is decided by the "word"-parameter in the Read()-functions. I would be grateful if somebody could elaborate on that.

[quote name='SHilbert' timestamp='1305690239' post='4812241']
[quote name='Soul Reaver' timestamp='1305578678' post='4811624']
OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc (null)izeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

Given the position of that (null), it looks like it's meant to be:

OAPipeline ASSERT: (UNWORD)pSRCParameters->pvSrc %sizeof(INT16) == 0, {OAPIPELINE::ResampleLinearFromInt16MonoSse2, Line 1714}

That is, it's checking if pSRCParameters->pvSrc is aligned to 16-bit boundaries. Perhaps a buffer you are passing in is not aligned this way -- that is, the buffer's address is not divisible by 2. That doesn't explain why it worked with stereo, because that probably requires even more strict alignment, but it might be worth checking out.
[/quote]

Okay I'm confused now.
I opened the audio file in an editor and resampled it to 16bit, which was displayed before already. Now it's played without any issues, even in debug mode.
What strikes me, is that I thought Vorbis uses a float format internally and the returned format is decided by the "word"-parameter in the Read()-functions. I would be grateful if somebody could elaborate on that.
[/quote]

If it's happening only some of the time, it definitely sounds like an alignment problem. Do you still have the file that caused the problem originally? I would look at the value of the pointer to the buffer you're passing into SubmitSourceBuffer (or wherever) in the debugger, or print it to the console. If it's odd when it fails, and even when it works, you have an alignment problem. I'm suspecting Xaudio2 has a requirement that your data buffers are aligned to the sample size, or sample size * channel count. If you do find out this is a problem, you should look at how you're getting the pointer to the buffer to give Xaudio -- if you new[] or malloc the buffer yourself, it's always going to be at least 4-byte aligned on windows, so you must be giving it an address into the middle of an existing buffer.

EDIT: To be clear, when I'm talking about buffer alignment, I'm talking about the buffer pointed to by your XAUDIO2_BUFFER's pAudioData field, not the address of the XAUDIO2_BUFFER structure itself.
Oh man,
just when I was checking the pointers of the pAudioData pointers I realized that those contain only zeros. For some reason the ov_read()-function copies only zeros into the buffer while not generating any error. I really should have checked that at first. *facepalm*

Btw: The pointers are in fact odd, but it doesn't seem to bother XAudio2 in contrary to empty buffers.

Thanks for your help, I think I can fix this finally.
So,

this thread is old but I've encountered this problem again. I had to rewrite parts of my audio engine and the same exact issue appeared with mono vorbis files.
But I could fix it by aligning the data to 2 bytes. My struct to save pcm data now looks like this:
[source lang="cpp"]
struct PCM_BUFFER
{
bool submitted;
UINT size, flags;
__declspec( align(2) ) BYTE data[BUFFER_SIZE];
};
[/source]
Just wanted to share this with you in case you have the same problem.

This topic is closed to new replies.

Advertisement