c++visual-c++waveout

Bad performance with waveOut synth


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.

Edit: source can be found here, executable here.


Solution

  • 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.