module Synthesizer.LLVM.Server.Common where
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Sound.ALSA.Sequencer.Address as Addr
import qualified Sound.ALSA.Sequencer.Client as Client
import qualified Sound.ALSA.Sequencer.Port as Port
import qualified Sound.ALSA.Sequencer.Queue as Queue
import qualified Sound.ALSA.Sequencer.RealTime as RealTime
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Sound.ALSA.PCM as ALSA
import qualified Synthesizer.Storable.ALSA.Play as Play
import qualified Synthesizer.PiecewiseConstant.ALSA.MIDI as PC
import qualified Synthesizer.PiecewiseConstant.ALSA.MIDIControllerSet as PCS
import qualified Synthesizer.LLVM.Parameterized.Signal as SigP
import qualified Synthesizer.LLVM.Parameter as Param
import qualified LLVM.Extra.Representation as Rep
import qualified LLVM.Core as LLVM
import qualified Data.EventList.Relative.BodyTime as EventListBT
import qualified Synthesizer.Storable.Signal as SigSt
import qualified Data.StorableVector.Lazy as SVL
import Foreign.Storable (Storable, )
import qualified Synthesizer.Generic.Signal as SigG
import qualified Sound.MIDI.Message.Channel as ChannelMsg
import qualified Sound.Sox.Frame as SoxFrame
import Control.Arrow ((^<<), )
import qualified Numeric.NonNegative.Wrapper as NonNegW
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.ToInteger as ToInteger
import qualified Algebra.Additive as Additive
import Data.Word (Word8, )
import NumericPrelude.Numeric (zero, round, )
import Prelude hiding (Real, round, break, )
channel :: ChannelMsg.Channel
channel = ChannelMsg.toChannel 0
sampleRate :: Num a => a
sampleRate = 44100
latency :: Int
latency = 0
chunkSize :: SVL.ChunkSize
chunkSize = Play.defaultChunkSize
lazySize :: SigG.LazySize
lazySize =
let (SVL.ChunkSize size) = chunkSize
in SigG.LazySize size
periodTime :: Field.C t => t
periodTime =
let (SVL.ChunkSize size) = chunkSize
in ToInteger.fromIntegral size Field./ Ring.fromInteger sampleRate
type Real = Float
($/) :: (Functor f) => f (a -> b) -> a -> f b
f $/ x = fmap ($x) f
play ::
(RealRing.C t, Additive.C y, ALSA.SampleFmt y) =>
t -> t -> SigSt.T y -> IO ()
play period rate =
Play.auto period (round rate) .
SigSt.append (SigSt.replicate chunkSize latency zero)
playAndRecord ::
(RealRing.C t, Additive.C y, ALSA.SampleFmt y, SoxFrame.C y) =>
FilePath -> t -> t -> SigSt.T y -> IO ()
playAndRecord fileName period rate =
Play.autoAndRecord period fileName (round rate) .
SigSt.append (SigSt.replicate chunkSize latency zero)
piecewiseConstant ::
(Storable a,
LLVM.MakeValueTuple a al,
Rep.Memory al am,
LLVM.IsSized am as) =>
Param.T p (PC.T a) -> SigP.T p al
piecewiseConstant pc =
SigP.piecewiseConstant
(EventListBT.mapTime
(NonNegW.fromNumber . fromIntegral . NonNegW.toNumber) ^<< pc)
transposeModulation ::
(Functor stream) =>
Real ->
stream (PC.BendModulation Real) ->
stream (PC.BendModulation Real)
transposeModulation freq =
fmap (PC.shiftBendModulation (freq/sampleRate))
amplitudeFromVelocity :: Real -> Real
amplitudeFromVelocity vel = 4**vel
makeNote :: Event.NoteEv -> Word8 -> Event.T
makeNote typ pit =
Event.Cons
{ Event.highPriority = False
, Event.tag = 0
, Event.queue = Queue.direct
, Event.timestamp =
Event.RealTime $ RealTime.fromInteger 0
, Event.source = Addr.Cons {
Addr.client = Client.subscribers,
Addr.port = Port.unknown
}
, Event.dest = Addr.Cons {
Addr.client = Client.subscribers,
Addr.port = Port.unknown
}
, Event.body =
Event.NoteEv typ
(Event.simpleNote 0 pit 64)
}