-- | A high-level RTP receiver for G.711-ALAW. module Data.MediaBus.Rtp.AlawSource ( rtpAlaw16kHzS16Source , alawPayloadHandler ) where import Conduit import qualified Data.ByteString as B import Data.MediaBus import Data.MediaBus.Rtp.Packet import Data.MediaBus.Rtp.Source import Data.Proxy import Data.Streaming.Network (HostPreference) import Data.Word import Network.Socket (SockAddr) import Control.Lens import Data.Coerce import Control.Monad.Logger -- | Opend a UDP port and listen for RTP- G711 Alaw packets rtpAlaw16kHzS16Source :: (MonadLogger m, MonadResource m) => Int -> HostPreference -> Int -> Source m (Stream RtpSsrc RtpSeqNum (Ticks (Hz 16000) Word64) () (Segment (640 :/ Hz 16000) (Audio (Hz 16000) Mono (Raw S16)))) rtpAlaw16kHzS16Source !udpListenPort !udpListenIP !reorderBufferSize = annotateTypeSource (Proxy :: Proxy (Stream (SourceId (Maybe SockAddr)) RtpSeqNum (ClockTimeDiff UtcClock) () B.ByteString)) (udpDatagramSource useUtcClock udpListenPort udpListenIP) .| rtpSource .| rtpPayloadDemux [(8, alawPayloadHandler)] mempty .| annotateTypeCOut (Proxy :: Proxy (Stream RtpSsrc RtpSeqNum (Ticks (Hz 8000) Word32) () (Audio (Hz 8000) Mono (Raw S16)))) alawToS16 .| resample8to16kHz' (0 :: Pcm Mono S16) .| convertTimestampC (Proxy :: Proxy '( Hz 8000, Word32)) (Proxy :: Proxy '( Hz 16000, Word64)) .| reorderFramesBySeqNumC reorderBufferSize .| segmentC -- | Coerce an 'RtpPayload' to an 'ALaw' buffer. alawPayloadHandler :: RtpPayloadHandler t (Audio (Hz 8000) Mono (Raw ALaw)) alawPayloadHandler = framePayload %~ (view (from pcmMediaBuffer) . coerce . _rtpPayload)