+ get = do idWord ← getWord8
+ let isOdd = idWord .&. 0x40 ≢ 0
+ isLarge = idWord .&. 0x80 ≢ 0
+ rawID = idWord .&. (complement 0x40) .&. (complement 0x80)
+ adj = if isOdd then -1 else 0
+ size ← if isLarge then
+ do sz0 ← getWord8
+ sz1 ← getWord8
+ sz2 ← getWord8
+ return $ ( (fromIntegral sz2 `shiftL` 17) .|.
+ (fromIntegral sz1 `shiftL` 9) .|.
+ (fromIntegral sz0 `shiftL` 1)
+ ) + adj
+ else
+ fmap ((+ adj) ∘ (`shiftL` 1) ∘ fromIntegral) getWord8
+ subb ← getLazyByteString $ fromIntegral (size ∷ Word32)
+ return $ runGet (getSubBlock rawID) subb
+ where
+ getSubBlock ∷ Word8 → Get SubBlock
+ getSubBlock 0x00 = fmap SubBlock (get ∷ Get Dummy)
+ getSubBlock unknownID
+ = if unknownID .&. 0x20 ≡ 0 then
+ fail ("Unknown WavPack metadata ID: " ⧺ show unknownID)
+ else
+ -- It's unknown but optional. We can safely ignore it.
+ fmap (SubBlock ∘ Unknown unknownID) getRemainingLazyByteString