{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE Rank2Types #-} module Synthesizer.Dimensional.RateAmplitude.Play ( auto, timeVoltage, timeVoltageMonoDoubleToInt16, timeVoltageStereoDoubleToInt16, renderTimeVoltageMonoDoubleToInt16, renderTimeVoltageStereoDoubleToInt16, ) where import qualified Sound.Sox.Play as Play import qualified Sound.Sox.Option.Format as SoxOpt import qualified Sound.Sox.Frame as Frame import qualified Synthesizer.Basic.Binary as BinSmp import qualified Data.StorableVector.Lazy.Builder as Builder import Foreign.Storable (Storable, ) import qualified Synthesizer.Dimensional.Process as Proc import qualified Synthesizer.Dimensional.Amplitude.Signal as SigA import qualified Synthesizer.Dimensional.RateAmplitude.Signal as SigRA import qualified Synthesizer.Dimensional.RateWrapper as SigP import qualified Synthesizer.Storable.Signal as SigSt import qualified Synthesizer.State.Signal as Sig import qualified Synthesizer.Frame.Stereo as Stereo import qualified Algebra.DimensionTerm as Dim import qualified Number.DimensionTerm as DN import qualified Algebra.ToInteger as ToInteger -- import qualified Algebra.Transcendental as Trans import qualified Algebra.Module as Module import qualified Algebra.RealField as RealField import qualified Algebra.Field as Field -- import qualified Algebra.Ring as Ring import System.Exit(ExitCode) import NumericPrelude import PreludeBase {-# INLINE auto #-} auto :: (Bounded int, ToInteger.C int, Storable int, Frame.C int, BinSmp.C yv, Dim.C u, RealField.C t, Dim.C v, Module.C y yv, Field.C y) => DN.T (Dim.Recip u) t -> DN.T v y -> (int -> Builder.Builder int) -> SigP.T u t (SigA.S v y) yv -> -- SigP.T u t (SigA.D v y SigS.S) yv -> IO ExitCode auto freqUnit amp put sig = let opts = SoxOpt.numberOfChannels (BinSmp.numberOfSignalChannels sig) sampleRate = DN.divToScalar (SigP.sampleRate sig) freqUnit in Play.extended SigSt.hPut opts SoxOpt.none (round sampleRate) (Builder.toLazyStorableVector SigSt.defaultChunkSize $ Sig.monoidConcatMap (BinSmp.outputFromCanonical put) $ SigA.vectorSamples (flip DN.divToScalar amp) sig) {-# INLINE timeVoltage #-} timeVoltage :: (Bounded int, ToInteger.C int, Storable int, Frame.C int, BinSmp.C yv, RealField.C t, Module.C y yv, Field.C y) => (int -> Builder.Builder int) -> SigP.T Dim.Time t (SigA.S Dim.Voltage y) yv -> -- SigP.T Dim.Time t (SigA.D Dim.Voltage y SigS.S) yv -> IO ExitCode timeVoltage = auto (DN.frequency one) (DN.voltage one) {-# INLINE timeVoltageMonoDoubleToInt16 #-} timeVoltageMonoDoubleToInt16 :: SigP.T Dim.Time Double (SigA.S Dim.Voltage Double) Double -> IO ExitCode timeVoltageMonoDoubleToInt16 sig = let rate = DN.toNumberWithDimension Dim.frequency (SigP.sampleRate sig) in Play.simple SigSt.hPut SoxOpt.none (round rate) (SigP.signal (SigRA.toStorableInt16Mono sig)) {-# INLINE timeVoltageStereoDoubleToInt16 #-} timeVoltageStereoDoubleToInt16 :: SigP.T Dim.Time Double (SigA.S Dim.Voltage Double) (Stereo.T Double) -> -- SigP.T Dim.Time t (SigA.D Dim.Voltage y SigS.S) yv -> IO ExitCode timeVoltageStereoDoubleToInt16 sig = let rate = DN.toNumberWithDimension Dim.frequency (SigP.sampleRate sig) in Play.simple SigSt.hPut SoxOpt.none (round rate) (SigP.signal (SigRA.toStorableInt16Stereo sig)) {-# INLINE renderTimeVoltageMonoDoubleToInt16 #-} renderTimeVoltageMonoDoubleToInt16 :: DN.T Dim.Frequency Double -> (forall s. Proc.T s Dim.Time Double (SigA.R s Dim.Voltage Double Double)) -> IO ExitCode renderTimeVoltageMonoDoubleToInt16 rate sig = timeVoltageMonoDoubleToInt16 (SigP.runProcess rate sig) {-# INLINE renderTimeVoltageStereoDoubleToInt16 #-} renderTimeVoltageStereoDoubleToInt16 :: DN.T Dim.Frequency Double -> (forall s. Proc.T s Dim.Time Double (SigA.R s Dim.Voltage Double (Stereo.T Double))) -> IO ExitCode renderTimeVoltageStereoDoubleToInt16 rate sig = timeVoltageStereoDoubleToInt16 (SigP.runProcess rate sig)