{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Storable.Play where

import qualified Synthesizer.Basic.Binary as BinSmp

import qualified Sound.Sox.Option.Format as SoxOpt
import qualified Sound.Sox.Play as Play

import Foreign.Storable (Storable, )

import qualified Synthesizer.Storable.Signal as SigSt
import qualified Synthesizer.Frame.Stereo as Stereo

import System.Exit (ExitCode, )

import qualified Algebra.RealRing as RealRing

import NumericPrelude.Numeric
import NumericPrelude.Base


{- |
Latency is high using Sox -
We can achieve better results using ALSA's sound output!
See synthesizer-alsa package.
-}
monoToInt16 ::
   (Storable a, RealRing.C a) =>
   a -> SigSt.T a -> IO ExitCode
monoToInt16 :: forall a. (Storable a, C a) => a -> T a -> IO ExitCode
monoToInt16 a
rate =
   forall y (sig :: * -> *).
C y =>
(Handle -> sig y -> IO ()) -> T -> Int -> sig y -> IO ExitCode
Play.simple forall a. Storable a => Handle -> Vector a -> IO ()
SigSt.hPut T
SoxOpt.none (forall a b. (C a, C b) => a -> b
round a
rate) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall x y.
(Storable x, Storable y) =>
(x -> y) -> Vector x -> Vector y
SigSt.map forall a. C a => a -> Int16
BinSmp.int16FromCanonical

stereoToInt16 ::
   (Storable a, RealRing.C a) =>
   a -> SigSt.T (Stereo.T a) -> IO ExitCode
stereoToInt16 :: forall a. (Storable a, C a) => a -> T (T a) -> IO ExitCode
stereoToInt16 a
rate =
   forall y (sig :: * -> *).
C y =>
(Handle -> sig y -> IO ()) -> T -> Int -> sig y -> IO ExitCode
Play.simple forall a. Storable a => Handle -> Vector a -> IO ()
SigSt.hPut T
SoxOpt.none (forall a b. (C a, C b) => a -> b
round a
rate) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall x y.
(Storable x, Storable y) =>
(x -> y) -> Vector x -> Vector y
SigSt.map (\T a
y -> forall a. a -> a -> T a
Stereo.cons
                       (forall a. C a => a -> Int16
BinSmp.int16FromCanonical forall a b. (a -> b) -> a -> b
$ forall a. T a -> a
Stereo.left T a
y)
                       (forall a. C a => a -> Int16
BinSmp.int16FromCanonical forall a b. (a -> b) -> a -> b
$ forall a. T a -> a
Stereo.right T a
y))