{-
This data type can be used as sample type for stereo signals.
-}
module Sound.Frame.MuLaw (T, cons, decons, fromLinear16, toLinear16, ) where

import qualified Sound.Frame as Frame

import Foreign.Storable.Newtype as Store
import Foreign.Storable (Storable (..), )

import Data.Word (Word8, )
import Data.Int (Int16, )

import Test.QuickCheck (Arbitrary(arbitrary), )

import Prelude hiding (map, )


newtype T = Cons Word8
   deriving (T -> T -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: T -> T -> Bool
$c/= :: T -> T -> Bool
== :: T -> T -> Bool
$c== :: T -> T -> Bool
Eq)


instance Show T where
   showsPrec :: Int -> T -> ShowS
showsPrec Int
p T
x =
      Bool -> ShowS -> ShowS
showParen (Int
p forall a. Ord a => a -> a -> Bool
>= Int
10)
         (String -> ShowS
showString String
"MuLaw.cons " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (T -> Word8
decons T
x))

instance Arbitrary T where
   arbitrary :: Gen T
arbitrary = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word8 -> T
cons forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Int -> T) forall a. Arbitrary a => Gen a
arbitrary


{-# INLINE cons #-}
cons :: Word8 -> T
cons :: Word8 -> T
cons = Word8 -> T
Cons

{-# INLINE decons #-}
decons :: T -> Word8
decons :: T -> Word8
decons (Cons Word8
a) = Word8
a


{-# INLINE fromLinear16 #-}
fromLinear16 :: Int16 -> T
fromLinear16 :: Int16 -> T
fromLinear16 Int16
x16 =
   let x :: Int
x = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
x16 :: Int
       logi :: t -> t -> t
logi t
e t
y =
          if t
y forall a. Ord a => a -> a -> Bool
< t
16
            then t
eforall a. Num a => a -> a -> a
*t
16 forall a. Num a => a -> a -> a
+ t
y
            else t -> t -> t
logi (t
eforall a. Num a => a -> a -> a
+t
1) (forall a. Integral a => a -> a -> a
div (t
y forall a. Num a => a -> a -> a
- t
16) t
2)
       loga :: Int -> Int
loga = forall a. Ord a => a -> a -> a
min Int
127 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Integral a => a -> a -> a
logi Int
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Integral a => a -> a -> a
div Int
8
   in  Word8 -> T
cons forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$
       if Int
x forall a. Ord a => a -> a -> Bool
>= -Int
2
         then Int
255 forall a. Num a => a -> a -> a
- Int -> Int
loga (Int
xforall a. Num a => a -> a -> a
+Int
6)
         else Int
127 forall a. Num a => a -> a -> a
- Int -> Int
loga (Int
5forall a. Num a => a -> a -> a
-Int
x)

{-# INLINE toLinear16 #-}
toLinear16 :: T -> Int16
toLinear16 :: T -> Int16
toLinear16 T
ymu =
   let y :: Int
y = forall a b. (Integral a, Num b) => a -> b
fromIntegral (T -> Word8
decons T
ymu) :: Int
       (Int
e,Int
m) = forall a. Integral a => a -> a -> (a, a)
divMod Int
y Int
16
   in  forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$
       if Int
eforall a. Ord a => a -> a -> Bool
>=Int
8
         then (Int
2forall a b. (Num a, Integral b) => a -> b -> a
^(Int
15forall a. Num a => a -> a -> a
-Int
e) forall a. Num a => a -> a -> a
* ((Int
15forall a. Num a => a -> a -> a
-Int
m)forall a. Num a => a -> a -> a
*Int
2 forall a. Num a => a -> a -> a
+ Int
33) forall a. Num a => a -> a -> a
- Int
33) forall a. Num a => a -> a -> a
* Int
4
         else (Int
2forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
7forall a. Num a => a -> a -> a
-Int
e) forall a. Num a => a -> a -> a
* ((Int
mforall a. Num a => a -> a -> a
-Int
15)forall a. Num a => a -> a -> a
*Int
2 forall a. Num a => a -> a -> a
- Int
33) forall a. Num a => a -> a -> a
+ Int
33) forall a. Num a => a -> a -> a
* Int
4
{-
         then ((15-m) * 2^(16-e) + (2^(15-e) - 1) * 33) * 4
         else ((m-15) * 2^(8-e) - (2^(7-e) - 1) * 33) * 4
-}


{-
propZero :: Bool
propZero =
   fromLinear16 0 == cons 255 &&
   toLinear16 (cons 255) == 0

propLinear :: T -> Bool
propLinear x =
   fromLinear16 (toLinear16 x) == x
-}


instance Storable T where
   {-# INLINE sizeOf #-}
   sizeOf :: T -> Int
sizeOf = forall core wrapper.
Storable core =>
(wrapper -> core) -> wrapper -> Int
Store.sizeOf T -> Word8
decons
   {-# INLINE alignment #-}
   alignment :: T -> Int
alignment = forall core wrapper.
Storable core =>
(wrapper -> core) -> wrapper -> Int
Store.alignment T -> Word8
decons
   {-# INLINE peek #-}
   peek :: Ptr T -> IO T
peek = forall core wrapper.
Storable core =>
(core -> wrapper) -> Ptr wrapper -> IO wrapper
Store.peek Word8 -> T
cons
   {-# INLINE poke #-}
   poke :: Ptr T -> T -> IO ()
poke = forall core wrapper.
Storable core =>
(wrapper -> core) -> Ptr wrapper -> wrapper -> IO ()
Store.poke T -> Word8
decons


instance Frame.C T where
   {-# INLINE numberOfChannels #-}
   numberOfChannels :: T -> Int
numberOfChannels T
_ = Int
1
   {-# INLINE sizeOfElement #-}
   sizeOfElement :: T -> Int
sizeOfElement = forall core wrapper.
Storable core =>
(wrapper -> core) -> wrapper -> Int
Store.sizeOf T -> Word8
decons