packages feed

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 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