如何从Haskell代码跨平台播放audio文件

我正在编写一个在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 

程序在最后工作正常,但是

  • 编译在Windows下的SDL绑定是棘手的。 我遵循这个好的解释如何做到这一点
  • SDL-1.2的SDL绑定似乎没有维护, 甚至没有用GHC-7.8或更新版本编译 。 起初我没有注意到,因为我的发行版(Debian)围绕这些问题进行了修补,但这意味着我的用户不能再轻易地cabal install依赖关系了。
  • 有SDL-2的绑定,但没有SDL_mixer,我需要在这里(我相信)。

所以我会高兴地阅读更好的答案。