, Dummy(..)
, DecorrTerms(..)
+ , DecorrWeights(..)
+ , DecorrSamples(..)
, RIFFHeader(..)
, RIFFTrailer(..)
, Unknown(..)
)
where
+import Codec.Audio.WavPack.Internal
import Control.Monad
import Data.Binary
import Data.Binary.Get
return $ runGet (getSubBlock rawID) subb
where
getSubBlock ∷ Word8 → Get SubBlock
- getSubBlock 0x00 = fmap SubBlock (get ∷ Get Dummy )
- getSubBlock 0x02 = fmap SubBlock (get ∷ Get DecorrTerms)
- getSubBlock 0x21 = fmap SubBlock (get ∷ Get RIFFHeader )
- getSubBlock 0x22 = fmap SubBlock (get ∷ Get RIFFTrailer)
+ getSubBlock 0x00 = fmap SubBlock (get ∷ Get Dummy )
+ getSubBlock 0x02 = fmap SubBlock (get ∷ Get DecorrTerms )
+ getSubBlock 0x03 = fmap SubBlock (get ∷ Get DecorrWeights)
+ getSubBlock 0x04 = fmap SubBlock (get ∷ Get DecorrSamples)
+ getSubBlock 0x21 = fmap SubBlock (get ∷ Get RIFFHeader )
+ getSubBlock 0x22 = fmap SubBlock (get ∷ Get RIFFTrailer )
getSubBlock unknownID
= if unknownID .&. 0x20 ≡ 0 then
fail ("Unknown WavPack metadata ID: " ⧺ show unknownID)
-- | Decorrelation terms and deltas.
data DecorrTerms
= DecorrTerms {
- -- | [ (term, delta) ]
+ -- | @[ (term, delta) ]@
dectVec ∷ !(UV.Vector (Int8, Int8))
}
deriving (Eq, Show, Typeable)
.|.
((δ `shiftL` 5) .&. 0xE0)
)
-
get = do n ← remaining
vec ← UV.replicateM (fromIntegral n) $ fmap unpackDT getWord8
-- THINKME: unpack.c(read_decorr_terms) reverses the
in
(term, δ)
+-- | Decorrelation weights.
+data DecorrWeights
+ = DecorrWeights {
+ -- | For mono blocks, this is a weight vector for the single
+ -- channel. For stereo blocks, it's interleaved as A, B, A, B,
+ -- ...
+ decwVec ∷ !(UV.Vector Int16)
+ }
+ deriving (Eq, Show, Typeable)
+
+instance Metadata DecorrWeights where
+ metaID _ = 0x03
+ metaSize = fromIntegral ∘ UV.length ∘ decwVec
+
+instance Binary DecorrWeights where
+ put = UV.mapM_ (putWord8 ∘ packWeight) ∘ decwVec
+ get = do n ← remaining
+ vec ← UV.replicateM (fromIntegral n)
+ $ fmap unpackWeight getWord8
+ -- THINKME: the same caution as DecorrTerms, but never
+ -- try to simply reverse the vector. Think about the
+ -- interleaving.
+ return $ DecorrWeights vec
+
+-- | Decorrelation samples
+data DecorrSamples
+ = DecorrSamples {
+ -- | The decorrelation sample vector stored in the metadata
+ -- as-is. Actual interpretation of the vector depends on the
+ -- number of channels and each corresponding decorrelation
+ -- terms.
+ decsVec ∷ !(UV.Vector Int32)
+ }
+ deriving (Eq, Show, Typeable)
+
+instance Metadata DecorrSamples where
+ metaID _ = 0x04
+ metaSize = fromIntegral ∘ (⋅ 2) ∘ UV.length ∘ decsVec
+
+instance Binary DecorrSamples where
+ put = UV.mapM_ (putWord16le ∘ fromIntegral ∘ log2s) ∘ decsVec
+ get = do n ← remaining
+ vec ← UV.replicateM (fromIntegral $ n `div` 2)
+ $ fmap (exp2s ∘ fromIntegral) getWord16le
+ return $ DecorrSamples vec
+
-- | RIFF header for .wav files (before audio)
data RIFFHeader
= RIFFHeader {