私は音声合成についていくつかの調査を行い、非常に単純なシンセサイザーを作成することができました。Microsoft waveOut API を使用しました。プロセス全体を簡素化するためのインターフェースを作成しました。(モノラル) オーディオ ストリームを初期化し、setSample を呼び出すことができるようになりました。したがって、1 秒あたり 44100 サンプルのサンプリング レートでは、setSample を 1 秒あたり少なくとも 44100 回呼び出す必要があります。
これは私の(クアッドコア)ラップトップでは問題なく動作しますが、両親の古いデュアルコア ビスタでは、非常にカクカクします。これはかなり奇妙です。コードはかなり基本的なものですが、より複雑なシンセサイザーで複数のエフェクトを使用している場合でも、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 で、どのような状況で)、どの程度のパフォーマンスが得られるかはわかりません。これがもたらす違い。
誰かが私を助けてくれることを願っています。