sdl2-mixer-0.1: examples/Effect.hs
module Main where
import Data.Int (Int16)
import Data.Word (Word8)
import Control.Monad (when, forM_)
import System.Environment (getArgs)
import System.Exit (exitFailure)
import qualified SDL
import qualified SDL.Mixer as Mix
import qualified Data.Vector.Storable.Mutable as MV
main :: IO ()
main = do
SDL.initialize [SDL.InitAudio]
Mix.withAudio Mix.defaultAudio 256 $ do
putStr "Available music decoders: "
print =<< Mix.musicDecoders
args <- getArgs
case args of
[] -> putStrLn "Usage: cabal run sdl2-mixer-effect FILE" >> exitFailure
xs -> runExample $ head xs
SDL.quit
-- An effect that does something silly: lowers the volume 2 times.
halveVolume :: MV.IOVector Word8 -> IO ()
halveVolume bytes = do
let shorts = MV.unsafeCast bytes :: MV.IOVector Int16
forM_ [0 .. MV.length shorts - 1] $ \i -> do
s <- MV.read shorts i
MV.write shorts i $ div s 2
-- Apply an Effect on the Music being played.
runExample :: FilePath -> IO ()
runExample path = do
-- Add effects, get back effect removal actions.
-- The volume should be FOUR times as low after this.
popEffects <-
mapM (Mix.effect Mix.PostProcessing (\_ -> return ()) . const)
[halveVolume, halveVolume]
-- Then give the left channel louder music than the right one.
popPan <- Mix.effectPan Mix.PostProcessing 128 64
music <- Mix.load path
Mix.playMusic Mix.Once music
delayWhile Mix.playingMusic
-- The effects are no longer applied after this.
sequence_ $ popPan : popEffects
Mix.free music
delayWhile :: IO Bool -> IO ()
delayWhile check = loop'
where
loop' = do
still <- check
when still $ SDL.delay 300 >> delayWhile check