{-# LANGUAGE TemplateHaskell #-}

module Dahdit.Midi.Binary
  ( getTermText
  , putTermText
  , BoundedBinary (..)
  , MidiWord7 (..)
  , MidiInt7 (..)
  , MidiWord14 (..)
  , MidiInt14 (..)
  , VarWord (..)
  , Word14
  , Int14
  )
where

import Control.Newtype (Newtype (..))
import Dahdit (Binary (..), Get, Put, StaticByteSized (..), TermBytes8 (..), Word16BE (..), putText)
import Data.Bits (Bits (..))
import Data.ByteString.Short qualified as BSS
import Data.Hashable (Hashable)
import Data.Proxy (Proxy (..))
import Data.ShortWord (Int7, Word7)
import Data.ShortWord.TH (mkShortWord)
import Data.Text (Text)
import Data.Text.Encoding qualified as TE
import Data.Word (Word16, Word32, Word8)
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)

getTermText :: Get Text
getTermText :: Get Text
getTermText = do
  TermBytes8 ShortByteString
bs <- Get TermBytes8
forall a. Binary a => Get a
get
  case ByteString -> Either UnicodeException Text
TE.decodeUtf8' (ShortByteString -> ByteString
BSS.fromShort ShortByteString
bs) of
    Left UnicodeException
err -> String -> Get Text
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Invalid UTF-8: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnicodeException -> String
forall a. Show a => a -> String
show UnicodeException
err)
    Right Text
s -> Text -> Get Text
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
s

putTermText :: Text -> Put
putTermText :: Text -> Put
putTermText Text
s = Text -> Put
putText Text
s Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall a. Binary a => a -> Put
put @Word8 Word8
0

newtype BoundedBinary (s :: Symbol) a b = BoundedBinary {forall {k} (s :: Symbol) a (b :: k). BoundedBinary s a b -> a
unBoundedBinary :: a}

instance
  (KnownSymbol s, Bounded a, Ord a, Show a, Newtype a b, Binary b)
  => Binary (BoundedBinary s a b)
  where
  get :: Get (BoundedBinary s a b)
get = do
    b
w <- Get b
forall a. Binary a => Get a
get
    let v :: a
v = b -> a
forall n o. Newtype n o => o -> n
pack b
w
    if a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
|| a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
forall a. Bounded a => a
maxBound
      then String -> Get (BoundedBinary s a b)
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (Proxy s -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy s
forall {k} (t :: k). Proxy t
Proxy :: Proxy s) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value out of bounds: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v)
      else BoundedBinary s a b -> Get (BoundedBinary s a b)
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> BoundedBinary s a b
forall {k} (s :: Symbol) a (b :: k). a -> BoundedBinary s a b
BoundedBinary a
v)
  put :: BoundedBinary s a b -> Put
put = b -> Put
forall a. Binary a => a -> Put
put (b -> Put)
-> (BoundedBinary s a b -> b) -> BoundedBinary s a b -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall n o. Newtype n o => n -> o
unpack (a -> b) -> (BoundedBinary s a b -> a) -> BoundedBinary s a b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BoundedBinary s a b -> a
forall {k} (s :: Symbol) a (b :: k). BoundedBinary s a b -> a
unBoundedBinary

newtype MidiWord7 = MidiWord7 {MidiWord7 -> Word7
unMidiWord7 :: Word7}
  deriving stock (Int -> MidiWord7 -> String -> String
[MidiWord7] -> String -> String
MidiWord7 -> String
(Int -> MidiWord7 -> String -> String)
-> (MidiWord7 -> String)
-> ([MidiWord7] -> String -> String)
-> Show MidiWord7
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> MidiWord7 -> String -> String
showsPrec :: Int -> MidiWord7 -> String -> String
$cshow :: MidiWord7 -> String
show :: MidiWord7 -> String
$cshowList :: [MidiWord7] -> String -> String
showList :: [MidiWord7] -> String -> String
Show)
  deriving newtype (MidiWord7 -> MidiWord7 -> Bool
(MidiWord7 -> MidiWord7 -> Bool)
-> (MidiWord7 -> MidiWord7 -> Bool) -> Eq MidiWord7
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiWord7 -> MidiWord7 -> Bool
== :: MidiWord7 -> MidiWord7 -> Bool
$c/= :: MidiWord7 -> MidiWord7 -> Bool
/= :: MidiWord7 -> MidiWord7 -> Bool
Eq, Eq MidiWord7
Eq MidiWord7 =>
(MidiWord7 -> MidiWord7 -> Ordering)
-> (MidiWord7 -> MidiWord7 -> Bool)
-> (MidiWord7 -> MidiWord7 -> Bool)
-> (MidiWord7 -> MidiWord7 -> Bool)
-> (MidiWord7 -> MidiWord7 -> Bool)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> Ord MidiWord7
MidiWord7 -> MidiWord7 -> Bool
MidiWord7 -> MidiWord7 -> Ordering
MidiWord7 -> MidiWord7 -> MidiWord7
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiWord7 -> MidiWord7 -> Ordering
compare :: MidiWord7 -> MidiWord7 -> Ordering
$c< :: MidiWord7 -> MidiWord7 -> Bool
< :: MidiWord7 -> MidiWord7 -> Bool
$c<= :: MidiWord7 -> MidiWord7 -> Bool
<= :: MidiWord7 -> MidiWord7 -> Bool
$c> :: MidiWord7 -> MidiWord7 -> Bool
> :: MidiWord7 -> MidiWord7 -> Bool
$c>= :: MidiWord7 -> MidiWord7 -> Bool
>= :: MidiWord7 -> MidiWord7 -> Bool
$cmax :: MidiWord7 -> MidiWord7 -> MidiWord7
max :: MidiWord7 -> MidiWord7 -> MidiWord7
$cmin :: MidiWord7 -> MidiWord7 -> MidiWord7
min :: MidiWord7 -> MidiWord7 -> MidiWord7
Ord, Int -> MidiWord7
MidiWord7 -> Int
MidiWord7 -> [MidiWord7]
MidiWord7 -> MidiWord7
MidiWord7 -> MidiWord7 -> [MidiWord7]
MidiWord7 -> MidiWord7 -> MidiWord7 -> [MidiWord7]
(MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7)
-> (Int -> MidiWord7)
-> (MidiWord7 -> Int)
-> (MidiWord7 -> [MidiWord7])
-> (MidiWord7 -> MidiWord7 -> [MidiWord7])
-> (MidiWord7 -> MidiWord7 -> [MidiWord7])
-> (MidiWord7 -> MidiWord7 -> MidiWord7 -> [MidiWord7])
-> Enum MidiWord7
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MidiWord7 -> MidiWord7
succ :: MidiWord7 -> MidiWord7
$cpred :: MidiWord7 -> MidiWord7
pred :: MidiWord7 -> MidiWord7
$ctoEnum :: Int -> MidiWord7
toEnum :: Int -> MidiWord7
$cfromEnum :: MidiWord7 -> Int
fromEnum :: MidiWord7 -> Int
$cenumFrom :: MidiWord7 -> [MidiWord7]
enumFrom :: MidiWord7 -> [MidiWord7]
$cenumFromThen :: MidiWord7 -> MidiWord7 -> [MidiWord7]
enumFromThen :: MidiWord7 -> MidiWord7 -> [MidiWord7]
$cenumFromTo :: MidiWord7 -> MidiWord7 -> [MidiWord7]
enumFromTo :: MidiWord7 -> MidiWord7 -> [MidiWord7]
$cenumFromThenTo :: MidiWord7 -> MidiWord7 -> MidiWord7 -> [MidiWord7]
enumFromThenTo :: MidiWord7 -> MidiWord7 -> MidiWord7 -> [MidiWord7]
Enum, MidiWord7
MidiWord7 -> MidiWord7 -> Bounded MidiWord7
forall a. a -> a -> Bounded a
$cminBound :: MidiWord7
minBound :: MidiWord7
$cmaxBound :: MidiWord7
maxBound :: MidiWord7
Bounded, Integer -> MidiWord7
MidiWord7 -> MidiWord7
MidiWord7 -> MidiWord7 -> MidiWord7
(MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7)
-> (Integer -> MidiWord7)
-> Num MidiWord7
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: MidiWord7 -> MidiWord7 -> MidiWord7
+ :: MidiWord7 -> MidiWord7 -> MidiWord7
$c- :: MidiWord7 -> MidiWord7 -> MidiWord7
- :: MidiWord7 -> MidiWord7 -> MidiWord7
$c* :: MidiWord7 -> MidiWord7 -> MidiWord7
* :: MidiWord7 -> MidiWord7 -> MidiWord7
$cnegate :: MidiWord7 -> MidiWord7
negate :: MidiWord7 -> MidiWord7
$cabs :: MidiWord7 -> MidiWord7
abs :: MidiWord7 -> MidiWord7
$csignum :: MidiWord7 -> MidiWord7
signum :: MidiWord7 -> MidiWord7
$cfromInteger :: Integer -> MidiWord7
fromInteger :: Integer -> MidiWord7
Num, Num MidiWord7
Ord MidiWord7
(Num MidiWord7, Ord MidiWord7) =>
(MidiWord7 -> Rational) -> Real MidiWord7
MidiWord7 -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: MidiWord7 -> Rational
toRational :: MidiWord7 -> Rational
Real, Enum MidiWord7
Real MidiWord7
(Real MidiWord7, Enum MidiWord7) =>
(MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> MidiWord7)
-> (MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7))
-> (MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7))
-> (MidiWord7 -> Integer)
-> Integral MidiWord7
MidiWord7 -> Integer
MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7)
MidiWord7 -> MidiWord7 -> MidiWord7
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: MidiWord7 -> MidiWord7 -> MidiWord7
quot :: MidiWord7 -> MidiWord7 -> MidiWord7
$crem :: MidiWord7 -> MidiWord7 -> MidiWord7
rem :: MidiWord7 -> MidiWord7 -> MidiWord7
$cdiv :: MidiWord7 -> MidiWord7 -> MidiWord7
div :: MidiWord7 -> MidiWord7 -> MidiWord7
$cmod :: MidiWord7 -> MidiWord7 -> MidiWord7
mod :: MidiWord7 -> MidiWord7 -> MidiWord7
$cquotRem :: MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7)
quotRem :: MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7)
$cdivMod :: MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7)
divMod :: MidiWord7 -> MidiWord7 -> (MidiWord7, MidiWord7)
$ctoInteger :: MidiWord7 -> Integer
toInteger :: MidiWord7 -> Integer
Integral, Eq MidiWord7
Eq MidiWord7 =>
(Int -> MidiWord7 -> Int)
-> (MidiWord7 -> Int) -> Hashable MidiWord7
Int -> MidiWord7 -> Int
MidiWord7 -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> MidiWord7 -> Int
hashWithSalt :: Int -> MidiWord7 -> Int
$chash :: MidiWord7 -> Int
hash :: MidiWord7 -> Int
Hashable)

instance StaticByteSized MidiWord7 where
  type StaticSize MidiWord7 = 1
  staticByteSize :: Proxy MidiWord7 -> ByteCount
staticByteSize Proxy MidiWord7
_ = ByteCount
1

instance Binary MidiWord7 where
  byteSize :: MidiWord7 -> ByteCount
byteSize MidiWord7
_ = ByteCount
1
  get :: Get MidiWord7
get = do
    Word8
w <- forall a. Binary a => Get a
get @Word8
    if Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x80 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
      then MidiWord7 -> Get MidiWord7
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word7 -> MidiWord7
MidiWord7 (Word8 -> Word7
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w))
      else String -> Get MidiWord7
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Word7 high bit set: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
w)
  put :: MidiWord7 -> Put
put MidiWord7
v = forall a. Binary a => a -> Put
put @Word8 (Word8
0x7F Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word7 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (MidiWord7 -> Word7
unMidiWord7 MidiWord7
v))

newtype MidiInt7 = MidiInt7 {MidiInt7 -> Int7
unMidiInt7 :: Int7}
  deriving stock (Int -> MidiInt7 -> String -> String
[MidiInt7] -> String -> String
MidiInt7 -> String
(Int -> MidiInt7 -> String -> String)
-> (MidiInt7 -> String)
-> ([MidiInt7] -> String -> String)
-> Show MidiInt7
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> MidiInt7 -> String -> String
showsPrec :: Int -> MidiInt7 -> String -> String
$cshow :: MidiInt7 -> String
show :: MidiInt7 -> String
$cshowList :: [MidiInt7] -> String -> String
showList :: [MidiInt7] -> String -> String
Show)
  deriving newtype (MidiInt7 -> MidiInt7 -> Bool
(MidiInt7 -> MidiInt7 -> Bool)
-> (MidiInt7 -> MidiInt7 -> Bool) -> Eq MidiInt7
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiInt7 -> MidiInt7 -> Bool
== :: MidiInt7 -> MidiInt7 -> Bool
$c/= :: MidiInt7 -> MidiInt7 -> Bool
/= :: MidiInt7 -> MidiInt7 -> Bool
Eq, Eq MidiInt7
Eq MidiInt7 =>
(MidiInt7 -> MidiInt7 -> Ordering)
-> (MidiInt7 -> MidiInt7 -> Bool)
-> (MidiInt7 -> MidiInt7 -> Bool)
-> (MidiInt7 -> MidiInt7 -> Bool)
-> (MidiInt7 -> MidiInt7 -> Bool)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> Ord MidiInt7
MidiInt7 -> MidiInt7 -> Bool
MidiInt7 -> MidiInt7 -> Ordering
MidiInt7 -> MidiInt7 -> MidiInt7
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiInt7 -> MidiInt7 -> Ordering
compare :: MidiInt7 -> MidiInt7 -> Ordering
$c< :: MidiInt7 -> MidiInt7 -> Bool
< :: MidiInt7 -> MidiInt7 -> Bool
$c<= :: MidiInt7 -> MidiInt7 -> Bool
<= :: MidiInt7 -> MidiInt7 -> Bool
$c> :: MidiInt7 -> MidiInt7 -> Bool
> :: MidiInt7 -> MidiInt7 -> Bool
$c>= :: MidiInt7 -> MidiInt7 -> Bool
>= :: MidiInt7 -> MidiInt7 -> Bool
$cmax :: MidiInt7 -> MidiInt7 -> MidiInt7
max :: MidiInt7 -> MidiInt7 -> MidiInt7
$cmin :: MidiInt7 -> MidiInt7 -> MidiInt7
min :: MidiInt7 -> MidiInt7 -> MidiInt7
Ord, Int -> MidiInt7
MidiInt7 -> Int
MidiInt7 -> [MidiInt7]
MidiInt7 -> MidiInt7
MidiInt7 -> MidiInt7 -> [MidiInt7]
MidiInt7 -> MidiInt7 -> MidiInt7 -> [MidiInt7]
(MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7)
-> (Int -> MidiInt7)
-> (MidiInt7 -> Int)
-> (MidiInt7 -> [MidiInt7])
-> (MidiInt7 -> MidiInt7 -> [MidiInt7])
-> (MidiInt7 -> MidiInt7 -> [MidiInt7])
-> (MidiInt7 -> MidiInt7 -> MidiInt7 -> [MidiInt7])
-> Enum MidiInt7
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MidiInt7 -> MidiInt7
succ :: MidiInt7 -> MidiInt7
$cpred :: MidiInt7 -> MidiInt7
pred :: MidiInt7 -> MidiInt7
$ctoEnum :: Int -> MidiInt7
toEnum :: Int -> MidiInt7
$cfromEnum :: MidiInt7 -> Int
fromEnum :: MidiInt7 -> Int
$cenumFrom :: MidiInt7 -> [MidiInt7]
enumFrom :: MidiInt7 -> [MidiInt7]
$cenumFromThen :: MidiInt7 -> MidiInt7 -> [MidiInt7]
enumFromThen :: MidiInt7 -> MidiInt7 -> [MidiInt7]
$cenumFromTo :: MidiInt7 -> MidiInt7 -> [MidiInt7]
enumFromTo :: MidiInt7 -> MidiInt7 -> [MidiInt7]
$cenumFromThenTo :: MidiInt7 -> MidiInt7 -> MidiInt7 -> [MidiInt7]
enumFromThenTo :: MidiInt7 -> MidiInt7 -> MidiInt7 -> [MidiInt7]
Enum, MidiInt7
MidiInt7 -> MidiInt7 -> Bounded MidiInt7
forall a. a -> a -> Bounded a
$cminBound :: MidiInt7
minBound :: MidiInt7
$cmaxBound :: MidiInt7
maxBound :: MidiInt7
Bounded, Integer -> MidiInt7
MidiInt7 -> MidiInt7
MidiInt7 -> MidiInt7 -> MidiInt7
(MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7)
-> (Integer -> MidiInt7)
-> Num MidiInt7
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: MidiInt7 -> MidiInt7 -> MidiInt7
+ :: MidiInt7 -> MidiInt7 -> MidiInt7
$c- :: MidiInt7 -> MidiInt7 -> MidiInt7
- :: MidiInt7 -> MidiInt7 -> MidiInt7
$c* :: MidiInt7 -> MidiInt7 -> MidiInt7
* :: MidiInt7 -> MidiInt7 -> MidiInt7
$cnegate :: MidiInt7 -> MidiInt7
negate :: MidiInt7 -> MidiInt7
$cabs :: MidiInt7 -> MidiInt7
abs :: MidiInt7 -> MidiInt7
$csignum :: MidiInt7 -> MidiInt7
signum :: MidiInt7 -> MidiInt7
$cfromInteger :: Integer -> MidiInt7
fromInteger :: Integer -> MidiInt7
Num, Num MidiInt7
Ord MidiInt7
(Num MidiInt7, Ord MidiInt7) =>
(MidiInt7 -> Rational) -> Real MidiInt7
MidiInt7 -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: MidiInt7 -> Rational
toRational :: MidiInt7 -> Rational
Real, Enum MidiInt7
Real MidiInt7
(Real MidiInt7, Enum MidiInt7) =>
(MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> MidiInt7)
-> (MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7))
-> (MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7))
-> (MidiInt7 -> Integer)
-> Integral MidiInt7
MidiInt7 -> Integer
MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7)
MidiInt7 -> MidiInt7 -> MidiInt7
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: MidiInt7 -> MidiInt7 -> MidiInt7
quot :: MidiInt7 -> MidiInt7 -> MidiInt7
$crem :: MidiInt7 -> MidiInt7 -> MidiInt7
rem :: MidiInt7 -> MidiInt7 -> MidiInt7
$cdiv :: MidiInt7 -> MidiInt7 -> MidiInt7
div :: MidiInt7 -> MidiInt7 -> MidiInt7
$cmod :: MidiInt7 -> MidiInt7 -> MidiInt7
mod :: MidiInt7 -> MidiInt7 -> MidiInt7
$cquotRem :: MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7)
quotRem :: MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7)
$cdivMod :: MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7)
divMod :: MidiInt7 -> MidiInt7 -> (MidiInt7, MidiInt7)
$ctoInteger :: MidiInt7 -> Integer
toInteger :: MidiInt7 -> Integer
Integral, Eq MidiInt7
Eq MidiInt7 =>
(Int -> MidiInt7 -> Int) -> (MidiInt7 -> Int) -> Hashable MidiInt7
Int -> MidiInt7 -> Int
MidiInt7 -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> MidiInt7 -> Int
hashWithSalt :: Int -> MidiInt7 -> Int
$chash :: MidiInt7 -> Int
hash :: MidiInt7 -> Int
Hashable)

instance StaticByteSized MidiInt7 where
  type StaticSize MidiInt7 = 1
  staticByteSize :: Proxy MidiInt7 -> ByteCount
staticByteSize Proxy MidiInt7
_ = ByteCount
1

instance Binary MidiInt7 where
  byteSize :: MidiInt7 -> ByteCount
byteSize MidiInt7
_ = ByteCount
1
  get :: Get MidiInt7
get = do
    Word8
w <- forall a. Binary a => Get a
get @Word8
    if Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x80 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
      then MidiInt7 -> Get MidiInt7
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int7 -> MidiInt7
MidiInt7 (Word8 -> Int7
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w))
      else String -> Get MidiInt7
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Int7 high bit set: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
w)
  put :: MidiInt7 -> Put
put MidiInt7
v = forall a. Binary a => a -> Put
put @Word8 (Word8
0x7F Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Int7 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (MidiInt7 -> Int7
unMidiInt7 MidiInt7
v))

mkShortWord "Word14" "Word14" "aWord14" "Int14" "Int14" "anInt14" ''Word16 14 []

expandW14 :: Word14 -> Word16
expandW14 :: Word14 -> Word16
expandW14 Word14
w =
  let x :: Word16
x = Word14 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word14
w :: Word16
      xLo :: Word16
xLo = Word16
x Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0x007F
      xHi :: Word16
xHi = Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL Word16
x Int
1 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0x7F00
  in  Word16
xHi Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16
xLo

contractW14 :: Word16 -> Word14
contractW14 :: Word16 -> Word14
contractW14 Word16
v =
  let vLo :: Word16
vLo = Word16
v Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0x007F
      vHi :: Word16
vHi = Word16
v Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0x7F00
      x :: Word16
x = Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
vHi Int
1 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16
vLo
  in  Word16 -> Word14
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
x

newtype MidiWord14 = MidiWord14 {MidiWord14 -> Word14
unMidiWord14 :: Word14}
  deriving stock (Int -> MidiWord14 -> String -> String
[MidiWord14] -> String -> String
MidiWord14 -> String
(Int -> MidiWord14 -> String -> String)
-> (MidiWord14 -> String)
-> ([MidiWord14] -> String -> String)
-> Show MidiWord14
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> MidiWord14 -> String -> String
showsPrec :: Int -> MidiWord14 -> String -> String
$cshow :: MidiWord14 -> String
show :: MidiWord14 -> String
$cshowList :: [MidiWord14] -> String -> String
showList :: [MidiWord14] -> String -> String
Show)
  deriving newtype (MidiWord14 -> MidiWord14 -> Bool
(MidiWord14 -> MidiWord14 -> Bool)
-> (MidiWord14 -> MidiWord14 -> Bool) -> Eq MidiWord14
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiWord14 -> MidiWord14 -> Bool
== :: MidiWord14 -> MidiWord14 -> Bool
$c/= :: MidiWord14 -> MidiWord14 -> Bool
/= :: MidiWord14 -> MidiWord14 -> Bool
Eq, Eq MidiWord14
Eq MidiWord14 =>
(MidiWord14 -> MidiWord14 -> Ordering)
-> (MidiWord14 -> MidiWord14 -> Bool)
-> (MidiWord14 -> MidiWord14 -> Bool)
-> (MidiWord14 -> MidiWord14 -> Bool)
-> (MidiWord14 -> MidiWord14 -> Bool)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> Ord MidiWord14
MidiWord14 -> MidiWord14 -> Bool
MidiWord14 -> MidiWord14 -> Ordering
MidiWord14 -> MidiWord14 -> MidiWord14
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiWord14 -> MidiWord14 -> Ordering
compare :: MidiWord14 -> MidiWord14 -> Ordering
$c< :: MidiWord14 -> MidiWord14 -> Bool
< :: MidiWord14 -> MidiWord14 -> Bool
$c<= :: MidiWord14 -> MidiWord14 -> Bool
<= :: MidiWord14 -> MidiWord14 -> Bool
$c> :: MidiWord14 -> MidiWord14 -> Bool
> :: MidiWord14 -> MidiWord14 -> Bool
$c>= :: MidiWord14 -> MidiWord14 -> Bool
>= :: MidiWord14 -> MidiWord14 -> Bool
$cmax :: MidiWord14 -> MidiWord14 -> MidiWord14
max :: MidiWord14 -> MidiWord14 -> MidiWord14
$cmin :: MidiWord14 -> MidiWord14 -> MidiWord14
min :: MidiWord14 -> MidiWord14 -> MidiWord14
Ord, Int -> MidiWord14
MidiWord14 -> Int
MidiWord14 -> [MidiWord14]
MidiWord14 -> MidiWord14
MidiWord14 -> MidiWord14 -> [MidiWord14]
MidiWord14 -> MidiWord14 -> MidiWord14 -> [MidiWord14]
(MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14)
-> (Int -> MidiWord14)
-> (MidiWord14 -> Int)
-> (MidiWord14 -> [MidiWord14])
-> (MidiWord14 -> MidiWord14 -> [MidiWord14])
-> (MidiWord14 -> MidiWord14 -> [MidiWord14])
-> (MidiWord14 -> MidiWord14 -> MidiWord14 -> [MidiWord14])
-> Enum MidiWord14
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MidiWord14 -> MidiWord14
succ :: MidiWord14 -> MidiWord14
$cpred :: MidiWord14 -> MidiWord14
pred :: MidiWord14 -> MidiWord14
$ctoEnum :: Int -> MidiWord14
toEnum :: Int -> MidiWord14
$cfromEnum :: MidiWord14 -> Int
fromEnum :: MidiWord14 -> Int
$cenumFrom :: MidiWord14 -> [MidiWord14]
enumFrom :: MidiWord14 -> [MidiWord14]
$cenumFromThen :: MidiWord14 -> MidiWord14 -> [MidiWord14]
enumFromThen :: MidiWord14 -> MidiWord14 -> [MidiWord14]
$cenumFromTo :: MidiWord14 -> MidiWord14 -> [MidiWord14]
enumFromTo :: MidiWord14 -> MidiWord14 -> [MidiWord14]
$cenumFromThenTo :: MidiWord14 -> MidiWord14 -> MidiWord14 -> [MidiWord14]
enumFromThenTo :: MidiWord14 -> MidiWord14 -> MidiWord14 -> [MidiWord14]
Enum, MidiWord14
MidiWord14 -> MidiWord14 -> Bounded MidiWord14
forall a. a -> a -> Bounded a
$cminBound :: MidiWord14
minBound :: MidiWord14
$cmaxBound :: MidiWord14
maxBound :: MidiWord14
Bounded, Integer -> MidiWord14
MidiWord14 -> MidiWord14
MidiWord14 -> MidiWord14 -> MidiWord14
(MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14)
-> (Integer -> MidiWord14)
-> Num MidiWord14
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: MidiWord14 -> MidiWord14 -> MidiWord14
+ :: MidiWord14 -> MidiWord14 -> MidiWord14
$c- :: MidiWord14 -> MidiWord14 -> MidiWord14
- :: MidiWord14 -> MidiWord14 -> MidiWord14
$c* :: MidiWord14 -> MidiWord14 -> MidiWord14
* :: MidiWord14 -> MidiWord14 -> MidiWord14
$cnegate :: MidiWord14 -> MidiWord14
negate :: MidiWord14 -> MidiWord14
$cabs :: MidiWord14 -> MidiWord14
abs :: MidiWord14 -> MidiWord14
$csignum :: MidiWord14 -> MidiWord14
signum :: MidiWord14 -> MidiWord14
$cfromInteger :: Integer -> MidiWord14
fromInteger :: Integer -> MidiWord14
Num, Num MidiWord14
Ord MidiWord14
(Num MidiWord14, Ord MidiWord14) =>
(MidiWord14 -> Rational) -> Real MidiWord14
MidiWord14 -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: MidiWord14 -> Rational
toRational :: MidiWord14 -> Rational
Real, Enum MidiWord14
Real MidiWord14
(Real MidiWord14, Enum MidiWord14) =>
(MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> MidiWord14)
-> (MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14))
-> (MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14))
-> (MidiWord14 -> Integer)
-> Integral MidiWord14
MidiWord14 -> Integer
MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14)
MidiWord14 -> MidiWord14 -> MidiWord14
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: MidiWord14 -> MidiWord14 -> MidiWord14
quot :: MidiWord14 -> MidiWord14 -> MidiWord14
$crem :: MidiWord14 -> MidiWord14 -> MidiWord14
rem :: MidiWord14 -> MidiWord14 -> MidiWord14
$cdiv :: MidiWord14 -> MidiWord14 -> MidiWord14
div :: MidiWord14 -> MidiWord14 -> MidiWord14
$cmod :: MidiWord14 -> MidiWord14 -> MidiWord14
mod :: MidiWord14 -> MidiWord14 -> MidiWord14
$cquotRem :: MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14)
quotRem :: MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14)
$cdivMod :: MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14)
divMod :: MidiWord14 -> MidiWord14 -> (MidiWord14, MidiWord14)
$ctoInteger :: MidiWord14 -> Integer
toInteger :: MidiWord14 -> Integer
Integral, Eq MidiWord14
Eq MidiWord14 =>
(Int -> MidiWord14 -> Int)
-> (MidiWord14 -> Int) -> Hashable MidiWord14
Int -> MidiWord14 -> Int
MidiWord14 -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> MidiWord14 -> Int
hashWithSalt :: Int -> MidiWord14 -> Int
$chash :: MidiWord14 -> Int
hash :: MidiWord14 -> Int
Hashable)

instance StaticByteSized MidiWord14 where
  type StaticSize MidiWord14 = 2
  staticByteSize :: Proxy MidiWord14 -> ByteCount
staticByteSize Proxy MidiWord14
_ = ByteCount
2

instance Binary MidiWord14 where
  byteSize :: MidiWord14 -> ByteCount
byteSize MidiWord14
_ = ByteCount
2
  get :: Get MidiWord14
get = (Word16BE -> MidiWord14) -> Get Word16BE -> Get MidiWord14
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word14 -> MidiWord14
MidiWord14 (Word14 -> MidiWord14)
-> (Word16BE -> Word14) -> Word16BE -> MidiWord14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Word14
contractW14 (Word16 -> Word14) -> (Word16BE -> Word16) -> Word16BE -> Word14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16BE -> Word16
unWord16BE) Get Word16BE
forall a. Binary a => Get a
get
  put :: MidiWord14 -> Put
put = Word16BE -> Put
forall a. Binary a => a -> Put
put (Word16BE -> Put) -> (MidiWord14 -> Word16BE) -> MidiWord14 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Word16BE
Word16BE (Word16 -> Word16BE)
-> (MidiWord14 -> Word16) -> MidiWord14 -> Word16BE
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word14 -> Word16
expandW14 (Word14 -> Word16)
-> (MidiWord14 -> Word14) -> MidiWord14 -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MidiWord14 -> Word14
unMidiWord14

newtype MidiInt14 = MidiInt14 {MidiInt14 -> Int14
unMidiInt14 :: Int14}
  deriving stock (Int -> MidiInt14 -> String -> String
[MidiInt14] -> String -> String
MidiInt14 -> String
(Int -> MidiInt14 -> String -> String)
-> (MidiInt14 -> String)
-> ([MidiInt14] -> String -> String)
-> Show MidiInt14
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> MidiInt14 -> String -> String
showsPrec :: Int -> MidiInt14 -> String -> String
$cshow :: MidiInt14 -> String
show :: MidiInt14 -> String
$cshowList :: [MidiInt14] -> String -> String
showList :: [MidiInt14] -> String -> String
Show)
  deriving newtype (MidiInt14 -> MidiInt14 -> Bool
(MidiInt14 -> MidiInt14 -> Bool)
-> (MidiInt14 -> MidiInt14 -> Bool) -> Eq MidiInt14
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiInt14 -> MidiInt14 -> Bool
== :: MidiInt14 -> MidiInt14 -> Bool
$c/= :: MidiInt14 -> MidiInt14 -> Bool
/= :: MidiInt14 -> MidiInt14 -> Bool
Eq, Eq MidiInt14
Eq MidiInt14 =>
(MidiInt14 -> MidiInt14 -> Ordering)
-> (MidiInt14 -> MidiInt14 -> Bool)
-> (MidiInt14 -> MidiInt14 -> Bool)
-> (MidiInt14 -> MidiInt14 -> Bool)
-> (MidiInt14 -> MidiInt14 -> Bool)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> Ord MidiInt14
MidiInt14 -> MidiInt14 -> Bool
MidiInt14 -> MidiInt14 -> Ordering
MidiInt14 -> MidiInt14 -> MidiInt14
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiInt14 -> MidiInt14 -> Ordering
compare :: MidiInt14 -> MidiInt14 -> Ordering
$c< :: MidiInt14 -> MidiInt14 -> Bool
< :: MidiInt14 -> MidiInt14 -> Bool
$c<= :: MidiInt14 -> MidiInt14 -> Bool
<= :: MidiInt14 -> MidiInt14 -> Bool
$c> :: MidiInt14 -> MidiInt14 -> Bool
> :: MidiInt14 -> MidiInt14 -> Bool
$c>= :: MidiInt14 -> MidiInt14 -> Bool
>= :: MidiInt14 -> MidiInt14 -> Bool
$cmax :: MidiInt14 -> MidiInt14 -> MidiInt14
max :: MidiInt14 -> MidiInt14 -> MidiInt14
$cmin :: MidiInt14 -> MidiInt14 -> MidiInt14
min :: MidiInt14 -> MidiInt14 -> MidiInt14
Ord, Int -> MidiInt14
MidiInt14 -> Int
MidiInt14 -> [MidiInt14]
MidiInt14 -> MidiInt14
MidiInt14 -> MidiInt14 -> [MidiInt14]
MidiInt14 -> MidiInt14 -> MidiInt14 -> [MidiInt14]
(MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14)
-> (Int -> MidiInt14)
-> (MidiInt14 -> Int)
-> (MidiInt14 -> [MidiInt14])
-> (MidiInt14 -> MidiInt14 -> [MidiInt14])
-> (MidiInt14 -> MidiInt14 -> [MidiInt14])
-> (MidiInt14 -> MidiInt14 -> MidiInt14 -> [MidiInt14])
-> Enum MidiInt14
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MidiInt14 -> MidiInt14
succ :: MidiInt14 -> MidiInt14
$cpred :: MidiInt14 -> MidiInt14
pred :: MidiInt14 -> MidiInt14
$ctoEnum :: Int -> MidiInt14
toEnum :: Int -> MidiInt14
$cfromEnum :: MidiInt14 -> Int
fromEnum :: MidiInt14 -> Int
$cenumFrom :: MidiInt14 -> [MidiInt14]
enumFrom :: MidiInt14 -> [MidiInt14]
$cenumFromThen :: MidiInt14 -> MidiInt14 -> [MidiInt14]
enumFromThen :: MidiInt14 -> MidiInt14 -> [MidiInt14]
$cenumFromTo :: MidiInt14 -> MidiInt14 -> [MidiInt14]
enumFromTo :: MidiInt14 -> MidiInt14 -> [MidiInt14]
$cenumFromThenTo :: MidiInt14 -> MidiInt14 -> MidiInt14 -> [MidiInt14]
enumFromThenTo :: MidiInt14 -> MidiInt14 -> MidiInt14 -> [MidiInt14]
Enum, MidiInt14
MidiInt14 -> MidiInt14 -> Bounded MidiInt14
forall a. a -> a -> Bounded a
$cminBound :: MidiInt14
minBound :: MidiInt14
$cmaxBound :: MidiInt14
maxBound :: MidiInt14
Bounded, Integer -> MidiInt14
MidiInt14 -> MidiInt14
MidiInt14 -> MidiInt14 -> MidiInt14
(MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14)
-> (Integer -> MidiInt14)
-> Num MidiInt14
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: MidiInt14 -> MidiInt14 -> MidiInt14
+ :: MidiInt14 -> MidiInt14 -> MidiInt14
$c- :: MidiInt14 -> MidiInt14 -> MidiInt14
- :: MidiInt14 -> MidiInt14 -> MidiInt14
$c* :: MidiInt14 -> MidiInt14 -> MidiInt14
* :: MidiInt14 -> MidiInt14 -> MidiInt14
$cnegate :: MidiInt14 -> MidiInt14
negate :: MidiInt14 -> MidiInt14
$cabs :: MidiInt14 -> MidiInt14
abs :: MidiInt14 -> MidiInt14
$csignum :: MidiInt14 -> MidiInt14
signum :: MidiInt14 -> MidiInt14
$cfromInteger :: Integer -> MidiInt14
fromInteger :: Integer -> MidiInt14
Num, Num MidiInt14
Ord MidiInt14
(Num MidiInt14, Ord MidiInt14) =>
(MidiInt14 -> Rational) -> Real MidiInt14
MidiInt14 -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: MidiInt14 -> Rational
toRational :: MidiInt14 -> Rational
Real, Enum MidiInt14
Real MidiInt14
(Real MidiInt14, Enum MidiInt14) =>
(MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> MidiInt14)
-> (MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14))
-> (MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14))
-> (MidiInt14 -> Integer)
-> Integral MidiInt14
MidiInt14 -> Integer
MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14)
MidiInt14 -> MidiInt14 -> MidiInt14
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: MidiInt14 -> MidiInt14 -> MidiInt14
quot :: MidiInt14 -> MidiInt14 -> MidiInt14
$crem :: MidiInt14 -> MidiInt14 -> MidiInt14
rem :: MidiInt14 -> MidiInt14 -> MidiInt14
$cdiv :: MidiInt14 -> MidiInt14 -> MidiInt14
div :: MidiInt14 -> MidiInt14 -> MidiInt14
$cmod :: MidiInt14 -> MidiInt14 -> MidiInt14
mod :: MidiInt14 -> MidiInt14 -> MidiInt14
$cquotRem :: MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14)
quotRem :: MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14)
$cdivMod :: MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14)
divMod :: MidiInt14 -> MidiInt14 -> (MidiInt14, MidiInt14)
$ctoInteger :: MidiInt14 -> Integer
toInteger :: MidiInt14 -> Integer
Integral, Eq MidiInt14
Eq MidiInt14 =>
(Int -> MidiInt14 -> Int)
-> (MidiInt14 -> Int) -> Hashable MidiInt14
Int -> MidiInt14 -> Int
MidiInt14 -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> MidiInt14 -> Int
hashWithSalt :: Int -> MidiInt14 -> Int
$chash :: MidiInt14 -> Int
hash :: MidiInt14 -> Int
Hashable)

instance StaticByteSized MidiInt14 where
  type StaticSize MidiInt14 = 2
  staticByteSize :: Proxy MidiInt14 -> ByteCount
staticByteSize Proxy MidiInt14
_ = ByteCount
2

instance Binary MidiInt14 where
  byteSize :: MidiInt14 -> ByteCount
byteSize MidiInt14
_ = ByteCount
2
  get :: Get MidiInt14
get = (Word16BE -> MidiInt14) -> Get Word16BE -> Get MidiInt14
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int14 -> MidiInt14
MidiInt14 (Int14 -> MidiInt14)
-> (Word16BE -> Int14) -> Word16BE -> MidiInt14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word14 -> Int14
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word14 -> Int14) -> (Word16BE -> Word14) -> Word16BE -> Int14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Word14
contractW14 (Word16 -> Word14) -> (Word16BE -> Word16) -> Word16BE -> Word14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16BE -> Word16
unWord16BE) Get Word16BE
forall a. Binary a => Get a
get
  put :: MidiInt14 -> Put
put = Word16BE -> Put
forall a. Binary a => a -> Put
put (Word16BE -> Put) -> (MidiInt14 -> Word16BE) -> MidiInt14 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Word16BE
Word16BE (Word16 -> Word16BE)
-> (MidiInt14 -> Word16) -> MidiInt14 -> Word16BE
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word14 -> Word16
expandW14 (Word14 -> Word16) -> (MidiInt14 -> Word14) -> MidiInt14 -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int14 -> Word14
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int14 -> Word14) -> (MidiInt14 -> Int14) -> MidiInt14 -> Word14
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MidiInt14 -> Int14
unMidiInt14

newtype VarWord = VarWord {VarWord -> Word32
unVarWord :: Word32}
  deriving stock (Int -> VarWord -> String -> String
[VarWord] -> String -> String
VarWord -> String
(Int -> VarWord -> String -> String)
-> (VarWord -> String)
-> ([VarWord] -> String -> String)
-> Show VarWord
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> VarWord -> String -> String
showsPrec :: Int -> VarWord -> String -> String
$cshow :: VarWord -> String
show :: VarWord -> String
$cshowList :: [VarWord] -> String -> String
showList :: [VarWord] -> String -> String
Show)
  deriving newtype (VarWord -> VarWord -> Bool
(VarWord -> VarWord -> Bool)
-> (VarWord -> VarWord -> Bool) -> Eq VarWord
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VarWord -> VarWord -> Bool
== :: VarWord -> VarWord -> Bool
$c/= :: VarWord -> VarWord -> Bool
/= :: VarWord -> VarWord -> Bool
Eq, Eq VarWord
Eq VarWord =>
(VarWord -> VarWord -> Ordering)
-> (VarWord -> VarWord -> Bool)
-> (VarWord -> VarWord -> Bool)
-> (VarWord -> VarWord -> Bool)
-> (VarWord -> VarWord -> Bool)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> Ord VarWord
VarWord -> VarWord -> Bool
VarWord -> VarWord -> Ordering
VarWord -> VarWord -> VarWord
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: VarWord -> VarWord -> Ordering
compare :: VarWord -> VarWord -> Ordering
$c< :: VarWord -> VarWord -> Bool
< :: VarWord -> VarWord -> Bool
$c<= :: VarWord -> VarWord -> Bool
<= :: VarWord -> VarWord -> Bool
$c> :: VarWord -> VarWord -> Bool
> :: VarWord -> VarWord -> Bool
$c>= :: VarWord -> VarWord -> Bool
>= :: VarWord -> VarWord -> Bool
$cmax :: VarWord -> VarWord -> VarWord
max :: VarWord -> VarWord -> VarWord
$cmin :: VarWord -> VarWord -> VarWord
min :: VarWord -> VarWord -> VarWord
Ord, Int -> VarWord
VarWord -> Int
VarWord -> [VarWord]
VarWord -> VarWord
VarWord -> VarWord -> [VarWord]
VarWord -> VarWord -> VarWord -> [VarWord]
(VarWord -> VarWord)
-> (VarWord -> VarWord)
-> (Int -> VarWord)
-> (VarWord -> Int)
-> (VarWord -> [VarWord])
-> (VarWord -> VarWord -> [VarWord])
-> (VarWord -> VarWord -> [VarWord])
-> (VarWord -> VarWord -> VarWord -> [VarWord])
-> Enum VarWord
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: VarWord -> VarWord
succ :: VarWord -> VarWord
$cpred :: VarWord -> VarWord
pred :: VarWord -> VarWord
$ctoEnum :: Int -> VarWord
toEnum :: Int -> VarWord
$cfromEnum :: VarWord -> Int
fromEnum :: VarWord -> Int
$cenumFrom :: VarWord -> [VarWord]
enumFrom :: VarWord -> [VarWord]
$cenumFromThen :: VarWord -> VarWord -> [VarWord]
enumFromThen :: VarWord -> VarWord -> [VarWord]
$cenumFromTo :: VarWord -> VarWord -> [VarWord]
enumFromTo :: VarWord -> VarWord -> [VarWord]
$cenumFromThenTo :: VarWord -> VarWord -> VarWord -> [VarWord]
enumFromThenTo :: VarWord -> VarWord -> VarWord -> [VarWord]
Enum, Integer -> VarWord
VarWord -> VarWord
VarWord -> VarWord -> VarWord
(VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord)
-> (VarWord -> VarWord)
-> (VarWord -> VarWord)
-> (Integer -> VarWord)
-> Num VarWord
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: VarWord -> VarWord -> VarWord
+ :: VarWord -> VarWord -> VarWord
$c- :: VarWord -> VarWord -> VarWord
- :: VarWord -> VarWord -> VarWord
$c* :: VarWord -> VarWord -> VarWord
* :: VarWord -> VarWord -> VarWord
$cnegate :: VarWord -> VarWord
negate :: VarWord -> VarWord
$cabs :: VarWord -> VarWord
abs :: VarWord -> VarWord
$csignum :: VarWord -> VarWord
signum :: VarWord -> VarWord
$cfromInteger :: Integer -> VarWord
fromInteger :: Integer -> VarWord
Num, Enum VarWord
Real VarWord
(Real VarWord, Enum VarWord) =>
(VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> VarWord)
-> (VarWord -> VarWord -> (VarWord, VarWord))
-> (VarWord -> VarWord -> (VarWord, VarWord))
-> (VarWord -> Integer)
-> Integral VarWord
VarWord -> Integer
VarWord -> VarWord -> (VarWord, VarWord)
VarWord -> VarWord -> VarWord
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: VarWord -> VarWord -> VarWord
quot :: VarWord -> VarWord -> VarWord
$crem :: VarWord -> VarWord -> VarWord
rem :: VarWord -> VarWord -> VarWord
$cdiv :: VarWord -> VarWord -> VarWord
div :: VarWord -> VarWord -> VarWord
$cmod :: VarWord -> VarWord -> VarWord
mod :: VarWord -> VarWord -> VarWord
$cquotRem :: VarWord -> VarWord -> (VarWord, VarWord)
quotRem :: VarWord -> VarWord -> (VarWord, VarWord)
$cdivMod :: VarWord -> VarWord -> (VarWord, VarWord)
divMod :: VarWord -> VarWord -> (VarWord, VarWord)
$ctoInteger :: VarWord -> Integer
toInteger :: VarWord -> Integer
Integral, Num VarWord
Ord VarWord
(Num VarWord, Ord VarWord) => (VarWord -> Rational) -> Real VarWord
VarWord -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: VarWord -> Rational
toRational :: VarWord -> Rational
Real, Eq VarWord
Eq VarWord =>
(Int -> VarWord -> Int) -> (VarWord -> Int) -> Hashable VarWord
Int -> VarWord -> Int
VarWord -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> VarWord -> Int
hashWithSalt :: Int -> VarWord -> Int
$chash :: VarWord -> Int
hash :: VarWord -> Int
Hashable)

instance Bounded VarWord where
  minBound :: VarWord
minBound = Word32 -> VarWord
VarWord Word32
0
  maxBound :: VarWord
maxBound = Word32 -> VarWord
VarWord Word32
0x00FFFFFF

instance Binary VarWord where
  byteSize :: VarWord -> ByteCount
byteSize (VarWord Word32
w) =
    if
      | Word32
w Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFFFFFF80 Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 -> ByteCount
1
      | Word32
w Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFFFFC000 Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 -> ByteCount
2
      | Word32
w Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFFE00000 Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 -> ByteCount
3
      | Bool
otherwise -> ByteCount
4
  get :: Get VarWord
get = Int -> Word32 -> Get VarWord
go Int
0 Word32
0
   where
    go :: Int -> Word32 -> Get VarWord
go !Int
off !Word32
acc = do
      Word8
w <- forall a. Binary a => Get a
get @Word8
      let wLow :: Word32
wLow = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x7F)
          wShift :: Word32
wShift = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftL Word32
wLow Int
off
          accNext :: Word32
accNext = Word32
acc Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32
wShift
      if Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x80 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
        then VarWord -> Get VarWord
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word32 -> VarWord
VarWord Word32
accNext)
        else Int -> Word32 -> Get VarWord
go (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Word32
accNext

  put :: VarWord -> Put
put (VarWord Word32
acc) = Int -> Word32 -> Put
forall {t} {t}. (Integral t, Bits t, Eq t, Num t) => t -> t -> Put
go (Int
0 :: Int) Word32
acc
   where
    go :: t -> t -> Put
go !t
off !t
w = do
      let wLow :: Word8
wLow = t -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (t
w t -> t -> t
forall a. Bits a => a -> a -> a
.&. t
0x7F)
          wShift :: t
wShift = t -> Int -> t
forall a. Bits a => a -> Int -> a
shiftR t
w Int
7
      if t
wShift t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0 Bool -> Bool -> Bool
|| t
off t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
3
        then forall a. Binary a => a -> Put
put @Word8 Word8
wLow
        else forall a. Binary a => a -> Put
put @Word8 (Word8
wLow Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
0x80) Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> t -> t -> Put
go (t
off t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) t
wShift