packages feed

alsa-pcm-tests-0.1: volume_meter.hs

import Sound.Alsa
         (SoundFmt(SoundFmt), sampleFreq, soundSourceRead,
          SoundSource, alsaSoundSource, withSoundSource, )

import Foreign
         (allocaArray, peekArray,
          Storable, Ptr, castPtr, )
import Data.Int (Int16, )

bufSize :: Int
bufSize = 1000

inputFormat :: SoundFmt Int16
inputFormat = SoundFmt { sampleFreq  = 8000 }


main :: IO ()
main = let source = alsaSoundSource "plughw:0,0" inputFormat
        in allocaArray     bufSize $ \buf  -> 
           withSoundSource source  $ \from ->
               loop source from bufSize buf

-- FIXME: assumes little-endian machine
loop :: SoundSource Int16 h -> h -> Int -> Ptr Int16 -> IO ()
loop src h n buf =
    do n' <- soundSourceRead src h (castPtr buf) n
       avg <- avgBuf buf n'
       putStrLn (replicate (avg `div` 20) '*')
       loop src h n buf

avgBuf :: (Storable a, Integral a) => Ptr a -> Int -> IO Int
avgBuf buf n = do xs <- peekArray n buf
                  let xs' = map (fromIntegral . abs) xs :: [Int]
                  return $ sum xs' `div` fromIntegral n