Jump to content
  • Advertisement
Sign in to follow this  
TheWanderer

Trouble creating and using a secondary sound buffer...

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

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 this post


Link to post
Share on other sites
Advertisement
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).

Include dxerr9.h in your project and link to dxerr9.lib

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

-Jeff

Share this post


Link to post
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.

EDIT: Made Clearer

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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;

instead of:

fread(tmp->buffer, sizeof(unsigned char), data_size, fp);

Share this post


Link to post
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:

fread(buffer,sizeof(BYTE),size,fp);

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 this post


Link to post
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 this post


Link to post
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 :)

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!