• Advertisement
Sign in to follow this  

CreateSoundBuffer fails... odd bug - SOLVED

This topic is 4039 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

My sound routines all work fine except CreateSoundBuffer starts failing after a certain condition. When I create a sound I pass the number of buffers (channels) I require for that particular sound. When this is <= 10 (magic number???) all goes well. However, if I require more than 10... the next call to CreateSoundBuffer fails with E_FAIL. The first channel is created with CreateSoundBuffer while all other channels are created with the DuplicateSoundBuffer. Is there a way to get more detailed error codes back as E_FAIL is not too helpful.

BOOL CBuffer::CreateSecondarySoundBuffer(DWORD channels, DWORD size, DWORD samplerate, DWORD bitspersample, DWORD flags, DWORD buffers, BOOL p3d)
{
  HRESULT hr;

  if ((p3d && channels != 1) || buffers > 64 || channels > 2 || (bitspersample != 8 && bitspersample != 16 && bitspersample != 24 && bitspersample != 32))
  {
    Unload();
    return FALSE;
  }

 if (!p3d)
 {
   flags = flags & (~DSBCAPS_CTRL3D); // only mono can have 3d control
 }

 ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
 wfx.wFormatTag      = WAVE_FORMAT_PCM;
 wfx.nChannels       = (WORD)channels;
 wfx.nSamplesPerSec  = samplerate;
 wfx.wBitsPerSample  = (WORD)bitspersample;
 wfx.nBlockAlign     = (WORD)(wfx.wBitsPerSample / 8 * wfx.nChannels);
 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * (DWORD)wfx.nBlockAlign;

 ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
 dsbd.dwSize          = sizeof(DSBUFFERDESC);
 dsbd.dwFlags         = flags;
 dsbd.dwBufferBytes   = size;
 dsbd.guid3DAlgorithm = p3d ? DS3DALG_HRTF_FULL : GUID_NULL;
 dsbd.lpwfxFormat     = &wfx;

 m_channels = (CChannel *)malloc(sizeof(CChannel) * buffers);

 if (!m_channels)
 {
   Unload();
   return FALSE;
 }

 ZeroMemory(m_channels, sizeof(CChannel) * buffers);

 hr = g_pDS->CreateSoundBuffer(&dsbd, &m_channels[0].m_buffer, NULL);

 if (FAILED(hr))
 {   
   Unload();
   return FALSE;
 }

 
 m_channels[0].m_parent = this;
 
 m_p3d     = p3d;
 m_buffers = 1;

 if (p3d)
 {
   if (FAILED(m_channels[0].m_buffer->QueryInterface(IID_IDirectSound3DBuffer, (void **)&m_channels[0].m_buffer3d)))
   {
     Unload();
     return FALSE;
   }
 }

 for (DWORD i = 1; i < buffers; i++)
 {
    if (FAILED(g_pDS->DuplicateSoundBuffer(m_channels[0].m_buffer, &m_channels.m_buffer)))
    {
      Unload();
      return FALSE;
    }
    else
    {
      if (p3d)
      {
        if (FAILED(m_channels.m_buffer->QueryInterface(IID_IDirectSound3DBuffer, (void **)&m_channels.m_buffer3d)))
        {
          Unload();
          return FALSE;
        }
      }
    }
    m_channels.m_parent = this;
    m_buffers++;
 }

 CListElement *el = new CListElement();
 el->SetData(this);
 g_buffers.Add(el);

 return TRUE;
}
[Edited by - whitde on January 31, 2007 8:29:00 PM]

Share this post


Link to post
Share on other sites
Advertisement
Found this in the dsound.h header.


// An undetermined error occurred inside the DirectSound subsystem
#define DSERR_GENERIC E_FAIL


Seems I'll be on my own tracking this down. Been looking at anything that may upset the code but so far... no luck.

Share this post


Link to post
Share on other sites
The debug runtimes should give you some more helpful output. What SDK version are you using (E.g. August 2006)?

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
The debug runtimes should give you some more helpful output. What SDK version are you using (E.g. August 2006)?


DX8.1

My sound routines are jumbled a bit inside my engine code so I'm going to make the sound into a tight and specific DLL. It is possible other code is causing this undesired effect.

Share this post


Link to post
Share on other sites
Quote:
Original post by whitde
Quote:
Original post by Evil Steve
The debug runtimes should give you some more helpful output. What SDK version are you using (E.g. August 2006)?


DX8.1

My sound routines are jumbled a bit inside my engine code so I'm going to make the sound into a tight and specific DLL. It is possible other code is causing this undesired effect.
If you install the latest DirectX 9 SDK, you should get debug output in the debug window whenever a function fails.

At least I think you do, it's been ages since I used DX8 stuff.

Share this post


Link to post
Share on other sites
Quote:
Original post by whitde
When I create a sound I pass the number of buffers (channels) I require for that particular sound. When this is <= 10 (magic number???) all goes well.

Call me stupid, but aren't the number of buffers and the number of channels two completely different things?

As I see it, your problem isn't so much with DirectSound as with the Windows Audio HAL: WAVEFORMATEX is a Windows structure that DirectSound passes straight to the kernel. I imagine the error is just being forwarded to you.

As I understand it, the 'channels' element pertains to the number of channels in the audio stream, in the sense understood by audio technicians. That is,

channels == 1 <=> mono
channels == 2 <=> stereo
channels == 6 <=> 5.1
channels == 8 <=> 7.1

If this is the case, then it's no wonder that channels > 10 causes problems. Am I wrong?

Admiral

Share this post


Link to post
Share on other sites
I was looking at that... my terminology/variable names are a bit confusing.

the "channels" variable is usually 1 or 2.

However a variable called "buffers" tell the function how many duplicates we need... if any.

Spent a long day yesterday and got the entire sound engine into it's own DLL with minimal baggage from anywhere else to interfere. While doing it I did a lot more checking however still get the same problem.

The next step will be to write a small console app and link with the DLL and see what happens.

Share this post


Link to post
Share on other sites
I had a similar problem recently, i found out that i wasnt initialising the COM by calling CoInitialize(NULL) once BEFORE creating all the sound buffers (and everything else).

Share this post


Link to post
Share on other sites
Solved....

When I was creating the buffer I was ORing DSBSTATUS_LOOPING if it was music (flag passed into function had a wrong bit set).

This flag is in the ->Play(..) method and was causing an error after certain conditions.

Was hell tracking this down... but on the good side...the code checks all return values now (as it should have anyway) and is now more modular and bug free.


#define DSBCAPS_PRIMARYBUFFER 0x00000001
#define DSBCAPS_STATIC 0x00000002
#define DSBCAPS_LOCHARDWARE 0x00000004 <--- Was setting this :(
#define DSBCAPS_LOCSOFTWARE 0x00000008
#define DSBCAPS_CTRL3D 0x00000010
#define DSBCAPS_CTRLFREQUENCY 0x00000020
#define DSBCAPS_CTRLPAN 0x00000040
#define DSBCAPS_CTRLVOLUME 0x00000080
#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
#define DSBCAPS_CTRLFX 0x00000200
#define DSBCAPS_STICKYFOCUS 0x00004000
#define DSBCAPS_GLOBALFOCUS 0x00008000
#define DSBCAPS_GETCURRENTPOSITION2 0x00010000
#define DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000
#define DSBCAPS_LOCDEFER 0x00040000

#define DSBSTATUS_LOOPING 0x00000004


[Edited by - whitde on January 31, 2007 8:28:34 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement