我正在尝试编写一个迷你合成器程序。本质上,每 200 毫秒触发一个计时器。当它被触发时,循环会生成 200mS 的 PCM 样本(例如锯齿波、正弦波等),样本的数量与采样率和扫描周期有关。例如,每 200 毫秒,波形阵列中有 4000 个样本可供播放。我的问题是,我该如何播放这个数组,即 PlaySound 方法应该做什么?每 200 毫秒调用一次 PlaySound 应该以连续的方式播放后续样本。我玩过 DirectSound 和 NAudio 无济于事。
const int SAMPLE_RATE = 20000;
const double SCAN_PERIOD = .2; // S
Timer _ScanTimer = new Timer();
double[] wave = new double[(int)((double)SAMPLE_RATE * SCAN_PERIOD)];
_ScanTimer.Tick += new EventHandler(_ScanTimer_Tick);
private void _ScanTimer_Tick(object sender, EventArgs e) {
int numSamplesPerTick = (int)((double)SAMPLE_RATE * SCAN_PERIOD);
double secondsPerTick = (double)2 / SAMPLE_RATE;
for (int i = 0; i < numSamplesPerTick; i++) {
wave[i] = GetSynthOutput();
_CurrentTime += secondsPerTick;
if (_CurrentTime > double.MaxValue - 1)
_CurrentTime = 0;
}
PlaySound(wave);
}
我意识到计时器可能不会每 200 毫秒准确触发一次,并且 4000 个样本可能包含实际时间稍微太少或太多的样本。我并不担心这一点,因为我可以根据后续计时器触发之间的实际时间调整样本数量。