Я использую libPd для генерации звука. LibPd может обрабатывать предопределенное количество тиков, а затем заполнять float[]
сгенерированным выводом. Затем я использую BufferedWaveProvider
для хранения float[]
после преобразования в byte[]
.
Генерация звука может быть очень быстрой, поэтому можно вычислить 1 секунду звука за довольно короткое время, но она также может быть медленной, в зависимости от патча Pd. Есть ли способ инициировать обработку данных, когда в BufferedWaveProvider
осталось меньше предопределенного объема данных?
В настоящее время я генерирую звук в фоновом потоке, просто сплю некоторое время и надеюсь, что этого достаточно, и надеюсь, что BufferedWaveProvider
не переполнится, и даже когда, а затем отбрасываю эти данные.
public void ProcessData(float[] output, int ticks)
{
while (LibPD.Process(ticks, new float[0], output) == 0)
{
if (BufferReady != null)
{
BufferReady(this, new BufferReadyEventArgs(output));
}
Thread.Sleep(999*BlockSize * ticks / 44100);
}
}
public void StartProcessing(float[] output)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(SetPdOutput), output);
}
private void SetPdOutput(object state)
{
float[] output = state as float[];
if (state == null)
{
return;
}
ProcessData(output, Ticks);
}
В то время как мой код для склеивания libPd и NAudio таков:
Buffer = new float[2 * _player.Ticks * _player.BlockSize]; // stereo, number of Ticks
_soundOutput = new WasapiOut(AudioClientShareMode.Shared, 100);
_audioBuffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 2))
{
BufferDuration = TimeSpan.FromSeconds(10),
DiscardOnBufferOverflow = true
};
_soundOutput.Init(_audioBuffer);
_soundOutput.Play();
_player.BufferReady += ((sender, eventArgs) =>
{
_audioBuffer.AddSamples(PcmFromFloat(output), 0, output.Length * 4);
});
_player.StartProcessing(Buffer);