# Trouble creating and using a secondary sound buffer...

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

## Recommended Posts

I'm trying to create a sound buffer so as to play a sound using DirectSound. The problem seems to be that I fail on the Buffer creation. As far as I can tell, everything is in order, so perhaps I need a fresh set of eyes to looks a this code. Here is the source for the creation and loading of a sound buffer:
int loadSound(IDirectSound *lpds, SNDFILE *sndfile, unsigned long flags)
{
DSBUFFERDESC dsbd;

CLEAR(dsbd);
dsbd.dwSize = sizeof(DSBUFFERDESC);
if(flags != 0)
dsbd.dwFlags = flags;
else
dsbd.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE;
dsbd.dwBufferBytes = sndfile->size;
dsbd.lpwfxFormat = &sndfile->wfrmt;

if(FAILED(lpds->CreateSoundBuffer(&dsbd,&buffer,NULL))) /*!!!FAILED!!!*/
return 0;

unsigned char *audio_ptr1, *audio_ptr2;
unsigned long audio_length1, audio_length2;

if(FAILED(buffer->Lock(0,sndfile->size,(void **)&audio_ptr1,&audio_length1,(void **)&audio_ptr2,&audio_length2,DSBLOCK_ENTIREBUFFER)))
return 0;

memcpy(audio_ptr1,sndfile->buffer,audio_length1);
memcpy(audio_ptr2,sndfile->buffer+audio_length1,audio_length2);

if(FAILED(buffer->Unlock(audio_ptr1,audio_length1,audio_ptr2, audio_length2)))
return 0;

return 1;
}


And, for the curious, my definition of SNDFILE:
typedef struct{
WAVEFORMATEX wfrmt;
unsigned long size;
unsigned char *buffer;
}SNDFILE;


EDIT: Just in case you are wondering, buffer is a global... EDIT2: The HRESULT returned by the create method is E_INVALIDARG. I just can't tell which one... [Edited by - TheWanderer on June 21, 2005 10:44:06 AM]

##### Share on other sites
Can't tell just from looking at the code (don't use DirectSound much), but perhaps if you got the error string it would give you, and possibly all of us, a better idea of why the creation of your sound buffer is failing (if it is at all).

Then use the DXGetErrorString9(HRESULT), where HRESULT is the return value of CreateSoundBuffer() to grab the reason it's failing.

-Jeff

##### Share on other sites
I JUST put it up there as you where typing :D

It's E_INVALIDARG...

##### Share on other sites
A problem I see is in the flags you are setting for your DSBUFFERDESC structure.

According to MSDN, DSBCAPS_CTRLFX and DSBCAPS_STATIC cannot be combined.

Shown Here

Also, it says that DSBCAPS_LOCSOFTWARE would take precidence over the DSBCAPS_STATIC flag anyway, so it doesn't make sense for the STATIC flag to even be assigned. Try taking that flag out and see if it works.

Other than that, I don't see any problems as long as your buffer variable is properly initialized.

##### Share on other sites
Bingo! That was indeed it. :D

Thanks for the help, GodlyGamr. Now I just have to figure out why it does not play :(. All I get are two bleeps... (and no, the file does not consist of two bleeps :P).

Thanks again :)

##### Share on other sites
I might as well, ask here, as all of the code is already pasted there....

I am now able to create the buffer, but when I play it, I simply hear a light tap on the speakers when it starts playing the sound and one when it stops and that is it. The progam seems to work ok, since it lasts for as long as it should... I just can't hear anything (and I did setVolume(0)).

Any suggestions on what THAT might be?

Here is the calling code:

 SNDFILE *gunshot; //gunshot = readWav("Gunshot.wav"); gunshot = readWav("Missile.wav"); LPDIRECTSOUND lpds; if(FAILED(DirectSoundCreate(NULL,&lpds,NULL)))  return (0); if(FAILED(lpds->SetCooperativeLevel(main_hwnd,DSSCL_NORMAL)))  return (0);  { AudioBuffer sound; //Audio Buffer is a class defined to manage buffers if(!sound.loadSound(lpds,gunshot))  return 0; if(!sound.playSound())  return 0;   while(sound.getStatus()==DSBSTATUS_PLAYING); }

This might be useful as well:

SNDFILE *readWav(char *file_name){ FILE *fp = NULL;  fp = fopen(file_name,"r"); if (!fp) //Make sure the file was found  return NULL; unsigned char id[4]; //four bytes to hold identifiers ('RIFF','WAVE','fmt ','data'); unsigned long size; //32 bit value to hold file size unsigned long format_length, data_size;//our 32 bit values fread(id, sizeof(unsigned char), 4, fp); //read in first four bytes if (strncmp((const char *)id, "RIFF",4))  return NULL;  fread(&size, sizeof(unsigned long), 1, fp); //read in 32bit size value fread(id, sizeof(unsigned char), 4, fp); //read in 4 byte string if (strncmp((const char *)id,"WAVE",4))  return NULL; fread(id, sizeof(unsigned char), 4, fp); //read in 4 bytes "fmt ";  if(strncmp((const char *)id, "fmt ",4))  return NULL; SNDFILE *tmp = (SNDFILE *) malloc(sizeof(SNDFILE)); fread(&format_length, sizeof(unsigned long),1,fp); //Should be 16 fread(&tmp->wfrmt.wFormatTag, sizeof(short), 1, fp);//Should always be WAVE_FORMAT_PCM fread(&tmp->wfrmt.nChannels, sizeof(short),1,fp); //1 mono, 2 stereo fread(&tmp->wfrmt.nSamplesPerSec, sizeof(unsigned long), 1, fp); //like 44100, 22050, etc... fread(&tmp->wfrmt.nAvgBytesPerSec, sizeof(unsigned long), 1, fp); //Average Bytes per second fread(&tmp->wfrmt.nBlockAlign, sizeof(short), 1, fp); //nChannels * BytesPerSample fread(&tmp->wfrmt.wBitsPerSample, sizeof(short), 1, fp); //8 bit or 16 bit file? tmp->wfrmt.cbSize = 0; fread(id, sizeof(unsigned char), 4, fp); //read in 'data' if(strncmp((const char *)id, "data",4)) {  free(tmp);  return NULL; } fread(&data_size, sizeof(unsigned long), 1, fp); //how many bytes of sound data do we have tmp->buffer = (unsigned char *) malloc (sizeof(unsigned char) * data_size); //set aside sound buffer space fread(tmp->buffer, sizeof(unsigned char), data_size, fp); //read in our whole sound data chunk tmp->size = data_size; return tmp;}

[Edited by - TheWanderer on June 21, 2005 11:43:37 AM]

##### Share on other sites
Small update...

If I fill out the sound buffer with random data, I get white noise. Perhaps the file information is not getting read in correctly? I know the file is ok, since I can hear is on Media Player, so what could it be?

As to how I filled up my buffer, I simply plugged in the following lines:

for(int i=0; i<(int)data_size; i++)
tmp->buffer = (unsigned char) rand()%256;

##### Share on other sites
In ths hopes that someone might still see this, here is what I've done so far...

I've created a text file to which I am re-writing the sound file which I've just read in. As far as I can tell, only the first few bytes are getting written to the file. Everything else seems to be blank. For some reason, my buffer is not getting the information from the fread(). This is how fread is getting used:

Where:
- buffer is a BYTE* with sizeof(BYTE)*size allocated space
- sizeof(BYTE) I'm guessing is 1
- size is 27495
- fp is (of course) the file pointer.

Is there some limit to the amount of data that can be read by fread perhaps?

EDIT: I went INTO fread and found that even though the numbers are as I have shown them above, it is only reading 6 bytes into my buffer (which are exactly the same six which I see when I open notepad). This happens when it requests another read from the disk. It resturns as having read nothing. Yet I KNOW that the file does not end there (I've opened up the sound file in notepad as well; Gives you an idea of what is in there). So what gives? :(

[Edited by - TheWanderer on June 22, 2005 9:42:23 AM]

##### Share on other sites
It definitely isn't due to a limit in the capacity of fread, there is no way it would stop after only 6 bytes (This isn't based on personal experience, but the fread example on MSDN reads in 25 chars). I don't know if you've checked out this tutorial, but do what I do and compare your code to it.

Something else that may help all of us here with your problem are these functions:

ferror and feof

Test to make sure that you aren't actually getting to the end of the file for some reason. I think at this point we should hope that ferror() does return something useful.

Otherwise, try making your buffer a static array of 27495 bytes. I'm not sure if this will accomplish anything, but I guess at this point anything is worth a shot, right?

##### Share on other sites
I found out what the error was! (well, actually some one else here told me what it was :P).

If you notice, I am opening the file with the "r" access specifier. It seems that this default into reading the file in text mode, which counts new lines and the like as the EOF. By adding a b (i.e. "rb"), it changes that default to binary (which frankly should be the damn default in the first place >:( ). Anyways, this fixed the problem. Since when you open up a sound file, some of it's tones translate into "\n", which made the computer stop reading.

I do thank you for the help, GodlyGamr :)

• 10
• 17
• 9
• 14
• 41
• ### Forum Statistics

• Total Topics
631067
• Total Posts
2997735
×