+-- | Configuration information.
+data ConfigInfo
+ = ConfigInfo {
+ -- | fast mode
+ cfgFast ∷ !Bool
+ -- | high quality mode
+ , cfgHigh ∷ !Bool
+ -- | very high
+ , cfgVeryHigh ∷ !Bool
+ -- | bitrate is kbps, not bits / sample
+ , cfgBitrateKbps ∷ !Bool
+ -- | automatic noise shaping
+ , cfgAutoShaping ∷ !Bool
+ -- | shaping mode specified
+ , cfgShapeOverride ∷ !Bool
+ -- | joint-stereo mode specified
+ , cfgJointOverride ∷ !Bool
+ -- | dynamic noise shaping
+ , cfgDynamicShaping ∷ !Bool
+ -- | create executable
+ , cfgCreateEXE ∷ !Bool
+ -- | create correction file
+ , cfgCreateWVC ∷ !Bool
+ -- | maximize hybrid compression
+ , cfgOptimizeWVC ∷ !Bool
+ -- | calc noise in hybrid mode
+ , cfgCalcNoise ∷ !Bool
+ -- | obsolete (for information)
+ , cfgLossyMode ∷ !Bool
+ -- | extra processing mode level (1-6)
+ , cfgExtraModeLevel ∷ !(S.Maybe Word8)
+ -- | no wvx stream w/ floats & big ints
+ , cfgSkipWVX ∷ !Bool
+ -- | compute & store MD5 signature
+ , cfgMD5Checksum ∷ !Bool
+ -- | merge blocks of equal redundancy
+ , cfgMergeBlocks ∷ !Bool
+ -- | optimize for mono streams posing
+ , cfgOptimizeMono ∷ !Bool
+ }
+ deriving (Eq, Show, Typeable)
+
+instance Metadata ConfigInfo where
+ metaID _ = 0x25
+ metaSize ci
+ | S.isJust $ cfgExtraModeLevel ci
+ = 4
+ | otherwise
+ = 3
+
+instance Binary ConfigInfo where
+ put ci
+ = let !bs = runBitPut $
+ do putBit $ cfgOptimizeMono ci
+ putNBits 2 (0 ∷ Word8) -- unused
+ putBit $ cfgMergeBlocks ci
+ putBit $ cfgMD5Checksum ci
+ putBit $ cfgSkipWVX ci
+ putBit $ S.isJust $ cfgExtraModeLevel ci
+ putBit $ cfgLossyMode ci
+ putBit $ cfgCalcNoise ci
+ putNBits 2 (0 ∷ Word8) -- unused
+ putBit $ cfgOptimizeWVC ci
+ putBit $ cfgCreateWVC ci
+ putBit $ cfgCreateEXE ci
+ putBit $ cfgDynamicShaping ci
+ putBit $ cfgJointOverride ci
+ putBit $ cfgShapeOverride ci
+ putBit $ cfgAutoShaping ci
+ putBit $ cfgBitrateKbps ci
+ putBit $ cfgVeryHigh ci
+ putBit $ cfgHigh ci
+ putBit False -- unused
+ putBit $ cfgFast ci
+ putBit False -- unused
+ in
+ do putLazyByteString (L.reverse bs)
+ case cfgExtraModeLevel ci of
+ S.Nothing → return ()
+ S.Just eml → putWord8 eml
+
+ get = do bs ← getBytes 3
+ eml ← do xmode ← fmap (¬) isEmpty
+ if xmode then
+ fmap S.Just getWord8
+ else
+ return S.Nothing
+ let r = runBitGet (S.reverse bs) $
+ do optimizeMono ← getBit
+ BG.skip 2 -- unused
+ mergeBlocks ← getBit
+ md5Checksum ← getBit
+ skipWVX ← getBit
+ extraMode ← getBit
+ lossyMode ← getBit
+ calcNoise ← getBit
+ BG.skip 2 -- unused
+ optimizeWVC ← getBit
+ createWVC ← getBit
+ createEXE ← getBit
+ dynamicShaping ← getBit
+ jointOverride ← getBit
+ shapeOverride ← getBit
+ autoShaping ← getBit
+ bitrateKbps ← getBit
+ veryHigh ← getBit
+ high ← getBit
+ BG.skip 1 -- unused
+ fast ← getBit
+ BG.skip 1 -- unused
+ return ConfigInfo {
+ cfgFast = fast
+ , cfgHigh = high
+ , cfgVeryHigh = veryHigh
+ , cfgBitrateKbps = bitrateKbps
+ , cfgAutoShaping = autoShaping
+ , cfgShapeOverride = shapeOverride
+ , cfgJointOverride = jointOverride
+ , cfgDynamicShaping = dynamicShaping
+ , cfgCreateEXE = createEXE
+ , cfgCreateWVC = createWVC
+ , cfgOptimizeWVC = optimizeWVC
+ , cfgCalcNoise = calcNoise
+ , cfgLossyMode = lossyMode
+ , cfgExtraModeLevel = if extraMode then
+ eml
+ else
+ S.Nothing
+ , cfgSkipWVX = skipWVX
+ , cfgMD5Checksum = md5Checksum
+ , cfgMergeBlocks = mergeBlocks
+ , cfgOptimizeMono = optimizeMono
+ }
+
+ case r of
+ Left err → fail err
+ Right ci → return ci
+