我正在使用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,这是函数中的第一个样本。
如何使用音频输出功能迭代此列表?我认为我不能使用递归或地图。
编辑:代码复制错误
答案 0 :(得分: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))
...
答案 1 :(得分:4)
考虑使用map
的monadic堂兄mapM
/forM
。
答案 2 :(得分: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,因此它可以提供更方便,更高级的方式来完成您想要实现的目标。