mediabus-0.2.0.0: src/Data/MediaBus/Audio/Resample.hs
module Data.MediaBus.Audio.Resample ( resample8to16kHz' ) where
import Data.MediaBus.Stream
import Data.MediaBus.Sample
import Data.MediaBus.Audio.Raw
import Conduit
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as M
import Control.Monad.State.Strict
import Control.Lens
import Control.Parallel.Strategies ( NFData, rdeepseq, using )
resample8to16kHz' :: (NFData s, NFData t, NFData p, NFData i, IsAudioSample sa, GetAudioSampleRate sa ~ 8000, Monad m, IsAudioSample (SetAudioSampleRate sa 16000), NFData (SetAudioSampleRate sa 16000))
=> sa
-> Conduit (Stream i s t p (SampleBuffer sa)) m (Stream i s t p (SampleBuffer (SetAudioSampleRate sa 16000)))
resample8to16kHz' !sa = evalStateC sa (mapPayloadMC' resample)
where
resample !sb
| sampleCount sb == 0 = return (MkSampleBuffer mempty)
| otherwise = do
!lastVal <- get
let !lastVal' = V.last (sb ^. sampleVector)
put lastVal'
let !sb' = createSampleBufferFrom (interpolate lastVal) sb
return sb'
where
interpolate !lastVal !vIn = do
let !lenOut = 2 * lenIn
!vOut <- M.new lenOut
void $ lerpSamples vOut (doubleAudioSampleRate lastVal) 0
return (vOut `using` rdeepseq)
where
!lenIn = V.length vIn
lerpSamples !vOut !prev !i =
when (i < lenIn) $ do
!nextHalfRate <- V.indexM vIn i
let !next = doubleAudioSampleRate nextHalfRate
let !smpl = avgSamples prev next
M.unsafeWrite vOut (2 * i) smpl
M.unsafeWrite vOut (2 * i + 1) next
lerpSamples vOut next (i + 1)