module Synthesizer.Dimensional.RateAmplitude.Instrument where
import qualified Synthesizer.Dimensional.Rate.Oscillator as Osci
import qualified Synthesizer.Dimensional.Rate.Filter as Filt
import qualified Synthesizer.Dimensional.RateAmplitude.Displacement as Disp
import qualified Synthesizer.Dimensional.RateAmplitude.Noise as Noise
import qualified Synthesizer.Dimensional.RateAmplitude.Filter as FiltA
import qualified Synthesizer.Dimensional.RateAmplitude.Cut as Cut
import qualified Synthesizer.Dimensional.Amplitude.Cut as CutA
import qualified Synthesizer.Dimensional.RateAmplitude.Piece as Piece
import qualified Synthesizer.Dimensional.RateAmplitude.Control as Ctrl
import qualified Synthesizer.Dimensional.Rate.Control as CtrlR
import qualified Synthesizer.Dimensional.Amplitude.Analysis as Ana
import qualified Synthesizer.Dimensional.Process as Proc
import qualified Synthesizer.Dimensional.Signal as SigA
import Synthesizer.Dimensional.Signal (($-), ($&), (&*^), (&*>^), )
import Synthesizer.Dimensional.RateAmplitude.Piece ((-|#), ( #|-), (|#), ( #|), )
import Synthesizer.Dimensional.Wave ((&*~), )
import Synthesizer.Dimensional.Process (($:), ($::), ($^), (.^), ($#), )
import qualified Synthesizer.Dimensional.Amplitude.Displacement as DispA
import qualified Synthesizer.Dimensional.Amplitude.Flat as Flat
import qualified Synthesizer.Dimensional.Sample as Sample
import Foreign.Storable (Storable, )
import qualified Algebra.DimensionTerm as Dim
import qualified Number.DimensionTerm as DN
import Number.DimensionTerm ((*&), (&*&), )
import qualified Synthesizer.Interpolation.Module as Interpolation
import Synthesizer.Plain.Instrument (choirWave)
import qualified Synthesizer.Dimensional.Wave.Controlled as WaveCtrl
import qualified Synthesizer.Dimensional.Wave as WaveD
import qualified Synthesizer.Generic.Wave as WaveG
import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Basic.Phase as Phase
import qualified Number.NonNegative as NonNeg
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Module as Module
import qualified Algebra.RealField as RealField
import qualified Algebra.Ring as Ring
import System.Random (Random, randoms, randomRs, mkStdGen, )
import Synthesizer.Utility (randomRsBalanced, balanceLevel, )
import Data.List(zip4)
import NumericPrelude.Base
import NumericPrelude.Numeric
stereoPhaser :: Ring.C a =>
(DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s u b b))
-> a
-> DN.T Dim.Frequency a
-> Proc.T s Dim.Time a (SigA.R s u b b)
stereoPhaser sound dif freq =
sound (dif *& freq)
allpassDown ::
(RealField.C a, Trans.C a, Module.C a a) =>
NonNeg.Int -> DN.T Dim.Time a ->
DN.T Dim.Frequency a -> DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
allpassDown order halfLife filterfreq freq =
do x <- simpleSaw freq
FiltA.amplify 0.3 $:
(Disp.mix
$# x
$: (Filt.allpassCascade order Filt.allpassFlangerPhase
$: filterfreq &*^ CtrlR.exponential2 halfLife
$# x))
moogDown, moogReso ::
(RealField.C a, Trans.C a, Module.C a a) =>
NonNeg.Int -> DN.T Dim.Time a ->
DN.T Dim.Frequency a -> DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
moogDown order halfLife filterfreq freq =
Filt.moogLowpass order
$- DN.fromNumber 10
$: filterfreq &*^ CtrlR.exponential2 halfLife
$: simpleSaw freq
moogReso order halfLife filterfreq freq =
Filt.moogLowpass order
$: DN.fromNumber 100 &*>^ CtrlR.exponential2 halfLife
$- filterfreq
$: simpleSaw freq
bell :: (Trans.C a, RealField.C a, Module.C a a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
bell freq =
let halfLife = DN.time 0.5
in FiltA.amplify (1/3) $:
(Disp.mixMulti $::
(bellHarmonic 1 halfLife freq :
bellHarmonic 4 halfLife freq :
bellHarmonic 7 halfLife freq :
[]))
bellHarmonic :: (Trans.C a, RealField.C a, Module.C a a) =>
a -> DN.T Dim.Time a -> DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
bellHarmonic n halfLife freq =
Filt.envelope
$: CtrlR.exponential2 (recip n *& halfLife)
$: (Osci.freqMod (DN.voltage 1 &*~ Wave.sine) zero
$: Osci.static (WaveD.mapLinear 0.005 (DN.frequency 5) Wave.sine)
zero (n *& freq))
fastBell, squareBell, moogGuitar, moogGuitarSoft, fatSaw ::
(RealField.C a, Trans.C a, Module.C a a) =>
DN.T Dim.Frequency a -> Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
fastBell freq =
Filt.envelope
$: CtrlR.exponential2 (DN.time 0.2)
$: Osci.static (DN.voltage 1 &*~ Wave.sine) zero freq
filterSaw :: (Module.C a a, Trans.C a, RealField.C a) =>
DN.T Dim.Frequency a -> DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
filterSaw filterFreq freq =
FiltA.amplify 0.1 $:
(Filt.lowpassFromUniversal $^
(Filt.universal
$- DN.fromNumber 10
$: filterFreq &*^ CtrlR.exponential2 (DN.time 0.1)
$: Osci.static (DN.voltage 1 &*~ Wave.saw) zero freq))
squareBell freq =
Filt.firstOrderLowpass
$: DN.frequency 4000 &*^ CtrlR.exponential2 (DN.time (1/10))
$: (Osci.freqMod
(sampledWave Interpolation.linear (DN.voltage 1)
[0, 0.5, 0.6, 0.8, 0, 0.5, 0.6, 0.8]) zero
$: (Osci.static (WaveD.mapLinear 0.01 freq Wave.sine) zero (DN.frequency 5.0)))
fmBell :: (RealField.C a, Trans.C a, Module.C a a) =>
a -> a -> DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
fmBell depth freqRatio freq =
let modul =
Filt.envelope
$: CtrlR.exponential2 (DN.time 0.2)
$: Osci.static (DN.fromNumber depth &*~ Wave.sine)
zero (freqRatio *& freq)
in Filt.envelope
$: CtrlR.exponential2 (DN.time 0.5)
$: (Osci.phaseMod (DN.voltage 1 &*~ Wave.sine) freq $& modul)
moogGuitar freq =
let filterControl =
DN.frequency 4000 &*^ CtrlR.exponential2 (DN.time 0.5)
tone =
Osci.freqMod (DN.voltage 1 &*~ Wave.saw) zero
$: Osci.static (WaveD.mapLinear 0.005 freq Wave.sine)
zero (DN.frequency 5)
in Filt.moogLowpass 4 $- DN.fromNumber 10 $: filterControl $: tone
moogGuitarSoft freq =
Filt.envelope
$: (DispA.map (1) $^ CtrlR.exponential2 (DN.time 0.003))
$: moogGuitar freq
fmRing ::
(RealField.C a, Trans.C a, Module.C a a) =>
DN.T Dim.Frequency a -> Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
fmRing freq =
Osci.phaseMod (DN.voltage 1 &*~ Wave.sineSawSmooth 1) freq
$: (Filt.envelope
$: CtrlR.exponential2 (DN.time 0.2)
$: (Filt.envelope
$: Osci.static (WaveD.flat $ Wave.raise one Wave.sine) (Phase.fromRepresentative 0.75) freq
$: Osci.static
(DN.fromNumber 0.2 &*~ Wave.sine)
zero (5.001 *& freq)))
fatPad ::
(RealField.C a, Trans.C a, Module.C a a, Random a) =>
DN.T Dim.Frequency a -> Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
fatPad freq =
let env =
Cut.append
$: (Cut.take (DN.time 0.7) $:
Ctrl.cubicHermite
(DN.time 0, (DN.fromNumber 0, DN.frequency 1 &*& DN.fromNumber 5))
(DN.time 0.7, (DN.fromNumber 0.5, DN.frequency 1 &*& DN.fromNumber 0)))
$: Ctrl.constant (DN.fromNumber 0.5)
osci f =
Osci.phaseMod (DN.voltage 0.3 &*~ Wave.sine) f
$: (Filt.envelope
$: env
$: Osci.static (DN.fromNumber 2 &*~ Wave.sineSawSmooth 1) zero f)
freqs = randomRsBalanced (mkStdGen 384) 3 1 0.03
in Disp.mixMulti $:: map (\k -> osci (k *& freq)) freqs
brass ::
(RealField.C a, Trans.C a, Module.C a a, Random a) =>
DN.T Dim.Frequency a -> Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
brass freq =
let blobEnv = Piece.runState
(DN.fromNumber 0 |# (DN.time 0.05, Piece.cosine) #|-
DN.fromNumber 1 -|# (DN.time 0.05, Piece.cosine) #|
DN.fromNumber 0)
adsr = Piece.runState
(DN.fromNumber 0 |# (DN.time 0.1, Piece.cubic (DN.frequency 1 &*& DN.fromNumber 10) (DN.frequency 1 &*& DN.fromNumber 0)) #|-
DN.fromNumber 0.5 -|# (DN.time 1, Piece.step) #|-
DN.fromNumber 0.5 -|# (DN.time 0.3, Piece.exponential (DN.fromNumber 0)) #|
DN.fromNumber 0.01)
osci b f =
Osci.freqMod (DN.voltage 0.5 &*~ Wave.saw) zero $:
(Disp.mix
$: (Osci.static (WaveD.mapLinear 0.01 f Wave.sine)
zero (DN.frequency 2))
$: ((b *& f) &*^ blobEnv))
n = 4
freqs = randomRsBalanced (mkStdGen 295) n 1 0.03
blobAmps = balanceLevel 0 (take n (iterate (0.1+) 0))
in Filt.envelope
$: adsr
$: (Disp.mixMulti $:: zipWith (\b k -> osci b (k *& freq)) blobAmps freqs)
filterSweep :: (Module.C a v, Trans.C a, RealField.C a) =>
Phase.T a ->
Proc.T s Dim.Time a (
SigA.R s Dim.Voltage a v ->
SigA.R s Dim.Voltage a v)
filterSweep phase =
Filt.lowpassFromUniversal .^
(Filt.universal
$- DN.fromNumber 10
$: Osci.static (WaveD.mapExponential 2 (DN.frequency 1800) Wave.sine)
phase (DN.frequency (1/16)))
fatSawChordFilter, fatSawChord ::
(RealField.C a, Trans.C a, Module.C a a) =>
DN.T Dim.Frequency a -> Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
fatSawChordFilter freq =
FiltA.amplify (1/2) $:
(Filt.lowpassFromUniversal $^
(Filt.universal
$- DN.fromNumber 10
$: filterDown
$: fatSawChord freq))
fatSawChord freq =
FiltA.amplify (1/3) $:
(Disp.mixMulti $::
[fatSaw ( 1 *& freq),
fatSaw ((5/4) *& freq),
fatSaw ((3/2) *& freq)])
filterDown :: (RealField.C a, Trans.C a) =>
Proc.T s Dim.Time a (SigA.R s Dim.Frequency a a)
filterDown =
DN.frequency 4000 &*^ CtrlR.exponential2 (DN.time (1/3))
simpleSaw :: (Ring.C a, Dim.C u, RealField.C v) =>
DN.T (Dim.Recip u) v ->
Proc.T s u v (SigA.R s Dim.Voltage a v)
simpleSaw freq =
Osci.static (DN.voltage 1 &*~ Wave.saw) zero freq
modulatedWave :: (Trans.C a, RealField.C a, Dim.C u) =>
Proc.T s u a (SigA.R s (Dim.Recip u) a a -> SigA.R s Dim.Voltage a a) ->
DN.T (Dim.Recip u) a ->
a -> Phase.T a ->
DN.T (Dim.Recip u) a ->
Proc.T s u a (SigA.R s Dim.Voltage a a)
modulatedWave osc freq depth phase speed =
osc $: Osci.static (WaveD.mapLinear depth freq Wave.sine) phase speed
accumulationParameters :: (Random a, Trans.C a, RealField.C a, Module.C a a) =>
[(Phase.T a, a, Phase.T a, DN.T Dim.Frequency a)]
accumulationParameters =
let starts = randoms (mkStdGen 48251)
depths = randomRs (0,0.02) (mkStdGen 12354)
phases = randoms (mkStdGen 74389)
speeds = randomRs (DN.frequency 0.1, DN.frequency 0.3)
(mkStdGen 03445)
in zip4 starts depths phases speeds
accumulatedSaws, choir ::
(Random a, Trans.C a, RealField.C a, Module.C a a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
accumulatedSaws freq =
Disp.mixMulti $::
(map
(\(start, depth, phase, speed) ->
modulatedWave
(Osci.freqMod (DN.voltage 1 &*~ Wave.saw) start)
freq depth phase speed)
accumulationParameters)
choir freq =
FiltA.amplify 0.2 $: (Disp.mixMulti $::
take 10
(map
(\(start, depth, phase, speed) ->
modulatedWave
(Osci.freqMod
(sampledWave Interpolation.constant (DN.voltage 1) choirWave) start)
freq depth phase speed)
accumulationParameters))
fatSaw freq =
let partial depth modPhase modFreq =
osciDoubleSaw $:
Osci.static (WaveD.mapLinear depth freq Wave.sine)
(Phase.fromRepresentative modPhase) modFreq
in Disp.mixMulti $::
[partial 0.00311 0.0 (DN.frequency 20),
partial 0.00532 0.3 (DN.frequency 17),
partial 0.00981 0.9 (DN.frequency 6)]
wasp ::
(RealField.C q, Trans.C q, Module.C q q, Random q, Dim.C u) =>
DN.T (Dim.Recip u) q ->
Proc.T s u q (SigA.R s Dim.Voltage q q)
wasp freq =
Filt.envelope
$: Osci.static (WaveD.mapLinear 1 (DN.scalar 0.5) Wave.saw)
zero (recip 2.01 *& freq)
$: Osci.static (DN.voltage 0.7 &*~ Wave.saw) zero freq
osciDoubleSaw ::
(RealField.C a, Module.C a a, Dim.C u) =>
Proc.T s u a (
SigA.R s (Dim.Recip u) a a ->
SigA.R s Dim.Voltage a a)
osciDoubleSaw =
Osci.freqMod
(sampledWave Interpolation.linear (DN.voltage 1)
[1, 0.2, 0.5, 0.5, 0.2, 1.0]) zero
sampledWave :: (RealField.C t) =>
Interpolation.T t y -> amp -> [y] ->
WaveD.T t (Sample.Numeric amp y)
sampledWave ip amp =
WaveD.amplified amp . WaveG.sample ip
osciSharp :: (RealField.C a, Trans.C a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
osciSharp freq =
Osci.shapeMod (DN.voltage 1 `WaveCtrl.amplified` Wave.powerNormed2) zero freq $:
(Flat.canonicalize $^
DN.fromNumber 10 &*^ CtrlR.exponential2 (DN.time 0.01))
osciAbsModSaw :: (RealField.C a, Trans.C a, Module.C a a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
osciAbsModSaw freq =
let harmonic n =
Osci.freqMod (DN.voltage (0.25 / fromInteger n) &*~ Wave.sine) zero
$: Osci.static (WaveD.mapLinear 0.03 freq Wave.sine) zero (DN.frequency 1)
in Disp.mixMulti $:: map harmonic [1..20]
pulsedNoise :: (Random a, RealField.C a, Trans.C a, Module.C a a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
pulsedNoise freq =
let raisedSine :: Trans.C a => a -> WaveD.T a (Sample.Dimensional Dim.Voltage a a)
raisedSine v = DN.voltage v &*~ Wave.raise one Wave.sine
c = Proc.pure Ana.lessOrEqual
$: Osci.static (raisedSine 1.0) zero freq
$: Osci.static (raisedSine 0.2) zero (DN.frequency 0.1)
in Proc.pure CutA.selectBool
$- DN.voltage 0
$: Noise.white (DN.frequency 20000) (DN.voltage 1.0)
$: c
noisePerc :: (Random a, RealField.C a, Trans.C a) =>
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
noisePerc =
Filt.envelope
$: CtrlR.exponential2 (DN.time 0.1)
$: Noise.white (DN.frequency 20000) (DN.voltage 1.0)
noiseBass :: (Random a, RealField.C a, Trans.C a, Module.C a a, Storable a) =>
DN.T Dim.Frequency a ->
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
noiseBass freq =
FiltA.combProc (DN.unrecip freq)
(Filt.firstOrderLowpass $- DN.frequency 2000)
$: noisePerc
electroTom ::
(Random a, RealField.C a, Trans.C a, Module.C a a, Storable a) =>
Proc.T s Dim.Time a (SigA.R s Dim.Voltage a a)
electroTom =
let ks =
FiltA.combProc (DN.time (1/30))
(Filt.firstOrderLowpass $- (DN.frequency 1000))
$: noisePerc
in Filt.frequencyModulation Interpolation.linear
$: CtrlR.exponential2 (DN.time 0.3)
$: ks
bassDrum ::
(RealField.C q, Trans.C q, Module.C q q, Random q) =>
Proc.T s Dim.Time q (SigA.R s Dim.Voltage q q)
bassDrum =
Cut.take (DN.time 0.15) $:
(Disp.mix
$: (Filt.firstOrderLowpass
$- (DN.frequency 5000)
$: (Filt.envelope
$: (DispA.map (0.03+) $^ CtrlR.exponential2 (DN.time 0.002))
$: (Noise.white (DN.frequency 20000) (DN.voltage 1))))
$: (Filt.envelope
$: (CtrlR.exponential2 (DN.time 0.05))
$: (Osci.freqMod (DN.voltage 0.5 &*~ Wave.sine) zero
$: (Ctrl.exponential2
(DN.time 0.15) (DN.frequency 100)))))