waveOut合成器性能不佳



我对声音合成进行了一些研究,并设法编写了一个非常简单的合成器。我使用过微软的waveOut API。我写了一个界面来简化整个过程。我现在可以初始化(单声道)音频流并调用setSample。因此,对于每秒44100个样本的采样率,setSample需要每秒至少调用44100次。

这在我的(四核)笔记本电脑上运行良好,但在我父母的旧双核vista上,它的口吃非常严重。这很奇怪:FL Studio在我父母的机器上运行得很慢,即使我在更复杂的合成器上使用多个效果,而我的代码相当基本。

我不知道是什么原因导致了这种行为。我的代码远未优化,但如此简单,以至于我很难想象单独优化就是问题所在(除非我正在做一些真正减缓合成速度的事情)。

可能出现问题的代码:

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;
    }
}

我认为从浮点值到离散样本的转换可能很麻烦。我用它来处理多个样本大小。

我还听说waveOut可能是软件模拟的(这可以解释很多),但我不确定是否(或何时,如在什么版本的窗口或在什么情况下)是这样,以及这会对性能产生多大影响。

我希望有人能帮助我。

编辑:源代码可以在这里找到,可在这里执行。

一次将一个样本传递给waveOutWrite将是非常低效的,无论是在代码级别还是在驱动程序中。它设置了一个缓冲区的DMA传输,如果该缓冲区有一个字节长,则会导致为每个样本切换缓冲区的所有开销。我会在每次调用waveOutWrite时向它发送至少十分之一秒的样本。

WaveOut API和良好的性能是不可能结合在一起的。如果使用Windows,请使用更合适的东西,ASIO或WASAPI,如果您想跨平台,请尝试Portaudio。

如果你正在寻找一些非常简单的音频库来制作一个简单的合成器,我强烈推荐audierehttp://audiere.sourceforge.net/或BASShttp://www.un4seen.com/.

第一个已经过时了,但同时也是最简单的一个(这并不会让它变得糟糕)。我可以用它写不那么简单的合成器。第二个,BASS,在更复杂的项目中也会对你有好处。它提供了非常简单的例子(合成器就是其中之一)。设置起来也很容易。

相关内容

  • 没有找到相关文章

最新更新