packages feed

hXmixer-0.2.5.0: src/MixerQuery.hs

module MixerQuery
(
   mixerDevices,
   mixerChannels,
   setVol
) where

import Data.List (isInfixOf, sort)
import Data.List.Split (splitOn)
import System.IO (FilePath)
import System.Directory (getDirectoryContents)
import System.Process (runInteractiveCommand)
import GHC.IO.Handle (hGetContents)

-- | Gets all available mixer devices on this system.
mixerDevices :: IO [FilePath]
mixerDevices = 
   getDirectoryContents "/dev" >>= return . ("Default" : ) . map ((++) "/dev/") . sort . filter (isInfixOf "mixer")

-- | Gets the channels from a mixer device.
mixerChannels :: FilePath -> IO [(String, (Int, Int))]
mixerChannels mixer = do
   (_, stdout, _, _) <- runInteractiveCommand $ command mixer
   hGetContents stdout >>= return . parseMixerLines . lines
   where
      command "Default" = "mixer"
      command mixer' = "mixer -f " ++ mixer'

-- | Parses out the channel names and volumes from the output
-- of the mixer command.
parseMixerLines :: [String] -> [(String, (Int, Int))]
parseMixerLines lines =
   [(line !! 1, parseLevels $ last line) | line <- map words $ filter (isInfixOf "Mixer ") lines]
   where
      parseLevels str = (\(x:y:_) -> (read x, read y)) $ splitOn ":" str

-- | Sets the volume of a channel.
setVol :: String -> String -> Int -> Int -> IO ()
setVol "Default" channel left right =
   setVolCmd ["mixer", channel, (show left) ++ ":" ++ (show right)]
setVol mixer channel left right =
   setVolCmd ["mixer", "-f", mixer, channel, (show left) ++ ":" ++ (show right)]
   
setVolCmd cmd = (runInteractiveCommand $ unwords cmd) >>= \_ -> return ()