Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


.wav Parser Making Popping Sounds


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 blueshogun96   Crossbones+   -  Reputation: 1106

Like
0Likes
Like

Posted 13 March 2013 - 08:44 PM

I have this .wav parsing code that I've been using for quite some time, but there are some .wav files that will have a popping sound after it finishes playing.  I assume that it has something to do with my code since this doesn't happen when other .wav playing programs play the sound.  It shouldn't really matter, but I'm using OpenAL.

 

My code to load .wav files is in a single function.

 

ALuint wavstatic_open( char* filename )
{
	FILE* file = NULL;
	char* buffer = NULL;
	ALuint channels;
	ALuint frequency;
	ALuint format;
	ALuint bits;
	ALuint albuffer;
	long filesize = 0;
	int ret;

	/* Does the wav file exist? */
	file = fopen( filename, "rb" );
	if( !file )
		return 0;

	/* Get the file size */
	fseek( file, 0, SEEK_END );
	filesize = ftell(file);
	fseek( file, 0, SEEK_SET );

	/* Create buffers and sources */
	alGenBuffers( 1, &albuffer );
	if( alGetError() != AL_NO_ERROR )
	{
		fclose(file);
		free(buffer);
		alDeleteBuffers( 1, &albuffer );
		return 0;
	}

	/* Allocate this buffer to read bytes from as we go. */
	/* Should check for the strings "RIFF" and "WAVE" in the header, but I don't feel like
	   it at the moment, so... */
	buffer = malloc( filesize );
	fread( buffer, 1, 12, file );

	/* Check the wav file chunk header for the format information. If it's not there, forget it */
	fread( buffer, 1, 8, file );
	if( buffer[0] != 'f' || buffer[1] != 'm' || buffer[2] != 't' || buffer[3] != ' ' )
	{
		fclose(file);
		free(buffer);
		alDeleteBuffers( 1, &albuffer );
		return 0;
	}

	/* Read the wav format type. 1 == PCM.  If it's not, then we either
	   exit, or have to decode the format ourselves */
	fread( buffer, 1, 2, file );
	if( buffer[1] != 0 || buffer[0] != 1 )
	{
		fclose(file);
		free(buffer);
		alDeleteBuffers( 1, &albuffer );
		return 0;
	}

	/* Get the channel count */
	fread( buffer, 1, 2, file );
	channels = buffer[1]<<8;
	channels |= buffer[0];

	/* Get the sample frequency */
	fread( buffer, 1, 4, file );
	frequency  = buffer[3]<<24;
    frequency |= buffer[2]<<16;
    frequency |= buffer[1]<<8;
    frequency |= buffer[0];

	/* Ignore block size and bytes per second */
	fread( buffer, 1, 6, file );

	/* Get the bit depth */
	fread( buffer, 1, 2, file );
	bits = buffer[1]<<8;
	bits |= buffer[0];

	if( bits == 8 )
	{
		if( channels == 1 )
			format = AL_FORMAT_MONO8;
		else if( channels == 2 )
			format = AL_FORMAT_STEREO8;
	}
	else if( bits == 16 )
	{
		if( channels == 1 )
			format = AL_FORMAT_MONO16;
		else if( channels == 2 )
			format = AL_FORMAT_STEREO16;
	}

	/* Read the data chunk which will hold the decoded sample data */
	fread( buffer, 1, 8, file );
	if( buffer[0] != 'd' || buffer[1] != 'a' || buffer[2] != 't' || buffer[3] != 'a' )
	{
		fclose(file);
		free(buffer);
		alDeleteBuffers( 1, &albuffer );
		return 0;
	}

	/* Now read in the data section of this wav file */
	ret = fread( buffer, 1, filesize, file );
	alBufferData( albuffer, format, buffer, ret, frequency );
	if( alGetError() != AL_NO_ERROR )
	{
		fclose(file);
		free(buffer);
		alDeleteBuffers( 1, &albuffer );
		return 0;
	}

	/* That's all */
	fclose(file);
	free(buffer);

	return albuffer;
}

 

 

Not sure what it is.  The pop sound at the end only happens with a few .wav files.  The rest sound and work okay.  Any ideas?  Thanks.

 

Shogun.


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png

 

"Yo mama so fat, she can't be frustum culled." - yoshi_lol


Sponsor:

#2 Endurion   Crossbones+   -  Reputation: 3693

Like
0Likes
Like

Posted 13 March 2013 - 11:22 PM

Pop sounds usually happen when there's a bigger step in the sound curve. Look at the end of the .wav in an audio editor. Ideally the sound curve is zero at the end to avoid popping.

Some audio players default to fading out when playing (WinAMP)


Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#3 BGB   Crossbones+   -  Reputation: 1554

Like
2Likes
Like

Posted 14 March 2013 - 01:08 AM

some audio programs put some data after the "data" lump (note: lump==chunk).
(a common example here are lumps that indicate the audio program used and/or contain data similar to that found in an ID3 tag).

the reader code appears as if it will just read all the way to the end of the file, so if anything follows the main data lump, it may result in noise and/or pops, due to this data being treated as audio.

better could be taking the lump-size into account (for the "data" lump), then use this to know how many audio samples are present (rather than how much data was read).


secondary notes:
not all WAV files will have exactly the same length for the "fmt " lump (mostly N/A for PCM WAV files);
theoretically, other lumps may appear between "fmt " and "data" lumps (not actually ran into this AFAICT);
thoeretically, audio files may contain a 'LIST'/'wavl' lump instead of a single big 'data' lump (not seen AFAICT);
RIFF does this odd thing of padding lumps up to even (multiple of 2) sizes (N/A in this case);
...

the most likely scenario is here being data following 'data', because most of the other scenarios would likely result in the decoder rejecting the file (by not seeing 'data' where it is expected).


ADD, maybe try something like (trivial edit):
/* decode the length for "data" (32 bit little-endian DWORD) */
len = buffer[4] | (buffer[5]<<8) | (buffer[6]<<16) | (buffer[7]<<24);

/* Now read in the data section of this wav file */
ret = fread( buffer, 1, len, file );

Edited by cr88192, 14 March 2013 - 01:20 AM.


#4 blueshogun96   Crossbones+   -  Reputation: 1106

Like
0Likes
Like

Posted 14 March 2013 - 02:13 AM

This makes sense.  It would be best not to expect every chunk to come in a certain order.  Also, I'm pretty sure that it's another chunk after the actual data chunk.

 

So far, I've only had one instance where the data chunk wasn't where I expected it to be.


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png

 

"Yo mama so fat, she can't be frustum culled." - yoshi_lol





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS