Sign in to follow this  

DirectSound & OGG - Glitches at the end

This topic is 2657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everybody,

I'm looking for some help on a very strange issue I'm having with both DirectSound and Ogg files.

I have my own DirectX/C++ 2D engine which I have already used for games (http://www.spiritvg.com). It (mostly) works well on streaming Ogg audio and playing preloaded PCM Wavs.

But my new game takes a lot to load, so I'm moving from WAV to Ogg. Now I'm reading Ogg files into DSound buffers instead of doing it from PVM Wav files. The result should be the same, but I'm hearing glitches at the end of every sample.

I use the last version of LibOgg (1.2.0) and LibVorbis (1.3.1). I've also made sure that OGG files are converted using the last LibVorbis encoding (using the appropriate version of oggDropXPd for the test file). I've opened the test file with Winamp and Audacity, and works fine on both of them.

I've even tried to add some zeros at the end of the read data, but it won't help, as I inspected the buffer and found the glitch itself seems to be there. So it isn't DSound neither.

To finally make me mad, everything seems to be working fine when streaming (not preloading) audio.

I'm leaving the loading function source code here.

//--------------------------------------------------------------------
//--------------------------------------------------------------------
DWORD CSistemaSoAbstracte::LoadSoOgg(LPDIRECTSOUNDBUFFER *pSoundBuffer, char *pszFileName)
{
DWORD bufSize = -1;

CSistemaFicheros::TFichero *pFile = NULL;
char *pFileData = NULL;
bool bOk = true;

// Opening the file
if (bOk)
{
pFile = g_pFileSys->OpenFile(pszFileName, CSistemaFicheros::FL_LECTURA | CSistemaFicheros::FL_BINARIO);
if (!pFile)
{
GLOGERR(("Couldn't open file %s.", pszFileName));
bOk = false;
}
}

// Assigning file to OggVorbis_File
OggVorbis_File *pVF = NULL;

if (bOk)
{
pVF = NEW(OggVorbis_File);
bOk = pVF != NULL;
}

if (bOk)
{
ov_callbacks ovCallbacks;
ovCallbacks.read_func = read_func;
ovCallbacks.seek_func = seek_func;
ovCallbacks.close_func = close_func;
ovCallbacks.tell_func = tell_func;

if (ov_open_callbacks(pFile, pVF, NULL, 0, ovCallbacks))
{
bOk = false;
GLOGERR(("File %s is not an appropriate OGG.", pszFileName));
}
}

// Decoding file data to memory
DWORD dwSoundDataSize = 0;
vorbis_info *vi = NULL;
if (bOk)
{
vi = ov_info(pVF,-1);

// Allocating data buffer
dwSoundDataSize = (ov_pcm_total(pVF, -1) * vi->channels * 2);
pFileData = NEW (char[dwSoundDataSize]);

// Loop for decoding
int iSizeRead = -1;
int bitstream = 0;
DWORD dwBytesLeidos = 0;
while (iSizeRead != 0)
{
iSizeRead = ov_read(pVF, ((char *)&pFileData[dwBytesLeidos]), dwSoundDataSize - dwBytesLeidos, 0, 2, 1, &bitstream);
dwBytesLeidos += iSizeRead;
}
ASSERT(dwBytesLeidos == dwSoundDataSize);
}

// Creating DSound Buffer
if (bOk && (*pSoundBuffer == NULL))
{
char **ptr=ov_comment(pVF,-1)->user_comments;
while(*ptr)
{
GLOGINF(("%s\n",*ptr));
++ptr;
}

WAVEFORMATEX WaveFormat;

WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
WaveFormat.nChannels = vi->channels;
WaveFormat.nSamplesPerSec = vi->rate;
WaveFormat.nAvgBytesPerSec = vi->rate * vi->channels * 2; // 2 - 16 bits ergo 2 bytes per channel
WaveFormat.nBlockAlign = 4; // 2 * BitsPerSample / 8
WaveFormat.wBitsPerSample = 16;
WaveFormat.cbSize = 0;

//GLOGINF(("\nBitstream is %d channel, %ldHz\n", vi->channels, vi->rate));
//GLOGINF(("\nDecoded length: %ld samples\n", (long)ov_pcm_total(pVF,-1)));
//GLOGINF(("Encoded by: %s\n\n",ov_comment(pVF,-1)->vendor));

DSBUFFERDESC DescripcioBuffer;
memset(&DescripcioBuffer, 0, sizeof(DSBUFFERDESC));

DescripcioBuffer.dwSize = sizeof(DSBUFFERDESC);
DescripcioBuffer.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLVOLUME;
DescripcioBuffer.dwBufferBytes = dwSoundDataSize;
DescripcioBuffer.lpwfxFormat = &WaveFormat;

if (FAILED(m_IDirectSound->CreateSoundBuffer(&DescripcioBuffer, pSoundBuffer, NULL)))
{
GLOGERR(("No s'ha pogut crear el DSoundBuffer carregant el fitxer %s.", pszFileName));
bOk = false;
}
}

// Copying data to buffer
if (bOk)
{
LPVOID pSoundBufferDataPointer = NULL;
LPVOID pSoundBufferDataPointer2 = NULL;
DWORD dwWritableBytes = 0;
DWORD dwWritableBytes2 = 0;
if (FAILED((*pSoundBuffer)->Lock(0, 0, &pSoundBufferDataPointer, &dwWritableBytes, &pSoundBufferDataPointer2, &dwWritableBytes2, DSBLOCK_ENTIREBUFFER)))
{
GLOGERR(("Couldn't lock DSoundBuffer loading %s.", pszFileName));
bOk = false;
}
else
{
memcpy(pSoundBufferDataPointer, &pFileData[TAMANYCAPSALERA], dwSoundDataSize);

if (FAILED((*pSoundBuffer)->Unlock(pSoundBufferDataPointer, dwWritableBytes, pSoundBufferDataPointer2, dwWritableBytes2)))
{
GLOGERR(("Couldn't unlock DSoundBuffer when loading %s ... this shouldn't be happening :-P", pszFileName));
bOk = false;
}
else
{ bufSize = dwSoundDataSize; }
}
}

if (pFileData)
{ DISPOSE_ARRAY (pFileData); }

if (pFile)
{ g_pFileSys->CloseFile(pFile); }

if (pVF)
{
ov_clear(pVF);
DISPOSE(pVF);
}

return bufSize;
}





Can anyone give me some advice on this? I would really appreciate.

Thanks a lot in advance.

Share this post


Link to post
Share on other sites
What is TAMANYCAPSALERA declared as? 0?
Does dwWritableBytes == dwSoundDataSize?

Also, unrelated: You don't need to declare a OggVorbis_File on the heap with new, you can just allocate it on the stack - it's not that big.

Share this post


Link to post
Share on other sites
Hello, Steve :-) .

Quote:
Original post by Evil Steve
What is TAMANYCAPSALERA declared as? 0?


That's it! That's the whole problem about, since TAMANYCAPSALERA (which means "header size") is defined as 44. That's the problem of copy-pasting the code from the Load PCM Wav function, which uses TAMANYCAPSALERA to bypass the header of a PCM Wav file.

I should feel a bit silly about this... yep, I do. Just a bit.

I've been looking for this for over 3hrs. Thanks a lot, Steve, you've saved me ;-) .

Share this post


Link to post
Share on other sites
Hello MChiz,

glad to meet you too :-) . Have you seen my game? It takes place on Barcelona :-) . Get the demo at http://www.spiritvg.com, and tell me what do you think.

It didn't sell very well, but I'm quite proud of it. Moreover, I love Barcelona and this game is my tribute to it.

Hope to see you around!

Share this post


Link to post
Share on other sites

This topic is 2657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this