NO

Author Topic: Clicks and Pops with WaveOut  (Read 6534 times)

leandrojardim

  • Guest
Clicks and Pops with WaveOut
« on: May 29, 2011, 06:03:57 AM »
Hi, the first time I use the waveout api to play a streamed sound (actually a real time generated sine wave) the speaker emits a big popping sound.

I guess the problem is with Windows, because the pop only happens at the beginning of the sound, at the first use of the api and I dont know if it only happens with my sound card.

How do I can remove the pops at the beginning of the use of the waveout api? Or, do not exists any way to do it?

Thanks!

CommonTater

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #1 on: May 29, 2011, 07:53:57 AM »
It's probably the audio chip being initialized...

Does it do it if you play any other sound first?


leandrojardim

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #2 on: May 29, 2011, 05:27:10 PM »
Yes, it does. :)

CommonTater

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #3 on: May 29, 2011, 07:11:06 PM »
Hmmm... I'm not sure if this is a solution or not... but have you tried muting the volume while intializing then setting it back after?  You could try doing this manually first, using the windows mixer dialog and see what happens.




leandrojardim

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #4 on: May 29, 2011, 11:25:09 PM »
Nothing happened...

I think it should be a problem of my chipset. I have seen finished programs of other authors with very similar problems.

I hear some pops even while writting the wave to the sound card. I dont know if it is my bug or a bug of Windows. But WaveOut is not a good API for doing these things and the way it need to synchronize the writes to the sound card is error prone.

If I do not enconter a solution, I will need to use DirectSound, with its weak macro based C-API, but for now, it will suffice.
« Last Edit: May 29, 2011, 11:41:23 PM by leandrojardim »

CommonTater

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #5 on: May 30, 2011, 01:25:49 AM »
Ok... one last thought... when you begin generating the sound wave, are you starting with 0 and counting up or from max and counting down?   It may just be the initial value causing a very sharp jump in the output...

Beyond that, I'm as lost as you are. 

leandrojardim

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #6 on: May 30, 2011, 02:21:12 AM »
Thanks CommonTater for the time spend to me. :)

My program had a tiny bug that doubled the volume of the sine wave at very high speeds... And this was the cause of the "pops". Unfortunately... well I "breaked" the source code in a way that I didnt know if I could fix it quickly, so I will do it, again... :(

Hopefully I did a backup of the "important" parts. ;)

CommonTater

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #7 on: May 30, 2011, 03:55:33 AM »
Lets hope it's not too broken...

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: Clicks and Pops with WaveOut
« Reply #8 on: May 30, 2011, 03:01:30 PM »
Some code to test that
Code: [Select]
#define WIN32_DEFAULT_LIBS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#define _USE_MATH_DEFINES
#include <math.h>

//#define CHANNEL 2
#define SAMPLE_RATE 44100

void writeAudioBlock(HWAVEOUT hWaveOut, LPSTR block, DWORD size);
VOID FillBufferLR(short *pBuffer, int nSize, int iFreq, int iSampleRate);

char *WinMMErrorString(MMRESULT res)
{
static char szError[MAXERRORLENGTH];
waveOutGetErrorText(res, szError, sizeof(szError));
return szError;
}

int WINAPI WinMain(HINSTANCE Instance, HINSTANCE Previous, LPSTR Command, int Show)
{
HWAVEOUT hWaveOut;
WAVEFORMATEX wfx;
WAVEHDR whdr;
MMRESULT rc;
short aSine[16385];

wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = SAMPLE_RATE;
wfx.wBitsPerSample = 16;
wfx.cbSize = 0;
wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;

if ((rc = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR)
{
MessageBox(0, WinMMErrorString(rc), 0, MB_ICONERROR | MB_OK);
return 1;
}

// Some tests
FillBufferLR(aSine, sizeof(aSine)/sizeof(aSine[0]), 440, SAMPLE_RATE);
whdr.lpData = (LPSTR)&aSine;
whdr.dwBufferLength = sizeof(aSine)/sizeof(aSine[0]);
whdr.dwUser = 0;
whdr.dwFlags = 0;
whdr.dwLoops = 0;
whdr.lpNext = NULL;
whdr.reserved = 0;
waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
Sleep(100);
while (waveOutUnprepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING)
Sleep(100);
waveOutClose(hWaveOut);
return 0;
}

// Stereo L R 8-bit data is unsigned, but 16-bit data is signed
VOID FillBufferLR(short *pBuffer, int nSize, int iFreq, int iSampleRate)
{
double fAngle;
int i;

fAngle = 0;
for (i = 0; i < nSize; i+=2) {
pBuffer[i] = (short) (0x7FFF * sin(fAngle)*0.5);
pBuffer[i+1] = pBuffer[i];
fAngle += 2 * M_PI * iFreq / iSampleRate;
if (fAngle > 2 * M_PI)
fAngle -= 2 * M_PI;
}
}
May the source be with you

leandrojardim

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #9 on: May 31, 2011, 09:51:03 PM »
Yes, I heard the pops. Gets confusing, as I cant percept the sound quality of the algorithm.

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: Clicks and Pops with WaveOut
« Reply #10 on: June 01, 2011, 12:46:03 PM »
It was only example to test that problem.
Test putting enought silence to end of buffer.
Code: [Select]
FillBufferLR(aSine, (sizeof(aSine)/sizeof(aSine[0]))/2, 440, SAMPLE_RATE);
This example starts end ends to silence:
Code: [Select]
// Stereo L R 16-bit data is signed
VOID FillBufferLR(short *pBuffer, int nSize, int iFreq, int iSampleRate)
{
double fAngle, fLevel, fLevel2;
int i;

fAngle = 0;
fLevel = 1; // 0 - 1.0
int iPInc, iPDec;
iPInc = nSize / 3;
iPDec = nSize - iPInc - 1;
for (i = 0; i < nSize; i+=2) {
if (i <= iPInc) fLevel2 = (float)i / iPInc;
if (i >= iPDec) fLevel2 = (float)1.0 - (float)(i-iPDec) / iPInc;
pBuffer[i] = (short) (0x7FFF * sin(fAngle)*fLevel*fLevel2);
pBuffer[i+1] = pBuffer[i];

fAngle += 2 * M_PI * iFreq / iSampleRate;

if (fAngle > 2 * M_PI)
fAngle -= 2 * M_PI;
}
}
May the source be with you

leandrojardim

  • Guest
Re: Clicks and Pops with WaveOut
« Reply #11 on: June 02, 2011, 05:40:11 PM »
It not worked. :)
« Last Edit: June 02, 2011, 05:41:52 PM by leandrojardim »