DirectSound & OGG - Glitches at the end

Started by
3 comments, last by EJSainz 13 years, 7 months ago
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.
Advertisement
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.
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 ;-) .
Hi!

Glad to see another 'Barcelonian' here =)

Carlos
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!

This topic is closed to new replies.

Advertisement