module Synthesizer.Dimensional.RateAmplitude.Play (
timeVoltageMonoDouble,
timeVoltageStereoDouble,
timeVoltageMonoDoubleR,
timeVoltageStereoDoubleR,
) where
import qualified Sox
import qualified Sox.Play
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 Algebra.RealField as RealField
import qualified Algebra.DimensionTerm as Dim
import qualified Number.DimensionTerm as DN
import qualified Synthesizer.Frame.Stereo as Stereo
import Control.Exception(bracket)
import Foreign.Storable (Storable)
import qualified System.IO as IO
import qualified System.Process as Proc
import NumericPrelude
import PreludeBase
raw :: (RealField.C a, Storable y) =>
[String] -> a -> Int -> SigSt.T y -> IO ()
raw args sampleRate numChannels stream =
bracket
(Proc.runInteractiveProcess "play"
(args ++
Sox.sampleRateOption sampleRate ++
Sox.channelOption numChannels ++
["-t","sw","-"])
Nothing Nothing)
(\(input,output,err,proc) -> do
mapM IO.hClose [input, output, err]
Proc.waitForProcess proc)
(\(input,_,_,_) ->
Sox.Play.catchCtrlC >>
SigSt.hPut input stream)
timeVoltageMonoDouble ::
SigP.T Dim.Time Double (SigA.S Dim.Voltage Double) Double ->
IO ()
timeVoltageMonoDouble sig =
let rate = DN.toNumberWithDimension Dim.frequency (SigP.sampleRate sig)
in raw [] rate 1
(SigP.signal (SigRA.toStorableInt16Mono sig))
timeVoltageStereoDouble ::
SigP.T Dim.Time Double (SigA.S Dim.Voltage Double) (Stereo.T Double) ->
IO ()
timeVoltageStereoDouble sig =
let rate = DN.toNumberWithDimension Dim.frequency (SigP.sampleRate sig)
in raw [] rate 2
(SigP.signal (SigRA.toStorableInt16Stereo sig))
timeVoltageMonoDoubleR ::
DN.T Dim.Frequency Double ->
(forall s. Proc.T s Dim.Time Double (SigA.R s Dim.Voltage Double Double)) ->
IO ()
timeVoltageMonoDoubleR rate sig =
timeVoltageMonoDouble (SigP.runProcess rate sig)
timeVoltageStereoDoubleR ::
DN.T Dim.Frequency Double ->
(forall s. Proc.T s Dim.Time Double (SigA.R s Dim.Voltage Double (Stereo.T Double))) ->
IO ()
timeVoltageStereoDoubleR rate sig =
timeVoltageStereoDouble (SigP.runProcess rate sig)