使用 Haskell 进行实时音频流传输

Jef*_*own 6 linux audio haskell stream conduit

我希望能够从 GHCI 实时播放简单的 [1] 音频,启动和停止独立的振荡器和样本(“声音”)。

在 Linux 上使用 Bash,很容易[2] 将数据传输到命令中,通过扬声器传输音频。

在 Haskell 中,我想象了一些类似的东西:

x <- realtimeAudioSink
createVoices x [VoiceName "sinewave",VoiceName "drums"]
play x (VoiceName "sinewave") $ sinewave (Hz 440)
play x (VoiceName "sinewave") $ sinewave (Hz 220)
  -- replace the earlier sinewave with a lower-frequency one
play x (VoiceName "drums")
  $ asSoonAs (theTime >= floor theTime)
  $ every (Seconds 10) $ soundfile "snare.wav"
  -- starting on the next second, play the snare drum sample every 10 seconds
destroyVoice x (VoiceName "drums")
  -- the drums stop, the sinewave keeps going
Run Code Online (Sandbox Code Playgroud)

Haskell 提供了很多流媒体库。每个看起来都很难学。此外,音频流问题由于需要以特定采样率进行实时操作以及缓冲问题而变得复杂[3]。

这是容易还是困难?


[1] 四个正弦波和四个样本同时出现似乎足以探索一生的带宽。

[2] 例如,如果您使用 ALSA,cat /dev/urandom | aplay则会播放白噪声。(警告:它以最大音量播放。)

[3] 我相信,缓冲问题来自以下一对相反的约束:(1) 如果每个样本都有自己的计算和流循环,它可能会使处理器不堪重负。(或者可能不会,如果生成的音频足够简单?) (2) 如果您在发送之前一次计算太多样本,您可能没有及时完成计算。