25

いくつかのライブラリを使用してHaskellからWAVファイルを再生する簡単で直接的な方法はありますか?おそらく一度に多くのサウンドを再生できますか?

私は OpenAL を認識していますが、高度なオーディオ合成プログラムを書いているわけではありません。ちょっとした遊びのためにいくつかのサウンドを再生したいだけです。理想的には、API は次のようになります。

readWavFile :: FilePath -> IO Wave
playWave :: Wave -> IO ()
playWaveNonBlocking :: Wave -> IO ()

私は単にmplayerか何かを起動するだけに近いですまたは、wav を /dev/snd/ などに直接 cat しようとしています。

4

3 に答える 3

34

これは、SDL を使用して複数のチャネルで複数のサウンドを一度に再生する方法です。これは質問の基準に答えていると思います。WAV ファイル、シンプル、Haskell、複数チャンネル。

import Control.Monad
import Control.Monad.Fix
import Graphics.UI.SDL as SDL
import Graphics.UI.SDL.Mixer as Mix

main = do
  SDL.init [SDL.InitAudio]
  result <- openAudio audioRate audioFormat audioChannels audioBuffers
  classicJungle <- Mix.loadWAV "/home/chris/Samples/ClassicJungle/A4.wav"
  realTech      <- Mix.loadWAV "/home/chris/Samples/RealTech/A4.wav"
  ch1 <- Mix.playChannel anyChannel classicJungle 0
  SDL.delay 1000
  ch2 <- Mix.playChannel anyChannel realTech 0
  fix $ \loop -> do
    SDL.delay 50
    stillPlaying <- numChannelsPlaying
    when (stillPlaying /= 0) loop
  Mix.closeAudio
  SDL.quit

  where audioRate     = 22050
        audioFormat   = Mix.AudioS16LSB
        audioChannels = 2
        audioBuffers  = 4096
        anyChannel    = (-1)
于 2012-12-23T12:47:20.953 に答える
10

これは実際には便利な方法ではないことに気づきましたが、テストコードを置いていたので...

{-# LANGUAGE NoImplicitPrelude #-}
module Wav (main) where

import Fay.W3C.Events
import Fay.W3C.Html5

import Language.Fay.FFI
import Language.Fay.Prelude

main :: Fay ()
main = addWindowEventListener "load" run

run :: Event -> Fay Bool
run _ = do
    aud <- mkAudio
    setSrc aud "test.wav"
    play aud
    return False


mkAudio :: Fay HTMLAudioElement
mkAudio = ffi "new Audio()"

addWindowEventListener :: String -> (Event -> Fay Bool) -> Fay ()
addWindowEventListener = ffi "window['addEventListener'](%1,%2,false)"

HTML5のパワーのおかげで、HaskellでWAVファイルを再生できます。あなたがしなければならないのは、mplayerの代わりにウェブブラウザを起動することです。:D

于 2012-12-22T19:22:28.770 に答える
4

ALUT を介して OpenAL を使用する:

import Control.Monad
import Sound.ALUT

playSound :: IO ()
playSound =
  withProgNameAndArgs runALUTUsingCurrentContext $ \_ _ ->
  do
    (Just device) <- openDevice Nothing
    (Just context) <- createContext device []
    currentContext $= Just context
    buffer1 <- createBuffer $ Sine 440 0 1
    buffer2 <- createBuffer HelloWorld
    [source] <- genObjectNames 1
    queueBuffers source [buffer1,buffer2]
    play [source]
    sleep 4
    closeDevice device
    return ()

main = playSound

wav ファイルをロードするには:

buffer3 <- createBuffer $ File "/path/to/file.wav"

Chris Double の功績: http://bluishcoder.co.nz/articles/haskell/openal.html

于 2014-11-15T07:52:16.573 に答える