我对声音合成做了一些研究,并设法编写了一个非常简单的合成器。我使用了 microsoft 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 可能是软件模拟的(这可以解释很多),但我不确定是否(或何时,如在什么版本的 Windows 或在什么情况下)是这种情况以及性能有多大这会有所不同。
我希望有一个人可以帮助我。