1

我正在使用 Portaudio 在 Haskell 中编写音频程序。我有一个函数可以生成我想播放的样本列表,我正在尝试使用 main 中的以下代码段来播放它们:

curSamps <- return (chunk 1 (sineWave 440 44100))
forever $ do
  Right numSampsAvail <- getStreamWriteAvailable paStream
  Right NoError <- writeStream paStream curSamps numSampsAvail
  curSamps <- return (drop numSampsAvail curSamps)

sineWave 是我创建的一个函数,用于以指定的频率和采样率生成正弦波的 Int16 样本的无限列表。

当我调试此代码时,通过用 putStrLn 替换音频输出代码,它会打印全 0,这是该函数的第一个示例。

如何使用音频输出功能迭代此列表?我不认为我可以使用递归或地图。

编辑:代码复制错误

4

3 回答 3

4

使用递归:

play []       = return ()
play curSamps = do Right numSampsAvail <- getStreamWriteAvailable paStream
                   Right NoError <- writeStream paStream curSamps numSamps
                   play (drop numSampsAvail curSamps)

main = do ...
          play (chunk 1 (sineWave 440 44100))
          ...
于 2010-02-11T17:48:53.500 回答
4

考虑使用map's monadic cousins mapM/forM

于 2010-02-11T17:55:48.330 回答
2

使用相同的 API 函数可以做到这一点:

let playSamples curSamps = do
      Right numSampsAvail <- getStreamWriteAvailable paStream
      Right NoError <- writeStream paStream curSamps numSampsAvail
      playSamples (drop numSampsAvail curSamps)
playSamples (chunk 1 (sineWave 440 44100))

我不熟悉 Portaudio API,因此它可能会提供一种更方便、更高级的方式来完成您想要实现的目标。

于 2010-02-11T17:48:49.273 回答