module Sound.ALSA.PCM.Node.ALSA (
Handle,
PCM.Stream(..),
PCM.Mode, PCM.modes, PCM.nonBlock, PCM.async,
Interleaved, Noninterleaved,
Time, SampleFreq, Size,
Class.Access, Class.SampleFmt, Class.MonoSampleFmt,
open,
PCM.close,
PCM.prepare,
PCM.start,
PCM.drop,
PCM.drain,
readi, writei, readiRetry, writeiRetry,
readn, writen,
) where
import Sound.ALSA.PCM.Parameters.Hardware (Time, SampleFreq, Size, )
import Sound.ALSA.PCM.Core.Handle (Handle, Interleaved, Noninterleaved, prepare, )
import qualified Sound.ALSA.PCM.Parameters.Software as SwParam
import qualified Sound.ALSA.PCM.Parameters.Hardware as HwParam
import qualified Sound.ALSA.PCM.Core.Class as Class
import qualified Sound.ALSA.PCM.Core.Handle as PCM
import qualified Sound.ALSA.PCM.Debug as Debug
import qualified Sound.ALSA.Exception as AlsaExc
import Foreign.Marshal.Array (advancePtr, )
import Foreign (Ptr, )
open ::
(Class.Access i, Class.SampleFmt y) =>
PCM.Mode
-> PCM.Stream
-> HwParam.T i y a
-> (a -> SwParam.T i y b)
-> String
-> IO (b, Handle i y)
open mode stream hwp swp dev = do
h <- PCM.open dev stream mode
a <- Class.withHwParams h hwp
b <- Class.withSwParams h $ swp a
return (b, h)
readi ::
(Class.SampleFmt y) =>
Handle Interleaved y -> Ptr y -> Size -> IO Size
readi = PCM.readi
writei ::
(Class.SampleFmt y) =>
Handle Interleaved y -> Ptr y -> Size -> IO Size
writei = PCM.writei
readn ::
(Class.MonoSampleFmt y) =>
Handle Noninterleaved y -> Ptr (Ptr y) -> Size -> IO Size
readn = PCM.readn
writen ::
(Class.MonoSampleFmt y) =>
Handle Noninterleaved y -> Ptr (Ptr y) -> Size -> IO Size
writen = PCM.writen
readiRetry ::
Class.SampleFmt y =>
Handle Interleaved y -> Ptr y -> Size -> IO Size
readiRetry h buf0 n =
let go buf offset = do
nread <-
readi h buf (n-offset)
`AlsaExc.catchXRun`
do Debug.put "snd_pcm_readi reported buffer over-run"
prepare h
go buf offset
let newOffset = offset+nread
if newOffset < n
then go (advancePtr buf (fromIntegral nread)) newOffset
else return newOffset
in go buf0 0
writeiRetry ::
Class.SampleFmt y =>
Handle Interleaved y -> Ptr y -> Size -> IO Size
writeiRetry h buf0 n =
let go buf offset = do
nwritten <-
writei h buf (n-offset)
`AlsaExc.catchXRun`
do Debug.put "snd_pcm_writei reported buffer under-run"
prepare h
go buf offset
let newOffset = offset+nwritten
if newOffset < n
then go (advancePtr buf (fromIntegral nwritten)) newOffset
else return newOffset
in go buf0 0