I did some research on sound synthesis and managed to write a very simple synthesizer. I've used the microsoft waveOut API. I wrote an interface to simplify the whole process. I can now initialize a (mono) audio stream and call setSample. So with a sampling rate of 44100 samples per second, setSample needs to be called at least 44100 times a second.
This works fine on my (quadcore) laptop, but on my parents' old dualcore vista, it stutters really bad. This is pretty weird: FL Studio runs quite smootly on my parents' machine, even when I use multiple effects on a more complicated synthesizer, while my code is fairly basic.
I have no idea what causes this behaviour. My code is far from optimized but so simple that I can hardly imagine that optimizing alone is the problem (unless I'm doing something which really slows the synthesis down).
The piece of code that could be a problem:
void AudioStream::setSample(float sample)
{
unsigned int discreteSample = ((sampleSize > 1) ? 0 : amplitude) + ((float)amplitude * sample);
for (unsigned int i = 0; i < sampleSize; i++)
{
data[pointr++] = (char)(discreteSample & 255);
discreteSample = discreteSample >> 8;
}
if (pointr >= maxSize)
{
if (waveOutWrite(hWaveOut, firstHeader ? &header1 : &header2, firstHeader ? sizeof(header1) : sizeof(header2)) != MMSYSERR_NOERROR)
{ throw("Error writing to sound card!"); return; }
pointr = 0;
firstHeader = !firstHeader;
if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0) { throw("An error occured while waiting for sound to finish"); return; }
unsigned char *temp;
temp = data;
data = play;
play = temp;
first = false;
}
}
I think the conversion from a floating point value to a discrete sample may be troublesome. I use this to handle multiple sample sizes.
I also heard that waveOut may be software emulated (which would explain a lot), but I'm not sure if (or when, as in on what versions of windows or under which circumstances) this is the case and how much of a performance difference this would make.
I hope someone can help me.
WaveOut API and good performance are impossible together. Use something more suitable, ASIO or WASAPI if using Windows, or try Portaudio if you want to be cross-platform.