csound-expression-typed 0.2.0.2 → 0.2.1.0
raw patch · 7 files changed
+176/−27 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Csound.Typed.Plugins: tapeRead :: Sig -> Sig -> Sig -> SE Sig
+ Csound.Typed.Plugins: tapeWrite :: Sig -> Sig -> Sig -> SE ()
- Csound.Typed.Types.Prim: class Val a where fromE = fromGE . return
+ Csound.Typed.Types.Prim: class Val a
- Csound.Typed.Types.SigSpace: class SigSpace b => At a b c where type AtOut a b c :: * where {
+ Csound.Typed.Types.SigSpace: class SigSpace b => At a b c where {
Files
- csound-expression-typed.cabal +3/−2
- data/opcodes/MultiFX/TapeEcho.udo +89/−0
- src/Csound/Typed/GlobalState/Elements.hs +3/−0
- src/Csound/Typed/Plugins.hs +8/−4
- src/Csound/Typed/Plugins/Iain.hs +12/−12
- src/Csound/Typed/Plugins/TapeEcho.hs +52/−0
- src/Csound/Typed/Plugins/Zdf.hs +9/−9
csound-expression-typed.cabal view
@@ -1,5 +1,5 @@ Name: csound-expression-typed-Version: 0.2.0.2+Version: 0.2.1.0 Cabal-Version: >= 1.22 License: BSD3 License-file: LICENSE@@ -49,9 +49,9 @@ data/opcodes/MultiFX/RingModulator.udo data/opcodes/MultiFX/StChorus.udo data/opcodes/MultiFX/StereoPingPongDelay.udo+ data/opcodes/MultiFX/TapeEcho.udo data/opcodes/Utility/Delay1k.udo - Homepage: https://github.com/anton-k/csound-expression-typed Bug-Reports: https://github.com/anton-k/csound-expression-typed/issues @@ -126,6 +126,7 @@ Csound.Typed.Misc Csound.Typed.Plugins.TabQueue+ Csound.Typed.Plugins.TapeEcho Csound.Typed.Plugins.Zdf Csound.Typed.Plugins.Diode Csound.Typed.Plugins.Korg35
+ data/opcodes/MultiFX/TapeEcho.udo view
@@ -0,0 +1,89 @@+; Original research and code by Jon Downing as in paper+; Real-time digital modeling of the Roland Space Echo by Jon Downing, Christian Terjesen (ECE 472 - Audio Signal Processing, May 2016)+;+; Reimplemented in Csound by Anton Kholomiov++; Error function approximation ~ 2% accuracy+opcode ErrorFunApprox, a, a+ aIn xin+ kCoeff init ( (3.1415926535 ^ 0.5) * log(2) )+ xout tanh(kCoeff * aIn)+endop++; Bandpass Chebyshev Type I filter+opcode bandpassCheby1, a, akkii+ aIn, kLowFreq, kHighFreq, iOrder, iRipple xin++ aHigh clfilt aIn, kLowFreq, 1, iOrder, 1, iRipple+ aLow clfilt aHigh, kHighFreq, 0, iOrder, 1, iRipple++ xout aLow+endop++; Function to read from tape.+;+; tapeRead aIn, kDelay, kRandomSpread+;+; The function is used in the same manner as deltapi+; first init the delay buffer and the use tapeRead.+;+; aIn - input signal+; kDelay - delay time+; kRandomSpread - [0, Inf] - the random spread of reading from the tape+; the higher the worser the quality of the tape.+opcode tapeRead, a, akk+ aIn, kDelay, kRandomSpread xin+ iTauUp = 1.07+ iTauDown = 1.89+ aPrevDelay init 0.06+ kOldDelay init 0.06+ kLambda init 0.5++ kDelChange changed kDelay+ if (kDelChange == 1) then+ if (kOldDelay < kDelay) then+ kLambda = exp(-1/(iTauUp*sr))+ else+ kLambda = exp(-1/(iTauDown*sr))+ endif+ endif++ anoise noise kRandomSpread, 0+ anoise = 3*(7.5 - aPrevDelay*(10^-3))*(10^-7)*anoise+ anoiseMod butterlp anoise, 0.25 ; (0.5 / sr) * giNyquistFreq+ aActualDelay = (1 - kLambda) * kDelay + kLambda * aPrevDelay + anoiseMod+ aPrevDelay = aActualDelay+ ; measured+ aDelaySamps = aActualDelay * sr+ aReadSr = floor(aDelaySamps) ; in samples+ aLastSr = aReadSr + 1 ; in samples+ aReadIndex = aReadSr / sr ; in seconds+ aLastIndex = aLastSr / sr ; in seconds+ aFrac = aDelaySamps - aReadSr+ aFracScale = (1 - aFrac) * (1 + aFrac)++ aReadSample deltapi aReadIndex+ aLastSample deltapi aLastIndex++ aEcho ErrorFunApprox (aLastSample + aFracScale * (aReadSample - aLastSample))++ kOldDelay = kDelay+ xout aEcho+endop++; function to write to tape+;+; tapeWrite aIn, aOut, kFbGain+;+; It should be though of as delayw for magnetic tape.+;+; aIn - input signal+; aOut - output signal+; kFbGain - gain of feedback [0, 2]+opcode tapeWrite, 0, aak+ aIn, aOut, kFbGain xin+ iOrder = 2+ iRippleDb = 6+ aProc bandpassCheby1 aOut * kFbGain, 95, 3000, iOrder, iRippleDb+ delayw aIn + aProc * kFbGain+endop
src/Csound/Typed/GlobalState/Elements.hs view
@@ -42,6 +42,7 @@ analogDelayPlugin, distortionPlugin, envelopeFolollowerPlugin, flangerPlugin, freqShifterPlugin, loFiPlugin, panTremPlugin, monoTremPlugin, phaserPlugin, pitchShifterPlugin, reversePlugin, ringModulatorPlugin, stChorusPlugin, stereoPingPongDelayPlugin,+ tapeEchoPlugin, delay1kPlugin, ) where @@ -592,5 +593,7 @@ ringModulatorPlugin = UdoPlugin "MultiFX/RingModulator" stChorusPlugin = UdoPlugin "MultiFX/StChorus" stereoPingPongDelayPlugin = UdoPlugin "MultiFX/StereoPingPongDelay"++tapeEchoPlugin = UdoPlugin "MultiFX/TapeEcho" delay1kPlugin = UdoPlugin "Utility/Delay1k"
src/Csound/Typed/Plugins.hs view
@@ -1,7 +1,7 @@ module Csound.Typed.Plugins( adsr140, audaciousEq,- + -- Solina chorus solinaChorus, testSolinaChorus, @@ -12,10 +12,10 @@ zdf2, zlp, zbp, zhp, zdf2_notch, zbr, -- Ladder filter- zladder, + zladder, -- Four poles filters- zdf4, zlp4, zbp4, zhp4, + zdf4, zlp4, zbp4, zhp4, -- Eq-filters peakEq, highShelf, lowShelf,@@ -33,9 +33,12 @@ pitchShifterDelay, -- Iain's fxs- fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, + fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, fxPanTrem, fxMonoTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong, + -- * Tape echo+ tapeRead, tapeWrite,+ -- utilities delay1k @@ -49,4 +52,5 @@ import Csound.Typed.Plugins.SolinaChorus import Csound.Typed.Plugins.ZeroDelayConvolution import Csound.Typed.Plugins.Iain+import Csound.Typed.Plugins.TapeEcho import Csound.Typed.Plugins.Utilities
src/Csound/Typed/Plugins/Iain.hs view
@@ -1,6 +1,6 @@-module Csound.Typed.Plugins.Iain( +module Csound.Typed.Plugins.Iain( pitchShifterDelay,- fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, + fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, fxPanTrem, fxMonoTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong ) where @@ -12,7 +12,7 @@ import Csound.Typed.Types import Csound.Typed.GlobalState-import qualified Csound.Typed.GlobalState.Elements as E(pitchShifterDelayPlugin, +import qualified Csound.Typed.GlobalState.Elements as E(pitchShifterDelayPlugin, analogDelayPlugin, distortionPlugin, envelopeFolollowerPlugin, flangerPlugin, freqShifterPlugin, loFiPlugin, panTremPlugin, monoTremPlugin, phaserPlugin, pitchShifterPlugin, reversePlugin, ringModulatorPlugin, stChorusPlugin, stereoPingPongDelayPlugin) @@ -33,10 +33,10 @@ --; ----------- --; ain -- input audio to be pitch shifted --; ktrans -- pitch transposition (in semitones)---; kdlt -- delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt) +--; kdlt -- delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt) --; kFB1 -- feedback using method 1 (output from delay taps are fed back directly into their own buffers before enveloping and mixing) --; kFB2 -- feedback using method 2 (enveloped and mixed output from both taps is fed back into both buffers)--- +-- -- opcode PitchShifterDelay,a,akkkki csdPitchShifterDelay :: Sig -> Sig -> Sig -> Sig -> Sig -> D -> Sig csdPitchShifterDelay ain ktrans kdlt kFB1 kFB2 imaxdlt = fromGE $ do@@ -107,7 +107,7 @@ -- ; kfreq -- base frequency of the filter before modulation by the input dynamics (range: 0 to 1) -- ; kres -- resonance of the lowpass filter (suggested range: 0 to 0.99) csdEnvelopeFollower :: Sig -> Sig -> Sig -> Sig -> Sig-csdEnvelopeFollower ain ksens kfreq kres = fromGE $ do +csdEnvelopeFollower ain ksens kfreq kres = fromGE $ do addUdoPlugin E.envelopeFolollowerPlugin f <$> toGE ain <*> toGE ksens <*> toGE kfreq <*> toGE kres where f ain ksens kfreq kres = opcs "EnvelopeFollower" [(Ar,[Ar,Kr,Kr,Kr])] [ain, ksens, kfreq, kres]@@ -162,7 +162,7 @@ -- ; ----------- -- ; ain -- input audio to have low fidelity distortion effects applied -- ; kbits -- bit depth reduction (suggested range 0 to 0.6)--- ; kfold -- amount of foldover (range 0 to 1) +-- ; kfold -- amount of foldover (range 0 to 1) fxLoFi :: Sig -> Sig -> Sig -> Sig fxLoFi kbits kfold ain = fromGE $ do addUdoPlugin E.loFiPlugin@@ -219,7 +219,7 @@ -- ; krate -- rate of lfo of the effect (range 0 to 1) -- ; kdepth -- depth of lfo of the effect (range 0 to 1) -- ; kfreq -- centre frequency of the phase shifting effect in octaves (suggested range 6 to 11)--- ; kfback -- feedback and therefore intensity of the effect (range 0 to 1) +-- ; kfback -- feedback and therefore intensity of the effect (range 0 to 1) fxPhaser :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig fxPhaser krate kdepth kfreq kfback ain = fromGE $ do addUdoPlugin E.phaserPlugin@@ -239,7 +239,7 @@ -- ; kscal -- pitch ratio -- #### ; kpitch -- pitch shifting interval in thousands of a semitone (suggested range -0.012 to 0.012) -- #### ; kfine -- fine control of pitch shifting interval in octaves (range -1/12 to 1/12)--- ; kfback -- control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1) +-- ; kfback -- control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1) fxPitchShifter :: D -> Sig -> Sig -> Sig -> Sig -> Sig fxPitchShifter ifftsize kmix kscal kfback ain = fromGE $ do addUdoPlugin E.pitchShifterPlugin@@ -256,7 +256,7 @@ -- ; Performance -- ; ----------- -- ; ain -- input audio to be reversed--- ; ktime -- time duration of each chunk (suggested range: 0.3 to 2)-- +-- ; ktime -- time duration of each chunk (suggested range: 0.3 to 2)-- fxReverse :: Sig -> Sig -> Sig fxReverse ktime ain = fromGE $ do addUdoPlugin E.reversePlugin@@ -297,8 +297,8 @@ fxChorus2 :: Sig -> Sig -> Sig -> Sig2 -> Sig2 fxChorus2 krate kdepth kwidth (ainL, ainR) = toTuple $ do addUdoPlugin E.stChorusPlugin- f <$> toGE ainL <*> toGE ainR <*> toGE krate <*> toGE kdepth <*> toGE kwidth - where f ainL ainR krate kdepth kwidth = ($ 2) $ mopcs "StChorus" ([Ar,Ar], [Ar,Ar,Kr,Kr,Kr]) [ainL, ainR, krate, kdepth, kwidth] + f <$> toGE ainL <*> toGE ainR <*> toGE krate <*> toGE kdepth <*> toGE kwidth+ where f ainL ainR krate kdepth kwidth = ($ 2) $ mopcs "StChorus" ([Ar,Ar], [Ar,Ar,Kr,Kr,Kr]) [ainL, ainR, krate, kdepth, kwidth] -- aInL, aInR, kdelayTime, kFeedback, kMix, iMaxDelayTime xin
+ src/Csound/Typed/Plugins/TapeEcho.hs view
@@ -0,0 +1,52 @@+module Csound.Typed.Plugins.TapeEcho(+ tapeRead+ , tapeWrite+) where++import Control.Monad.Trans.Class+import Control.Applicative++import Csound.Dynamic++import Csound.Typed.Types+import Csound.Typed.GlobalState+import qualified Csound.Typed.GlobalState.Elements as E(tapeEchoPlugin)++-- Function to read from tape.+--+-- tapeRead aIn, kDelay, kRandomSpread+--+-- The function is used in the same manner as deltapi+-- first init the delay buffer and the use tapeRead.+--+-- aIn - input signal+-- kDelay - delay time+-- kRandomSpread - [0, Inf] - the random spread of reading from the tape+-- the higher the worser the quality of the tape.+-- opcode tapeRead, a, akk+tapeRead :: Sig -> Sig -> Sig -> SE Sig+tapeRead ain kdel kRandomSpread = fmap (Sig . return) $ SE $ (depT =<<) $ lift $ do+ addUdoPlugin E.tapeEchoPlugin+ f <$> toGE ain <*> toGE kdel <*> toGE kRandomSpread+ where f ain kdel krand = opcs "tapeRead" [(Ar, [Ar, Kr, Kr])] [ain, kdel, krand]+++-- function to write to tape+--+-- tapeWrite aIn, aOut, kFbGain+--+-- It should be though of as delayw for magnetic tape.+--+-- aIn - input signal+-- aOut - output signal+-- kFbGain - gain of feedback [0, 2]+tapeWrite :: Sig -> Sig -> Sig -> SE ()+tapeWrite ain aout kFeedback = SE $ (depT_ =<<) $ lift $ do+ f <$> toGE ain <*> toGE aout <*> toGE kFeedback+ where f ain aout kfb = opcs "tapeWrite" [(Xr, [Ar, Ar, Kr])] [ain, aout, kfb]++{-+addUdoPlugin E.pitchShifterDelayPlugin+ f <$> toGE ain <*> toGE ktrans <*> toGE kdlt <*> toGE kFB1 <*> toGE kFB2 <*> toGE imaxdlt+ where f ain ktrans kdlt kFB1 kFB2 imaxdlt = opcs "PitchShifterDelay" [(Ar, [Ar, Kr, Kr, Kr, Kr, Ir])] [ain, ktrans, kdlt, kFB1, kFB2, imaxdlt]+-}
src/Csound/Typed/Plugins/Zdf.hs view
@@ -1,5 +1,5 @@ -- Zero delay filters (implemented in Csound by Steven Yi)-module Csound.Typed.Plugins.Zdf( +module Csound.Typed.Plugins.Zdf( -- One pole filters zdf1, zlp1, zhp1, zap1, @@ -7,13 +7,13 @@ zdf2, zlp, zbp, zhp, zdf2_notch, zbr, -- Ladder filter- zladder, + zladder, -- Four poles filters- zdf4, zlp4, zbp4, zhp4, + zdf4, zlp4, zbp4, zhp4, -- Eq-filters- peakEq, highShelf, lowShelf + peakEq, highShelf, lowShelf ) where import Data.Boolean@@ -74,22 +74,22 @@ -- ladder zladder :: Sig -> Sig -> Sig -> Sig-zladder cfq q asig = zdf_ladder asig cfq q +zladder cfq q asig = zdf_ladder asig cfq q -- zdf_4pole zdf4 :: Sig -> Sig -> Sig -> (Sig, Sig, Sig, Sig, Sig, Sig) zdf4 cfq q asig = zdf_4pole asig cfq q -zlp4 :: Sig -> Sig -> Sig -> Sig +zlp4 :: Sig -> Sig -> Sig -> Sig zlp4 cfq q asig = lows where (_, _, _, lows, _, _) = zdf4 cfq q asig -zbp4 :: Sig -> Sig -> Sig -> Sig +zbp4 :: Sig -> Sig -> Sig -> Sig zbp4 cfq q asig = mids where (_, _, _, _, mids, _) = zdf4 cfq q asig -zhp4 :: Sig -> Sig -> Sig -> Sig +zhp4 :: Sig -> Sig -> Sig -> Sig zhp4 cfq q asig = highs where (_, _, _, _, _, highs) = zdf4 cfq q asig @@ -103,7 +103,7 @@ -- zdf_low_shelf_eq lowShelf :: Sig -> Sig -> Sig -> Sig-lowShelf kcf kres ain = zdf_low_shelf_eq ain kcf kres +lowShelf kcf kres ain = zdf_low_shelf_eq ain kcf kres ------------------------------------------------------------------------------- -- Steven implementation