I am writing a program which should output some frequency shift keyed (FSK) audio. I am using a sin(...) function to find some values to plug into an array of unsigned ints which I am outputting using waveOutWrite with a sample rate of 44100 specified in the header.

The values are all good and follow a sinusoidal wave, but looking at the output on the scope when I play the buffer shows a general sine wave shape with the frequency I want but it's a complex wave that's bouncing up and down with another sine-looking wave along the first wave.

When I specify a sample rate of 96000 in the header, it seems to look fine, but no other values seem to work. The Realtek 662 chip it's outputting from specifies that it can handle up to 96kHz, but the MSDN docs for WAVEOUTCAPS only shows 44.1kHz as the highest sample rate.

Playing pre-made wave files, even one that I bugged in the values from my buffer to, using PlaySound(...) looks nice and smooth on the scope, but if I play the 1.92ms duration wave files in succession to create the FSK it doesn't make a continuous wave like I need so it sounds like a bunch of blips (from the speaker kicking on and off?).

Any ideas why waveOutWrite makes the bad waveform or otherwise how to solve this problem? How can I play my buffer with a smooth sine wave?

Alternatively, I'm creating a string of binary bits that would need output as 1.92ms of frequency A for 0 bits and 1.92ms of frequency B for 1 bits. Other ideas on how to do that if what I'm doing above isn't the best way would also be appreciated.

Show us some code,please

"Show me your code and I will tell you who you are.."--Tkud

It's kind of a bastardization of a couple pieces of sample code I've found online, info from MSDN documentation and stuff I've generated.

signed int buffer[87];
const int max_amplitude = 16383;
int i;
CString tmp = "";
CString bufStr = "";
for (i=0; i < 87; i++)
{
	buffer[i] = max_amplitude * sin(i * 2 * 3.14159 * 1562.5 / 44100);
}



const int NUMPTS = 87;   // 10 seconds
int sampleRate = 44100;

HWAVEOUT hWaveOut;
WAVEHDR WaveOutHdr;
MMRESULT result;


// Specify recording parameters
WAVEFORMATEX pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM;		// simple, uncompressed format
pFormat.nChannels=1;				//  1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate;		// 44100
pFormat.nAvgBytesPerSec=sampleRate*2;		// = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2;				// = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16;			//  16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;

result = waveOutOpen(&hWaveOut, WAVE_MAPPER,&pFormat, 0, 0, CALLBACK_NULL);
if (result)
{
	char fault[256];
	waveOutGetErrorText(result, fault, 256);
	MessageBox("Failed to open waveform input device.");
	return;
}

// Set up and prepare header for input
ZeroMemory(&WaveOutHdr, sizeof(WAVEHDR));
WaveOutHdr.lpData = (LPSTR)buffer;
WaveOutHdr.dwBufferLength = sizeof(buffer);

result = waveOutPrepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));  
waveOutSetVolume(hWaveOut, 0xFFFF);
result = waveOutWrite(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR)); 
result = waveOutUnprepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
result = waveOutClose(hWaveOut);

Well, I solved it...kind of. I'm building the header and data portion of a wav file by hand, writing the whole thing to a file on disk and then using PlaySound(...) to play it back. I think that should work. I'll try to post code tomorrow to show how I did it.

I'd still be interested if anyone has an explanation or solution to the original problem.

This article has been dead for over six months. Start a new discussion instead.