mediabus-fdk-aac 0.3.2.1 → 0.4.0.0
raw patch · 6 files changed
+193/−227 lines, 6 filesdep ~mediabusdep ~mediabus-fdk-aac
Dependency ranges changed: mediabus, mediabus-fdk-aac
Files
- bench/Encoder.hs +42/−31
- examples/Main.hs +3/−2
- mediabus-fdk-aac.cabal +7/−6
- src/Data/MediaBus/FdkAac/Conduit/Encoder.hs +19/−75
- src/Data/MediaBus/FdkAac/Encoder.hs +79/−74
- src/Data/MediaBus/FdkAac/EncoderFdkWrapper.hs +43/−39
bench/Encoder.hs view
@@ -2,54 +2,69 @@ ( main ) where -import Control.Monad import Control.Monad.Logger+import Criterion.Main import Data.Conduit+import Data.Conduit.List import Data.MediaBus import Data.MediaBus.FdkAac-import Data.Conduit.List import Data.Time.Clock import Data.Typeable-import Criterion.Main-import Control.Lens-import Data.Vector.Storable as V import Data.Word import GHC.TypeLits main :: IO ()-main =- defaultMain- [bgroupFromTestDuration 1000 16000, bgroupFromTestDuration 1000 48000]+main = defaultMain [bgroupFromTestDuration 1] -bgroupFromTestDuration :: NominalDiffTime -> Int -> Benchmark-bgroupFromTestDuration testdur samplesPerSecond =- bgroup- (show testdur Prelude.++ " ptime=20ms " Prelude.++ show samplesPerSecond Prelude.++- " Hz") $+bgroupFromTestDuration :: NominalDiffTime -> Benchmark+bgroupFromTestDuration testdur =+ bgroup (show testdur Prelude.++ " ptime=20ms") $ let frameCount = ceiling (testdur / ptime) ptime = 20 / 1000 in [ bgroup- "AAC HE"+ "AAC HE 16kHz" [ bench "Stereo" $ nfIO $ encodeNFrames (aacEncoderConfig aacHe16KhzStereo) $- testFrames testdur frameCount+ testFrames ptime frameCount , bench "Mono" $ nfIO $ encodeNFrames (aacEncoderConfig aacHe16KhzMono) $- testFrames testdur frameCount+ testFrames ptime frameCount ] , bgroup- "AAC LC"+ "AAC LC 16kHz" [ bench "Stereo" $ nfIO $ encodeNFrames (aacEncoderConfig aacLc16KhzStereo) $- testFrames testdur frameCount+ testFrames ptime frameCount , bench "Mono" $ nfIO $ encodeNFrames (aacEncoderConfig aacLc16KhzMono) $- testFrames testdur frameCount+ testFrames ptime frameCount ]+ , bgroup+ "AAC HE 48kHz"+ [ bench "Stereo" $+ nfIO $+ encodeNFrames (aacEncoderConfig aacHe48KhzStereo) $+ testFrames ptime frameCount+ , bench "Mono" $+ nfIO $+ encodeNFrames (aacEncoderConfig aacHe48KhzMono) $+ testFrames ptime frameCount+ ]+ , bgroup+ "AAC LC 48kHz"+ [ bench "Stereo" $+ nfIO $+ encodeNFrames (aacEncoderConfig aacLc48KhzStereo) $+ testFrames ptime frameCount+ , bench "Mono" $+ nfIO $+ encodeNFrames (aacEncoderConfig aacLc48KhzMono) $+ testFrames ptime frameCount+ ] ] encodeNFrames@@ -64,23 +79,19 @@ , Typeable r ) => AacEncoderConfig r channels aot- -> [Stream SrcId32 SeqNum16 (Ticks r Word64) () (Audio r channels (Raw S16))]- -> IO [Stream SrcId32 SeqNum16 (Ticks r Word64) (AacEncoderInfo r channels aot) (Audio r channels (Aac aot))]+ -> [SyncStream SrcId32 () (Audio r channels (Raw S16))]+ -> IO [Stream SrcId32 SeqNum64 (Ticks r Word64) (AacEncoderInfo r channels aot) (Audio r channels (Aac aot))] encodeNFrames cfg pcms = runStdoutLoggingT $- runConduitRes $ sourceList pcms .| encodeLinearToAacC cfg .| consume+ runConduitRes $+ sourceList pcms .| encodeLinearToAacC cfg .| setSequenceNumberAndTimestampC .|+ consume testFrames :: (KnownRate r, IsPcmValue (Pcm channels S16)) => NominalDiffTime -> Int- -> [Stream SrcId32 SeqNum16 (Ticks r Word64) () (Audio r channels (Raw S16))]+ -> [SyncStream SrcId32 () (Audio r channels (Raw S16))] testFrames frameDuration frames =- [ MkStream- (Next- (MkFrame- (fromIntegral x * (nominalDiffTime # frameDuration))- (fromIntegral x)- (blankFor frameDuration)))- | x <- [0 .. frames]- ]+ Prelude.replicate frames $+ MkStream (Next (MkFrame () () (blankFor frameDuration)))
examples/Main.hs view
@@ -13,15 +13,16 @@ encodeOneSeconfOfSilence :: IO [Stream SrcId32- SeqNum16+ SeqNum64 (Ticks64 (Hz 48000)) (AacEncoderInfo (Hz 48000) Stereo 'HighEfficiency) (Audio (Hz 48000) Stereo (Aac 'HighEfficiency))] encodeOneSeconfOfSilence = runStdoutLoggingT $ runConduitRes $- yieldNextFrame (MkFrame 0 0 pcmAudioOneSecond)+ yieldNextFrame (MkFrame () () pcmAudioOneSecond) .| encodeLinearToAacC encoderConfig+ .| setSequenceNumberAndTimestampC .| traceShowSink 1 "Example Trace" where
mediabus-fdk-aac.cabal view
@@ -1,5 +1,5 @@ name: mediabus-fdk-aac-version: 0.3.2.1+version: 0.4.0.0 cabal-version: >=1.10 build-type: Simple license: BSD3@@ -27,7 +27,7 @@ deepseq <1.5, inline-c <0.6, lens <4.16,- mediabus <0.4,+ mediabus ==0.4.*, monad-logger <0.4, random <1.2, resourcet <1.2,@@ -67,8 +67,8 @@ ghc-prim <0.6, lens <4.16, monad-logger <0.4,- mediabus-fdk-aac <0.4,- mediabus <0.4,+ mediabus-fdk-aac <0.5,+ mediabus ==0.4.*, conduit <1.3, vector <13 default-language: Haskell2010@@ -93,9 +93,10 @@ ghc-prim <0.6, lens <4.16, monad-logger <0.4,+ time <1.7, criterion <1.2,- mediabus-fdk-aac <0.4,- mediabus <0.4,+ mediabus-fdk-aac <0.5,+ mediabus ==0.4.*, conduit <1.3, vector <13 default-language: Haskell2010
src/Data/MediaBus/FdkAac/Conduit/Encoder.hs view
@@ -6,25 +6,26 @@ ) where import Conduit-import Control.Lens-import Control.Monad import Control.Monad.Logger-import Control.Monad.Trans.State.Strict as State import Data.MediaBus import Data.MediaBus.FdkAac.Encoder-import Data.String import Data.Tagged import Data.Typeable import GHC.TypeLits - -- * Conduit Based 'Stream' Encoding -- | A conduit that receives signed 16 bit, mono or stereo, 'Raw' 'Audio' and--- yields AAC encoded frames. The timestamps of the input frames will be--- regarded such that gaps in the timestamps are reflected in the generated--- frames. The sequence numbering will be+-- yields AAC encoded frames.+-- When a 'Start' event is received, the delay lines will be flushed.+-- The timestamps and sequence numbers of the input will be ignored.+-- The output sequence numbers start from zero and increase+-- monotonic. 'Start' events don't lead to resetting neither sequence numbers+-- nor timestamps.+-- The timestamps start at the encoder delay and are increased by 'frameSize'+-- and the type signature requires that the timestamp unit for 'Frame's has the+-- same sampling rate as the encoded audio. encodeLinearToAacC- :: forall channels r aot i s t m.+ :: forall channels r aot i m. ( MonadLoggerIO m , MonadThrow m , MonadResource m@@ -34,81 +35,24 @@ , Show (AacAotProxy aot) , KnownNat (GetAacAot aot) , Show i- , Show t- , Typeable t- , LocalOrd t- , Show s- , Typeable s- , Num t- , Num s , CanBeSample (Pcm channels S16) , Show (Pcm channels S16)- , Integral t ) => AacEncoderConfig r channels aot- -> Conduit (Stream i s (Ticks r t) () (Audio r channels (Raw S16))) m (Stream i s (Ticks r t) (AacEncoderInfo r channels aot) (Audio r channels (Aac aot)))+ -> Conduit (SyncStream i () (Audio r channels (Raw S16))) m (SyncStream i (AacEncoderInfo r channels aot) (Audio r channels (Aac aot))) encodeLinearToAacC aacCfg = do (Tagged enc, info) <- lift $ aacEncoderAllocate aacCfg- (_res, _st, ()) <-- prefixLogsC (show enc ++ " - ") $- runRWSC- enc- (MkAacEncSt @r @channels @aot 0)- (evalStateC- (initialReframerState :: ReframerSt s (Ticks r t))- (encodeThenFlush info))- return ()+ prefixLogsC (show enc ++ " - ") $ runReaderC enc (encodeThenFlush info) where encodeThenFlush info = do awaitForever go- aacs <- lift $ lift flushAacEncoder- Prelude.mapM_ yieldAacFrame aacs+ aacs <- lift flushAacEncoder+ Prelude.mapM_ yieldNextFrame aacs where go (MkStream (Next f)) = do- let reframeFrame = f & framePayload %~ getDurationTicks- $logDebug (fromString ("in: " ++ show f))- pushRes <- lift $ pushFrame reframeFrame- case pushRes of- Nothing -> return ()- Just er -> do- $logInfo- (fromString- ("frame timing problem: " ++ show er ++ ", frame: " ++- show reframeFrame))- lift $ State.get >>= $logInfoSH- aacs <- lift $ lift flushAacEncoder- Prelude.mapM_ yieldAacFrame aacs- lift $- pushStartFrame- (reframeFrame ^. frameTimestamp + reframeFrame ^. framePayload)- aacs <-- lift $ lift $- encodeLinearToAac (view framePayload f)- Prelude.mapM_ yieldAacFrame aacs- go start@(MkStream (Start (MkFrameCtx fi ft fs _fp))) = do- lift $ pushStartFrame ft- lift $ $logDebug (fromString ("in: " ++ show start))- let outStart = MkFrameCtx fi ft fs info- lift $ $logDebug (fromString ("out: " ++ show outStart))+ aacs <- lift (encodeLinearToAac f)+ Prelude.mapM_ yieldNextFrame aacs+ go (MkStream (Start (MkFrameCtx fi _ _ _))) = do+ lift flushAacEncoder >>= Prelude.mapM_ yieldNextFrame+ let outStart = MkFrameCtx fi () () info yieldStartFrameCtx outStart- yieldAacFrame fc =- let wantDur = getDurationTicks fc- in when (wantDur > 0) $ do- frm <- lift $ generateFrame wantDur- when (frm ^. framePayload < wantDur) $ do- $logInfo- (fromString- ("encoder generated more output than input, input: " ++- show (frm ^. framePayload) ++- " < output: " ++- show wantDur))- availDur <- lift nextFrameAvailableDuration- $logInfo- (fromString- ("samples enqueuend in the encoder delay lines: " ++- show availDur))- rfst <- lift $ State.get- $logInfoSH rfst- let outFrm = frm & framePayload .~ fc- $logDebug (fromString ("out: " ++ show outFrm))- yieldNextFrame outFrm
src/Data/MediaBus/FdkAac/Encoder.hs view
@@ -5,7 +5,7 @@ -- For an easy to use, high-level interface please consult -- 'Data.MediaBus.FdkAac.Conduit.Encoder'. module Data.MediaBus.FdkAac.Encoder- ( aacFrameSize+ ( aacFrameDuration , aacFrameMediaData , Aac , aacHe48KhzStereo@@ -29,8 +29,6 @@ , type GetAacAot , aacEncoderAllocate , type AacEncT- , AacEncSt(..)- , numberOfDelayedSamples , encodeLinearToAac , flushAacEncoder ) where@@ -39,10 +37,9 @@ import Control.DeepSeq import Control.Lens import Control.Monad.Logger-import Control.Monad.Trans.RWS.Strict+import Control.Monad.Trans.Reader import Control.Monad.Trans.Resource import Data.Kind-import Data.Maybe import Data.MediaBus import Data.MediaBus.FdkAac.EncoderFdkWrapper import Data.Proxy@@ -58,9 +55,9 @@ -- | This is the media type for AAC encoded audio data. data Aac (aot :: AacAot) -data instance Audio r c (Aac aot) = MkAacFrame{aacFrameMediaData- :: !(V.Vector Word8),- aacFrameSize :: !Word64}+data instance Audio r c (Aac aot) = MkAacBuffer{aacFrameMediaData+ :: !(V.Vector Word8),+ aacFrameDuration :: !(Ticks64 r)} deriving (Generic) instance (KnownRate r, KnownChannelLayout c, Show (AacAotProxy aot)) =>@@ -82,24 +79,25 @@ instance (KnownRate r) => HasDuration (Audio r c (Aac aot)) where- getDuration MkAacFrame {aacFrameSize} =- from nominalDiffTime # (MkTicks aacFrameSize :: Ticks r Word64)- getDurationTicks MkAacFrame {aacFrameSize} =- convertTicks (MkTicks aacFrameSize :: Ticks r Word64)+ getDuration MkAacBuffer {aacFrameDuration} =+ from nominalDiffTime # aacFrameDuration+ getDurationTicks MkAacBuffer {aacFrameDuration} =+ convertTicks aacFrameDuration instance NFData (Audio r c (Aac aot)) instance (KnownRate r, KnownChannelLayout c, Show (AacAotProxy aot)) => Show (Audio r c (Aac aot)) where- showsPrec d MkAacFrame {aacFrameMediaData, aacFrameSize} =+ showsPrec d MkAacBuffer {aacFrameMediaData, aacFrameDuration} = showParen (d > 10) (showString "aac frame: " . showsPrec 11 (MkShowMedia :: MediaDescription (Audio r c (Aac aot))) . showString ", samples: " .- shows aacFrameSize .+ shows aacFrameDuration . showString ", data: " .- showsPrec 11 (V.length aacFrameMediaData) . showString " bytes starting with: " .+ showsPrec 11 (V.length aacFrameMediaData) .+ showString " bytes starting with: " . showsPrec 11 (V.take 16 aacFrameMediaData)) instance (KnownRate r, KnownChannelLayout c, Show (AacAotProxy aot)) =>@@ -179,7 +177,7 @@ , _aacEncoderInfoId :: String -- ^ Identification string for one specific encoder, derived from the natice -- C pointer in 'encoderHandle'.- } deriving Generic+ } deriving (Generic) instance NFData (AacEncoderInfo r c a) @@ -295,19 +293,11 @@ return (Tagged enc, i) -- * Stateful Encoding---- | Type alias for the internal RWS monad of the aac encoder.-type AacEncT rate channels aot m a = RWST Encoder () (AacEncSt rate channels aot) m a---- | The internal state for 'encodeLinearToAac'-newtype AacEncSt (rate :: Rate) channels (aot :: AacAot) = MkAacEncSt- { _numberOfDelayedSamples :: Word64- -- ^ The number of input samples currently buffered in the delay lines of the encoder.- } deriving (Show)+-- | Type alias for the internal ReaderT monad of the aac encoder.+type AacEncT rate channels aot m a = ReaderT Encoder m a --- | An internal 'Iso' for the 'AacEncSt'-numberOfDelayedSamples :: Iso' (AacEncSt (rate :: Rate) channels (aot :: AacAot)) Word64-numberOfDelayedSamples = iso _numberOfDelayedSamples MkAacEncSt+-- | Aac encoded 'Frame's+type AacFrame rate channels aot = Frame () () (Audio rate channels (Aac aot)) -- | Convert linear audio to AAC encoded audio with the given encoder settings. encodeLinearToAac@@ -320,17 +310,17 @@ , MonadThrow m , MonadLogger m )- => Audio rate channels (Raw S16)- -> AacEncT rate channels aot m [Audio rate channels (Aac aot)]-encodeLinearToAac !aIn =+ => Frame someSeq someTicks (Audio rate channels (Raw S16))+ -> AacEncT rate channels aot m [AacFrame rate channels aot]+encodeLinearToAac (MkFrame _ _ !aIn) = let dIn = V.unsafeCast (aIn ^. mediaBuffer . mediaBufferVector)- in encodeSampleVector dIn []+ in encodeAllFrames dIn [] --- | Convert linear audio to AAC encoded audio with the given encoder settings,+-- | (Internal) Convert linear audio to AAC encoded audio with the given encoder settings, -- from a raw sample vector.--- If the sample vector contains more that the encoder can swallow at a time,--- the encoder is repeatedly called until all input is consumed.-encodeSampleVector+-- If the input contains more than 'frameSize' samples per channel, recurse+-- until all input is consumed and return the generated frames.+encodeAllFrames :: forall m channels rate aot. ( MonadLogger m , MonadIO m@@ -341,9 +331,9 @@ , V.Storable (Pcm channels S16) ) => V.Vector Word16- -> [Audio rate channels (Aac aot)]- -> AacEncT rate channels aot m [Audio rate channels (Aac aot)]-encodeSampleVector dIn acc+ -> [AacFrame rate channels aot]+ -> AacEncT rate channels aot m [AacFrame rate channels aot]+encodeAllFrames dIn acc | V.length dIn <= 0 = return [] | otherwise = do e <- ask@@ -352,7 +342,12 @@ Left err -> do $logError (fromString (printf "encoding failed: %s" (show err))) throwM err- Right fr -> returnAccOrEncodeAgain acc fr+ Right MkEncodeResultEof -> return (reverse acc)+ Right MkEncodeResult {encodeResultLeftOverInput, encodeResultSamples} -> do+ acc' <- appendNextFrame acc encodeResultSamples+ case encodeResultLeftOverInput of+ Nothing -> return (reverse acc')+ Just rest -> encodeAllFrames rest acc' -- | Flush any left over input and then also flush delay lines of the AAC encoder. flushAacEncoder@@ -364,47 +359,57 @@ , Show (AacAotProxy aot) , V.Storable (Pcm channels S16) )- => AacEncT r channels aot m [Audio r channels (Aac aot)]+ => AacEncT r channels aot m [AacFrame r channels aot] flushAacEncoder = do- d <- use numberOfDelayedSamples+ $logDebug "flushing"+ flushLoop []+ where+ flushLoop acc = do+ e <- ask+ eres <- liftIO $ flush e+ case eres of+ Left err -> do+ $logError (fromString (printf "flushing failed: %s" (show err)))+ throwM err+ Right MkEncodeResultEof -> do+ $logInfo "flushed"+ return (reverse acc)+ Right MkEncodeResult {encodeResultSamples} -> do+ acc' <- appendNextFrame acc encodeResultSamples+ flushUntilEof acc'++++-- | (Internal) Flush until the encoder returns the EOF return code.+flushUntilEof+ :: (MonadThrow m, MonadLogger m, MonadIO m)+ => [AacFrame r channels aot]+ -> AacEncT r channels aot m [AacFrame r channels aot]+flushUntilEof acc = do e <- ask- $logDebug (fromString (printf "flushing %d samples" d)) eres <- liftIO $ flush e case eres of Left err -> do $logError (fromString (printf "flushing failed: %s" (show err))) throwM err- Right fr -> do- $logInfo (fromString (printf "flushed frame: %s" (show fr)))- returnAccOrEncodeAgain [] fr+ Right MkEncodeResultEof -> do+ $logInfo "flushed"+ return (reverse acc)+ Right MkEncodeResult {encodeResultSamples} -> do+ acc' <- appendNextFrame acc encodeResultSamples+ flushUntilEof acc' --- | Internal function-returnAccOrEncodeAgain- :: ( MonadLogger m- , MonadIO m- , MonadThrow m- , KnownChannelLayout channels- , KnownRate rate- , Show (AacAotProxy aot)- , V.Storable (Pcm channels S16)- )- => [Audio rate channels (Aac aot)]- -> EncodeResult- -> AacEncT rate channels aot m [Audio rate channels (Aac aot)]-returnAccOrEncodeAgain acc MkEncodeResult { encodeResultLeftOverInput- , encodeResultSamples- , encodeResultConsumedFrames- } = do- numberOfDelayedSamples += encodeResultConsumedFrames- delayed <- use numberOfDelayedSamples- let acc' = maybe acc (\es -> MkAacFrame es encoded : acc) encodeResultSamples- encoded =- if isJust encodeResultSamples- then delayed- else 0- numberOfDelayedSamples -= encoded- case encodeResultLeftOverInput of- Nothing -> return (reverse acc')- Just rest -> encodeSampleVector rest acc'+-- | (Internal) Create a new 'Frame' and increment the sequence number and+-- update the timestamp from 'AacEncSt'+appendNextFrame+ :: Monad m+ => [AacFrame rate channels aot]+ -> Maybe (V.Vector Word8)+ -> AacEncT rate channels aot m [AacFrame rate channels aot]+appendNextFrame acc = maybe (return acc) (\es -> (: acc) <$> mkNextFrame es)+ where+ mkNextFrame es = do+ len <- fromIntegral <$> asks frameSize+ return (MkFrame () () (MkAacBuffer es len)) makeLenses ''AacEncoderInfo
src/Data/MediaBus/FdkAac/EncoderFdkWrapper.hs view
@@ -376,53 +376,56 @@ -> IO (Either EncodeFailure EncodeResult) toEncodeResult vec MkEncoder {unsafeOutBuffer, channelCount} ((numOutBytes, numInSamples, numAncBytes), retCode) = let retCode' = toAacEncErrorCode retCode- in- if retCode' /= AacEncOk && retCode' /= AacEncEncodeEof - then return $- Left- MkEncodeFailure- { encodeFailureCode = toAacEncErrorCode retCode- , encodeFailureNumOutBytes = fromIntegral numOutBytes- , encodeFailureNumInSamples = fromIntegral numInSamples- , encodeFailureNumAncBytes = fromIntegral numAncBytes- }- else do- let !numInSamplesI = fromIntegral numInSamples- !consumedFrames =- fromIntegral numInSamplesI `div` fromIntegral channelCount- !leftOverInput =- if numInSamplesI >= V.length vec- then Nothing- else let !inSliceLen = V.length vec - numInSamplesI- !inSlice = V.slice numInSamplesI inSliceLen vec- in Just inSlice- !numOutBytesI = fromIntegral numOutBytes- !encodedOutput <-- if numOutBytesI == 0- then return Nothing- else do- !outTooLarge <- V.freeze unsafeOutBuffer- return $ Just $ V.force $ V.slice 0 numOutBytesI outTooLarge- return $- Right- MkEncodeResult- { encodeResultConsumedFrames = consumedFrames- , encodeResultLeftOverInput = coerce leftOverInput- , encodeResultSamples = coerce encodedOutput- }+ in if retCode' == AacEncEncodeEof+ then return (Right MkEncodeResultEof)+ else if retCode' /= AacEncOk+ then return $+ Left+ MkEncodeFailure+ { encodeFailureCode = toAacEncErrorCode retCode+ , encodeFailureNumOutBytes = fromIntegral numOutBytes+ , encodeFailureNumInSamples = fromIntegral numInSamples+ , encodeFailureNumAncBytes = fromIntegral numAncBytes+ }+ else do+ let !numInSamplesI = fromIntegral numInSamples+ !consumedFrames =+ fromIntegral numInSamplesI `div` fromIntegral channelCount+ !leftOverInput =+ if numInSamplesI >= V.length vec+ then Nothing+ else let !inSliceLen = V.length vec - numInSamplesI+ !inSlice = V.slice numInSamplesI inSliceLen vec+ in Just inSlice+ !numOutBytesI = fromIntegral numOutBytes+ !encodedOutput <-+ if numOutBytesI == 0+ then return Nothing+ else do+ !outTooLarge <- V.freeze unsafeOutBuffer+ return $+ Just $ V.force $ V.slice 0 numOutBytesI outTooLarge+ return $+ Right+ MkEncodeResult+ { encodeResultConsumedFrames = consumedFrames+ , encodeResultLeftOverInput = coerce leftOverInput+ , encodeResultSamples = coerce encodedOutput+ } -- | Result of 'encode'-data EncodeResult = MkEncodeResult- { encodeResultConsumedFrames :: !Word64 -- ^ Number of samples from the input+data EncodeResult+ = MkEncodeResultEof+ | MkEncodeResult { encodeResultConsumedFrames :: !Word64 -- ^ Number of samples from the input -- that were processed by the encoder- , encodeResultLeftOverInput :: !(Maybe (V.Vector Word16)) -- ^ The unprocessed+ , encodeResultLeftOverInput :: !(Maybe (V.Vector Word16)) -- ^ The unprocessed -- rest of the input. -- Only if the input -- is larger than the -- encoders frame -- length a left over -- is returned.- , encodeResultSamples :: !(Maybe (V.Vector Word8)) -- ^ Encoded output. If less+ , encodeResultSamples :: !(Maybe (V.Vector Word8)) -- ^ Encoded output. If less -- than the frame length -- samples have been -- encoded, then the result@@ -432,9 +435,10 @@ -- representing the encded -- samples delayed by -- 'frameLength'.- }+ } instance Show EncodeResult where+ showsPrec _ MkEncodeResultEof = showString "encoder-EOF" showsPrec d MkEncodeResult { encodeResultConsumedFrames , encodeResultLeftOverInput , encodeResultSamples