Jump to content

  • Log In with Google      Sign In   
  • Create Account


Sound pops and clicks - XAudio2


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
9 replies to this topic

#1 Prads   Members   -  Reputation: 139

Like
0Likes
Like

Posted 16 September 2011 - 09:55 PM

I have to play different quadrangular waves of 12.5%, 25%, 50% and 75% duty cycle to create melodies. So far I have been able to get melodies right but one problem exist and that is when I try to start and stop the sound, it gives me nasty pops and clicks sound. The program has to start and stop the sound quite a lot so there is lot of pops and clicks. One way I have found to get rids of these pops and clicks is by instead of starting and stopping the sound, I just start it once and then change the volume, if I am starting the sound I change the volume to 1 and if I am stopping the sound I change the volume to 0. This method works but I am not sure if this is a good or the right method to stop sound. So, can anyone tell me how I can get rid of pops and clicks when I am starting and stopping sound?

Thanks!!!



My first 3D game: Click Here

Sponsor:

#2 Geiger   Members   -  Reputation: 103

Like
0Likes
Like

Posted 17 September 2011 - 03:41 AM

I'm no expert on XAudio2 but one option you could possibly try is to call IXAudio2SourceVoice::FlushSourceBuffers() before you ultimately stop playing your sound. What this does is it discards all of the queued audio buffers for that source voice and only maintains the currently playing buffer, which (depending on your implementation) could only be a second or so of audio.


One way I have found to get rids of these pops and clicks is by instead of starting and stopping the sound, I just start it once and then change the volume, if I am starting the sound I change the volume to 1 and if I am stopping the sound I change the volume to 0.


If this works for you, you can still Start() and Stop() your source voice's normally, but just add a call to SetVolume(1.0f) and SetVolume(0.0f) before you actually call Start() and Stop() respectively. I don't believe there is that much overhead with SetVolume() that it would cause much of a problem, but again I'm no expert.

However I think it would be best if you posted some of your code for everyone to look at. The most important things would be your start, stop, initialization and update functions

#3 Prads   Members   -  Reputation: 139

Like
0Likes
Like

Posted 17 September 2011 - 06:18 AM

Thank you for your reply. Flushing off the buffer is not a bad idea but it wouldn't work for me because the source voice only has one buffer that is looped again and again. Also setting the volume to zero and starting and stopping didn't work.

Here are some codes, first this is how I have setup my WAVEFORMATEX:

	WAVEFORMATEX wFormat;

	wFormat.wFormatTag = WAVE_FORMAT_PCM;
	wFormat.wBitsPerSample = 8;
	wFormat.nBlockAlign = 1;
	wFormat.nAvgBytesPerSec = 8000;
	wFormat.nSamplesPerSec = 8000;
	wFormat.nChannels = 1;
	wFormat.cbSize = 0;

	ZeroMemory(&xABufferInfo, sizeof(xABufferInfo));
	xABufferInfo.AudioBytes = 8;
	xABufferInfo.pAudioData = xABuffer;
	xABufferInfo.LoopCount = XAUDIO2_LOOP_INFINITE;

	if (xASourceChTwo->SubmitSourceBuffer(&xABufferInfo) != S_OK) return false;

So the sample depth is 8 bits and sample rate is 8 kHz.

Now I have 5 buffers, 1st buffer that source voice reads and loops again and again and 4 others are wave patterns of different duty cycle. All of them are 8 bytes long:

	unsigned char xABuffer[8], wDTwelve[8], wDTwenty[8], wDFifty[8], wDSeventyFive[8];

	//12.5% duty cycle
	wDTwelve[0] = 0;	wDTwelve[1] = 64;	wDTwelve[2] = 64;	wDTwelve[3] = 64;	
	wDTwelve[4] = 64;	wDTwelve[5] = 64;	wDTwelve[6] = 64;	wDTwelve[7] = 64;
	
	//25% duty cycle
	wDTwentyFive[0] = 0;	wDTwentyFive[1] = 0;	wDTwentyFive[2] = 64;	wDTwentyFive[3] = 64;
	wDTwentyFive[4] = 64;	wDTwentyFive[5] = 64;	wDTwentyFive[6] = 64;	wDTwentyFive[7] = 64;
	
	//50% duty cycle
	wDFifty[0] = 0;		wDFifty[1] = 0;		wDFifty[2] = 0;		wDFifty[3] = 0;
	wDFifty[4] = 64;	wDFifty[5] = 64;	wDFifty[6] = 64;	wDFifty[7] = 64;

	//75% duty cycle
	wDSeventyFive[0] = 0;	wDSeventyFive[1] = 0;	wDSeventyFive[2] = 0;	wDSeventyFive[3] = 0;
	wDSeventyFive[4] = 0;	wDSeventyFive[5] = 0;	wDSeventyFive[6] = 64;	wDSeventyFive[7] = 64;

	//Default wave duty cycle is 50%
	memcpy(xABuffer, wDFifty, 8);

Now before playing and updating the sound, program checks duty cycle flag and just copies the data to xABuffer like this:

	switch (dutyFlag) {
		case DUTY_TWELVE:
			memcpy(xABuffer, wDTwelve, 8;
			break;
		case DUTY_TWENTYFIVE:
			memcpy(xABuffer, wDTwentyFive, 8);
			break;
		case DUTY_FIFTY:
			memcpy(xABuffer, wDFifty, 8);
			break;
		case DUTY_SEVENTYFIVE:
			memcpy(xABuffer, wDSeventyFive, 8);
	}

Then some flags are checked, frequency is set and the sound is played like this:

	if (!channelTwo) {
		channelTwo = true;
		xASourceChTwo->Start()
	}

And at last when sound is suppose to stop, it stops like this:

	if (channelTwo) {
		channelTwo = false;
		xASourceChTwo->Stop();
	}

My first 3D game: Click Here

#4 Adam_42   Crossbones+   -  Reputation: 2457

Like
0Likes
Like

Posted 17 September 2011 - 06:53 AM

When starting and stopping the sound, you should fade it in and out over a few milliseconds. Clicks and pops are caused by very sudden changes in amplitude.

#5 aregee   Members   -  Reputation: 1016

Like
0Likes
Like

Posted 17 September 2011 - 07:22 AM

When starting and stopping the sound, you should fade it in and out over a few milliseconds. Clicks and pops are caused by very sudden changes in amplitude.


This. And you can do a simple test:

Play a 0% duty cycle with full volume. Now you should not hear any clicks and pops at all when you start and stop the audio. If you do, the problem lies elsewhere.

#6 Prads   Members   -  Reputation: 139

Like
0Likes
Like

Posted 17 September 2011 - 07:45 AM

Yeah sudden change of amplitude seems to be the cause. I want to ask something else, performance wise, if sound has to stop and start many times (once a second an average) is it better to leave the sound open with volume down when not playing or is it better to completely stop the sound and restart the sound.

EDIT:
@aregee: Uh oh, I just did that test with 0% duty cycle and I still got clicks and pops. :(
My first 3D game: Click Here

#7 aregee   Members   -  Reputation: 1016

Like
2Likes
Like

Posted 17 September 2011 - 02:57 PM

@aregee: Uh oh, I just did that test with 0% duty cycle and I still got clicks and pops. :(

I have read about XAudio2 and its capabilities. Unless XAudio2 is broken, I can not see that it should behave this way and I don't think XAudio2 is broken like that.

I have one suggestion to what may be the fault. You are probably feeding signed data where unsigned is expected or the oposite. This would create cracks and pops where there should be silence when you start and stop the sample.

So if you are feeding all zeroes when each sample is 16 bit, you may actually be feeding DC at max amplitude instead of DC at 0 amplitude. Try the 0% duty cycle again, but this time use the value in the middle of an unsigned word or an unsigned byte depending on 8 bits or 16 bits sample size. 32768 dec (8000 hex) for 16 bits and 128 dec (80 hex) for 8 bits.

#8 Prads   Members   -  Reputation: 139

Like
0Likes
Like

Posted 17 September 2011 - 09:14 PM

Thank you very much. You were right, 0 amplitude is 128 for 8 bits. Cracks are far less frequent now in my program. But can you please answer my this question:

performance wise, if sound has to stop and start many times (once a second an average) is it better to leave the sound open with volume down when not playing or is it better to completely stop the sound and restart the sound.

Thank you...
My first 3D game: Click Here

#9 aregee   Members   -  Reputation: 1016

Like
1Likes
Like

Posted 18 September 2011 - 12:33 PM

Thank you very much. You were right, 0 amplitude is 128 for 8 bits. Cracks are far less frequent now in my program. But can you please answer my this question:

performance wise, if sound has to stop and start many times (once a second an average) is it better to leave the sound open with volume down when not playing or is it better to completely stop the sound and restart the sound.

Thank you...

Glad that it helped! :)

Regarding your question, I am not sure really. It depends on a lot of factors. My initial thought is that this is what XAudio2 is made to do. Starting, stopping and mixing sounds through a convenient interface. I believe there is very little overhead in starting and stopping sounds since you are not deallocating or reallocating resources for each time you do. That would probably be a bit of a overhead and not a good idea anyway.

I suggest you just postpone any premature optimizations till you actually stumble upon a problem regarding performance since any optimization I can think of is a lot of work that is better spent on the progress of your work. :)

#10 Prads   Members   -  Reputation: 139

Like
0Likes
Like

Posted 18 September 2011 - 10:20 PM

You're probably right. I think I should focus more on getting it done than optimizing it. Thanks!
My first 3D game: Click Here




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