我正在编写一个在Linux,Windows和OS X上运行的Haskell命令行应用程序。我现在必须从中播放audio文件( .wav
, .ogg
和.mp3
)。 我将如何去实现一个function
playAudioFile :: FilePath -> IO ()
甚至更好
playAudio :: ByteString -> IO ()
这只是在所有系统上工作?
(我很乐意引用常用的命令行工具,也不介意将它们捆绑在Windows发行版上。)
这是我使用SDL-1.2创建的代码:
module PlaySound (withSound, playSound) where import Control.Monad import System.IO import System.Directory import Data.Foldable import Control.Exception import qualified Data.ByteString.Lazy as B import Foreign.ForeignPtr import Graphics.UI.SDL as SDL import Graphics.UI.SDL.Mixer as Mix withSound :: IO a -> IO a withSound = bracket_ init cleanup where init = do SDL.init [SDL.InitAudio] getError >>= traverse_ putStrLn ok <- Mix.tryOpenAudio Mix.defaultFrequency Mix.AudioS16LSB 2 4096 unless ok $ putStrLn "Failed to open SDL audio device" cleanup = do Mix.closeAudio SDL.quit playSound :: B.ByteString -> IO () playSound content = do dir <- getTemporaryDirectory (tmp, h) <- openTempFile dir "sdl-input" B.hPutStr h content hClose h mus <- Mix.loadMUS tmp Mix.playMusic mus 1 wait -- This would double-free the Music, as it is also freed via a -- finalizer --Mix.freeMusic mus finalizeForeignPtr mus removeFile tmp wait :: IO () wait = do SDL.delay 50 stillPlaying <- Mix.playingMusic when stillPlaying wait
程序在最后工作正常,但是
cabal install
依赖关系了。 所以我会高兴地阅读更好的答案。