2015-04-24 8 views
6

मैं एक हास्केल कमांड लाइन एप्लिकेशन लिख रहा हूं जो लिनक्स, विंडोज और ओएस एक्स पर चलता है। अब मुझे ऑडियो फाइलें (.wav, .ogg और .mp3) खेलना है यह। मैं एक समारोहहास्केल कोड से ऑडियो फ़ाइल कैसे चलाएं, क्रॉस-प्लेटफ़ॉर्म

playAudioFile :: FilePath -> IO() 

या और भी बेहतर

playAudio :: ByteString -> IO() 

कि बस सभी सिस्टम पर काम करता है को लागू करने के बारे में कैसे जाना होगा?

(मैं आम कमांड लाइन उपकरण आह्वान करने के लिए और भी उन्हें विंडोज वितरण के लिए बंडल कोई आपत्ति नहीं है खुश हूँ।)

+0

यह http://stackoverflow.com/questions/14005592/play-a-wav-file-with-haskell से संबंधित है, लेकिन मैं '.wav' के अलावा सामान्य फ़ाइल प्रारूपों खेलने के लिए की जरूरत है। –

+0

यदि यह वास्तव में संभव है तो मैं (सुखद) आश्चर्यचकित हूं। मेरा मतलब है, मैन्युअल रूप से कुछ मौजूदा सी लाइब्रेरी में बाइंडिंग लिखने के बिना ... – MathematicalOrchid

+0

हम्म, शायद http://stackoverflow.com/a/14011063/946226 वास्तव में सही दिशा को इंगित करता है; एसडीएल एमपी 3 और [Graphics.UI.SDL.Mixer.Music] में ऑग (http://hackage.haskell.org/package/SDL-mixer-0.6.1/docs/Graphics-UI-SDL-Mixer- समर्थन करने के लिए लगता है music.html)। –

उत्तर

2

इस कोड को मैं के साथ आया था, एसडीएल-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 के तहत एसडीएल बाइंडिंग संकलन मुश्किल है। मैं पीछा किया this nice explanation on how to do it
  • एसडीएल-1.2 के लिए एसडीएल बाइंडिंग unmaintained और do not even compile with GHC-7.8 or newer होने लगते हैं। मैंने पहले नोटिस नहीं किया था, क्योंकि मेरा वितरण (डेबियन) ऐसे मुद्दों के आसपास पैच करता है, लेकिन इसका मतलब है कि मेरे उपयोगकर्ता अब निर्भरता cabal install निर्भरताओं को आसानी से नहीं कर सकते हैं।
  • वहाँ एसडीएल -2 के लिए बाइंडिंग हैं, लेकिन SDL_mixer, जिसे मैंने यहां की जरूरत के लिए कोई नहीं (मेरा मानना ​​है कि)।

तो मैं खुशी से बेहतर उत्तर पढ़ लेंगे।

+0

का बहुत कुछ शामिल है अंत में, मैं 'SDL' का उपयोग कर, एसडीएल-1.2 हास्केल बाइंडिंग, जो unmaintained हैं पर निर्भरता से बचने के लिए एक समर्पित द्विआधारी इस्तेमाल किया। वह [कोड सी में लिखा गया है] (https://github.com/entropia/tip-toi-reveng/blob/master/playmus/playmus.c), बस इसलिए कि एसडीएल_मिक्सर के साथ आया उदाहरण कोड लगभग काफी अच्छा था। –

+0

मुझे लगता है कि एसडीएल और एसडीएल_मिक्सर की आवश्यकता के बिना mp3s या wavs खेलने का एक आसान तरीका होना अच्छा होगा, या कम से कम उन विवरणों को छुपाएं। मैं सिर्फ SDL_mixer की देखभाल करने के लिए एक पैच भेजा यह GHC 7.8 के साथ संकलित करने के लिए प्राप्त करने के लिए (यह मुझे एक लिंक करने में त्रुटि दे रहा था)। मैं उत्सुक हूँ: आपके पास क्या समस्या है? मिक्सर के लिए SDL2 बाइंडिंग रहे हैं, https://github.com/jdeseno/hs-sdl2-mixer देखते हैं। मैंने केरा स्टूडियो की जादू कुकीज़ के लिए उन लोगों का इस्तेमाल किया! और उन्होंने ठीक काम किया (एंड्रॉइड के लिए उन्हें संकलित करने के लिए मामूली समायोजन के साथ)। –

+0

मुझे याद नहीं है, लेकिन शायद http://comments.gmane.org/gmane.comp.lang.haskell में उल्लिखित जैसा ही है।शुरुआती/13,663। 'sd2-mixer' के बारे में: यह अभी तक हैकेज पर नहीं है, जिसने मुझे उनका उपयोग करने से रोक दिया होगा। –

संबंधित मुद्दे