gpt4 book ai didi

linux - 如何跨平台从 Haskell 代码播放音频文件

转载 作者:IT王子 更新时间:2023-10-29 00:34:31 29 4
gpt4 key购买 nike

我正在编写一个在 Linux、Windows 和 OS X 上运行的 Haskell 命令行应用程序。我现在必须播放音频文件(.wav.ogg.mp3) 从它。我将如何实现一个功能

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 绑定(bind)非常棘手。我关注了this nice explanation on how to do it
  • SDL-1.2 的 SDL 绑定(bind)似乎没有维护并且 do not even compile with GHC-7.8 or newer .起初我没有注意到,因为我的发行版 (Debian) 围绕这些问题打了补丁,但这意味着我的用户不能再轻松地 cabal install 依赖项。
  • 有 SDL-2 的绑定(bind),但没有 SDL_mixer 的绑定(bind),我在这里需要(我相信)。

所以我会很乐意阅读更好的答案。

关于linux - 如何跨平台从 Haskell 代码播放音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29841999/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com