csound-expression 5.2.2 → 5.3.0
raw patch · 9 files changed
+503/−257 lines, 9 filesdep ~csound-expression-opcodes
Dependency ranges changed: csound-expression-opcodes
Files
- csound-expression.cabal +5/−2
- src/Csound/Air/Filter.hs +245/−77
- src/Csound/Air/Fx.hs +144/−89
- src/Csound/Air/Fx/FxBox.hs +18/−1
- src/Csound/Air/Wav.hs +10/−48
- src/Csound/Air/Wave.hs +25/−25
- src/Csound/Air/Wave/Sync.hs +15/−15
- src/Csound/Compat.hs +17/−0
- src/Csound/Compat/Filter.hs +24/−0
csound-expression.cabal view
@@ -1,5 +1,5 @@ Name: csound-expression-Version: 5.2.2+Version: 5.3.0 Cabal-Version: >= 1.6 License: BSD3 License-file: LICENSE@@ -80,7 +80,7 @@ Build-Depends: base >= 4, base < 5, process, data-default, Boolean >= 0.1.0, colour >= 2.0, transformers >= 0.3, containers, csound-expression-typed >= 0.2.0.2, csound-expression-dynamic >= 0.3.2, temporal-media >= 0.6.1,- csound-expression-opcodes >= 0.0.3.2+ csound-expression-opcodes >= 0.0.4.0 Hs-Source-Dirs: src/ Exposed-Modules: Csound.Base@@ -115,6 +115,9 @@ Csound.Options Csound.Tuning Csound.Cabbage++ Csound.Compat+ Csound.Compat.Filter Csound.Control Csound.Control.Evt
src/Csound/Air/Filter.hs view
@@ -8,7 +8,7 @@ -- * Simple filters lp, hp, bp, br, alp, bp2, br2,- + -- * Butterworth filters blp, bhp, bbp, bbr, @@ -32,25 +32,22 @@ alp1, alp2, alp3, alp4, ahp, - -- ** Low level analog filters - mvchpf, mvclpf1, mvclpf2, mvclpf3, mvclpf4,- -- * Zero delay filters -- ** One pole filters zdf1, zlp1, zhp1, zap1, -- ** Two pole filters- zdf2, zlp, zbp, zhp, zdf2_notch, zbr,+ zdf2, zlp, zhp, zbp, zubp, zbr, zap, zpeak, -- ** Ladder filter- zladder, + zladder, -- ** Four poles filters- zdf4, zlp4, zbp4, zhp4, + -- zdf4, zlp4, zbp4, zhp4, -- ** Eq-filters- peakEq, highShelf, lowShelf,+ -- peakEq, highShelf, lowShelf, -- * Classic analog-like filters @@ -61,13 +58,14 @@ hpCheb1, hpCheb1', hpCheb2, hpCheb2', chp, chp', -- * Named resonant low pass filters- plastic, wobble, trumpy, harsh, + plastic, wobble, trumpy, harsh, -- * TB303 filter- tbf, diode, linDiode, noNormDiode,+ tbf, diode, fdiode, linDiode, -- Korg 35 filters- linKorg_lp, linKorg_hp, korg_lp, korg_hp,+ linKorg_lp, linKorg_hp, linKorg_bp, korg_lp, korg_hp, korg_bp,+ klp, khp, kbp, -- * Statevariable filters slp, shp, sbp, sbr,@@ -79,7 +77,13 @@ import Control.Applicative import Csound.Typed-import Csound.Typed.Plugins+import Csound.Typed.Plugins hiding (+ zdf1, zlp1, zhp1, zap1,+ zdf2, zlp, zbp, zhp, zdf2_notch, zbr,+ zladder,+ diode, linDiode, noNormDiode,+ linKorg_lp, linKorg_hp, korg_lp, korg_hp)+ import Csound.SigSpace(bat) import Csound.Typed.Opcode @@ -139,7 +143,7 @@ -- | Band-regect filter. -- -- > bbr cutoff bandwidth sig-bbr :: Sig -> Sig -> Sig -> Sig +bbr :: Sig -> Sig -> Sig -> Sig bbr freq band a = butbr a freq band @@ -158,16 +162,18 @@ -- | Produces smooth transitions between values in the signals. -- The first value defines a duration in seconds for a transition from one -- value to another in piecewise constant signals.+--+-- > smooth transTime asig smooth :: Sig -> Sig -> Sig smooth = flip portk -- | Resonant filter.--- +-- -- > f centerFreq q asig type ResonFilter = Sig -> Sig -> Sig -> Sig -- | Filter without a resonance.--- +-- -- > f centerFreq q asig type FlatFilter = Sig -> Sig -> Sig @@ -197,10 +203,14 @@ -- | Another implementation of moog low pass filter (it's moogladder in Csound). -- The arguments have are just like in the @mlp@ filter.+--+-- > mlp2 centerFreq q asig mlp2 :: Sig -> Sig -> Sig -> Sig mlp2 cfq q asig = moogladder asig cfq q -- | Mooglowpass filter with 18 dB.+--+-- > mlp3 centerFreq q asig mlp3 :: Sig -> Sig -> Sig -> Sig mlp3 = lp18 0 @@ -216,13 +226,13 @@ hp1 :: Sig -> Sig -> Sig hp1 cfq asig = atone asig cfq --- | Resonance band pass filter (yet another implementation, it's reson in Csound) +-- | Resonance band pass filter (yet another implementation, it's reson in Csound) -- -- > bp2 centerFreq q asig bp2 :: Sig -> Sig -> Sig -> Sig bp2 cfq q asig = reson asig cfq q --- | Resonance band reject filter (yet another implementation, it's areson in Csound) +-- | Resonance band reject filter (yet another implementation, it's areson in Csound) -- -- > br2 centerFreq q asig br2 :: Sig -> Sig -> Sig -> Sig@@ -259,7 +269,7 @@ singO2 = bat (formant bp2 anO2) anO = [(280, 20), (650, 25), (2200, 30), (3450, 40), (4500, 50)]-anA = [(650, 50), (1100, 50), (2860, 50), (3300, 50), (4500, 50)] +anA = [(650, 50), (1100, 50), (2860, 50), (3300, 50), (4500, 50)] anE = [(500, 50), (1750, 50), (2450, 50), (3350, 50), (5000, 50)] anIY = [(330, 50), (2000, 50), (2800, 50), (3650, 50), (5000, 50)] anO2 = [(400, 50), (840, 50), (2800, 50), (3250, 50), (4500, 50)]@@ -288,63 +298,24 @@ -- | Analog-like low-pass filter -- -- > alpf4 centerFrequency resonance asig-alp4 :: Sig -> Sig -> Sig -> Sig-alp4 freq reson asig = mvclpf4 asig freq reson---- | Analog-like high-pass filter ----- > ahp centerFrequency asig-ahp :: Sig -> Sig -> Sig-ahp freq asig = mvchpf asig freq---- | --- Moog ladder lowpass filter.------ Moogladder is an new digital implementation of the Moog ladder filter based on --- the work of Antti Huovilainen, described in the paper "Non-Linear Digital --- Implementation of the Moog Ladder Filter" (Proceedings of DaFX04, Univ of Napoli). --- This implementation is probably a more accurate digital representation of --- the original analogue filter.------ > asig moogladder ain, kcf, kres[, istor]------ csound doc: <http://www.csounds.com/manual/html/moogladder.html>----- | Emulator of analog high pass filter.+-- Analog outputs ----- > mvchpf asig xfreq-mvchpf :: Sig -> Sig -> Sig-mvchpf b1 b2 = Sig $ f <$> unSig b1 <*> unSig b2- where f a1 a2 = opcs "mvchpf" [(Ar,[Ar,Xr,Ir])] [a1,a2]---- | Emulators of analog filters (requires Csound >= 6.07). +-- * asig1 -- 6dB/oct low-pass response output. ----- > mvclpf1 asig xfreq xresonance -mvclpf1 :: Sig -> Sig -> Sig -> Sig-mvclpf1 = genMvclpf "mvclpf1"---- | Emulators of analog filters.+-- * asig2 -- 12dB/oct low-pass response output. ----- > mvclpf2 asig xfreq xresonance -mvclpf2 :: Sig -> Sig -> Sig -> Sig-mvclpf2 = genMvclpf "mvclpf2"---- | Emulators of analog filters.+-- * asig3 -- 18dB/oct low-pass response output.. ----- > mvclpf3 asig xfreq xresonance -mvclpf3 :: Sig -> Sig -> Sig -> Sig-mvclpf3 = genMvclpf "mvclpf3"+-- * asig4 -- 24dB/oct low-pass response output.+alp4 :: Sig -> Sig -> Sig -> (Sig, Sig, Sig, Sig)+alp4 freq reson asig = mvclpf4 asig freq reson --- | Emulators of analog filters.+-- | Analog-like high-pass filter ----- > mvclpf4 asig xfreq xresonance -mvclpf4 :: Sig -> Sig -> Sig -> Sig-mvclpf4 = genMvclpf "mvclpf4"--genMvclpf :: String -> Sig -> Sig -> Sig -> Sig-genMvclpf name b1 b2 b3 = Sig $ f <$> unSig b1 <*> unSig b2 <*> unSig b3- where f a1 a2 a3 = opcs name [(Ar,[Ar,Xr,Xr,Ir])] [a1,a2,a3]+-- > ahp centerFrequency asig+ahp :: Sig -> Sig -> Sig+ahp freq asig = mvchpf asig freq -----------------------------------------------@@ -355,52 +326,76 @@ -- low pass -- | Chebyshev type I low pass filter (with 2 poles).+--+-- lpCheb1 centerFreq asig lpCheb1 :: Sig -> Sig -> Sig lpCheb1 = lpCheb1' 2 -- | Chebyshev type I low pass filter (with given number of poles, first argument).+--+-- lpCheb1' npols centerFreq asig lpCheb1' :: D -> Sig -> Sig -> Sig lpCheb1' npoles kcf asig = clfilt asig kcf 0 npoles `withD` 1 -- | Chebyshev type II low pass filter (with 2 poles).-lpCheb2 :: Sig -> Sig -> Sig +--+-- lpCheb2 centerFreq asig+lpCheb2 :: Sig -> Sig -> Sig lpCheb2 = lpCheb2' 2 -- | Chebyshev type II low pass filter (with given number of poles, first argument).+--+-- lpCheb2' npols centerFreq asig lpCheb2' :: D -> Sig -> Sig -> Sig lpCheb2' npoles kcf asig = clfilt asig kcf 0 npoles `withD` 2 -- | Butterworth lowpass filter based on clfilt opcode (with 2 poles).+--+-- clp centerFreq asig clp :: Sig -> Sig -> Sig clp = clp' 2 -- | Butterworth lowpass filter based on clfilt opcode (with given number of poles, first argument).+--+-- clp' npols centerFreq asig clp' :: D -> Sig -> Sig -> Sig clp' npoles kcf asig = clfilt asig kcf 0 npoles `withD` 0 -- high pass -- | Chebyshev type I high pass filter (with 2 poles).+--+-- hpCheb1 centerFreq asig hpCheb1 :: Sig -> Sig -> Sig hpCheb1 = hpCheb1' 2 -- | Chebyshev type I high pass filter (with given number of poles, first argument).+--+-- hpCheb1' npols centerFreq asig hpCheb1' :: D -> Sig -> Sig -> Sig hpCheb1' npoles kcf asig = clfilt asig kcf 1 npoles `withD` 1 -- | Chebyshev type II high pass filter (with 2 poles).-hpCheb2 :: Sig -> Sig -> Sig +--+-- hpCheb2 centerFreq asig+hpCheb2 :: Sig -> Sig -> Sig hpCheb2 = hpCheb2' 2 -- | Chebyshev type II high pass filter (with given number of poles, first argument).+--+-- hpCheb2' npols centerFreq asig hpCheb2' :: D -> Sig -> Sig -> Sig hpCheb2' npoles kcf asig = clfilt asig kcf 1 npoles `withD` 2 -- | Butterworth high pass filter based on clfilt opcode (with 2 poles).+--+-- chp centerFreq asig chp :: Sig -> Sig -> Sig chp = clp' 2 -- | Butterworth high pass filter based on clfilt opcode (with given number of poles, first argument).+--+-- chp' npols centerFreq asig chp' :: D -> Sig -> Sig -> Sig chp' npoles kcf asig = clfilt asig kcf 1 npoles `withD` 0 @@ -415,19 +410,19 @@ bpCheb1 = bpCheb1' 2 bpCheb1' :: D -> Sig -> Sig -> Sig -> Sig-bpCheb1' npoles = mkBp (lpCheb1' npoles) (hpCheb1' npoles) +bpCheb1' npoles = mkBp (lpCheb1' npoles) (hpCheb1' npoles) bpCheb2 :: Sig -> Sig -> Sig -> Sig bpCheb2 = bpCheb2' 2 bpCheb2' :: D -> Sig -> Sig -> Sig -> Sig-bpCheb2' npoles = mkBp (lpCheb2' npoles) (hpCheb2' npoles) +bpCheb2' npoles = mkBp (lpCheb2' npoles) (hpCheb2' npoles) cbp :: Sig -> Sig -> Sig -> Sig cbp = cbp' 2 cbp' :: D -> Sig -> Sig -> Sig -> Sig-cbp' npoles = mkBp (clp' npoles) (chp' npoles) +cbp' npoles = mkBp (clp' npoles) (chp' npoles) ---------------------------------------------@@ -437,43 +432,58 @@ mkReson lowPass highPass kcf res asig = 0.5 * (lowPass (kcf * 2) asig + bandPass bw kcf asig) where bw = kcf / (0.001 + abs res)- bandPass = mkBp lowPass highPass + bandPass = mkBp lowPass highPass cheb1 :: Sig -> Sig -> Sig -> Sig cheb1 = cheb1' 2 cheb1' :: D -> Sig -> Sig -> Sig -> Sig-cheb1' npoles = mkReson (lpCheb1' npoles) (hpCheb1' npoles) +cheb1' npoles = mkReson (lpCheb1' npoles) (hpCheb1' npoles) cheb2 :: Sig -> Sig -> Sig -> Sig cheb2 = cheb2' 2 cheb2' :: D -> Sig -> Sig -> Sig -> Sig-cheb2' npoles = mkReson (lpCheb2' npoles) (hpCheb2' npoles) +cheb2' npoles = mkReson (lpCheb2' npoles) (hpCheb2' npoles) vcf :: Sig -> Sig -> Sig -> Sig vcf = cbp' 2 vcf' :: D -> Sig -> Sig -> Sig -> Sig-vcf' npoles = mkReson (clp' npoles) (chp' npoles) +vcf' npoles = mkReson (clp' npoles) (chp' npoles) -- moog ladder +-- | Moog ladder filter+--+-- > ladder centerFreq q asig ladder :: Sig -> Sig -> Sig -> Sig ladder kcf res asig = moogladder asig kcf res ----------------------------------------- -- named filters +-- | plastic sound+--+-- > plastic centerFreq q asig plastic :: Sig -> Sig -> Sig -> Sig plastic kcf res asig = rezzy asig kcf (1 + 99 * res) +-- | wobble sound+--+-- > wobble centerFreq q asig wobble :: Sig -> Sig -> Sig -> Sig wobble kcf res asig = lowres asig kcf res +-- | trumpy sound+--+-- > trumpy centerFreq q asig trumpy :: Sig -> Sig -> Sig -> Sig trumpy kcf res asig = vlowres asig kcf (res* 0.15) 6 (4 + res * 20) +-- | harsh sound+--+-- > harsh centerFreq q asig harsh :: Sig -> Sig -> Sig -> Sig harsh kcf res asig = bat (\x -> bqrez x kcf (1 + 90 * res)) asig @@ -487,18 +497,22 @@ ----------------------------- -- state variable filter +-- | State variable low-pass filter slp :: Sig -> Sig -> Sig -> Sig slp kcf res asig = lows where (_, lows, _, _) = statevar asig kcf res +-- | State variable high-pass filter shp :: Sig -> Sig -> Sig -> Sig shp kcf res asig = highs where (highs, _, _, _) = statevar asig kcf res +-- | State variable band-pass filter sbp :: Sig -> Sig -> Sig -> Sig sbp kcf res asig = mids where (_, _, mids, _) = statevar asig kcf res +-- | State variable band-reject filter sbr :: Sig -> Sig -> Sig -> Sig sbr kcf res asig = sides where (_, _, _, sides) = statevar asig kcf res@@ -512,3 +526,157 @@ multiSvfilter (weightLows, wieghtHighs, weightMids) kcf res asig = weightLows * lows + wieghtHighs * highs + weightMids * mids where (highs, lows, mids) = svfilter asig kcf res ++--------------------------------++-- | Zero-delay feedback implementation of 1 pole filter.+--+-- ouputs low-pass and high-pass signals.+--+-- > zdf1 centerFreq asig = (alp, ahp)+zdf1 :: Sig -> Sig -> (Sig, Sig)+zdf1 cfq asig = zdf_1pole_mode asig cfq++-- | Zero-delay feedback implementation of 1 pole low-pass filter.+--+-- > zlp1 centerFreq asig+zlp1 :: Sig -> Sig -> Sig+zlp1 cfq asig = zdf_1pole asig cfq `withSig` 0++-- | Zero-delay feedback implementation of 1 pole high-pass filter.+--+-- > zhp1 centerFreq asig+zhp1 :: Sig -> Sig -> Sig+zhp1 cfq asig = zdf_1pole asig cfq `withSig` 1++-- | Zero-delay feedback implementation of 1 pole allpass filter.+--+-- > zap1 centerFreq asig+zap1 :: Sig -> Sig -> Sig+zap1 cfq asig = zdf_1pole asig cfq `withSig` 2++-- | zero delay feedback 2 pole filter+--+-- > zdf2 centerFreq q asig = (alp, abp, ahp)+zdf2 :: Sig -> Sig -> Sig -> (Sig, Sig, Sig)+zdf2 cfq q asig = zdf_2pole_mode asig cfq (uon 0.5 25 q)++zpole2 :: D -> Sig -> Sig -> Sig -> Sig+zpole2 n cfq q asig = zdf_2pole asig cfq (uon 0.5 25 q) `withSig` 0++-- | zero delay feedback 2 pole Low pass filter. Q is unipolar [0, 1]+--+-- > zlp centerFreq q asig+zlp :: Sig -> Sig -> Sig -> Sig+zlp = zpole2 0++-- | zero delay feedback 2 pole High pass filter. Q is unipolar [0, 1]+--+-- > zhp centerFreq q asig+zhp :: Sig -> Sig -> Sig -> Sig+zhp = zpole2 1++-- | zero delay feedback 2 pole Band pass. Q is unipolar [0, 1]+--+-- > zbp centerFreq q asig+zbp :: Sig -> Sig -> Sig -> Sig+zbp = zpole2 2++-- | Unity-gain bandpass (zero delay feedback 2 pole). Q is unipolar [0, 1]+--+-- > zubp centerFreq q asig+zubp :: Sig -> Sig -> Sig -> Sig+zubp = zpole2 3++-- | zero delay feedback 2 pole Notch (band reject). Q is unipolar [0, 1]+--+-- > zbr centerFreq q asig+zbr :: Sig -> Sig -> Sig -> Sig+zbr = zpole2 4++-- | zero delay feedback 2 pole Allpass filter. Q is unipolar [0, 1]+--+-- > zap centerFreq q asig+zap :: Sig -> Sig -> Sig -> Sig+zap = zpole2 5++-- | zero delay feedback 2 pole Peak filter. Q is unipolar [0, 1]+--+-- > zpeak centerFreq q asig+zpeak :: Sig -> Sig -> Sig -> Sig+zpeak = zpole2 6++-- | Zero-delay feedback implementation of 4 pole ladder filter. Q is unipolar [0, 1]+--+-- > zladder centerFreq q asig+zladder :: Sig -> Sig -> Sig -> Sig+zladder cfq q asig = zdf_ladder asig cfq (uon 0.5 25 q)++-- | Zero-delay feedback implementation of 4 pole diode ladder filter (24 dB/oct) .+-- This filter design was originally used in the EMS VCS3 and was the resonant filter in the Roland TB-303.+--+-- * Q is unipolar [0, 1]+--+-- * saturation - amount to use for non-linear processing. Values > 1 increase the steepness of the NLP curve.+--+-- > diode saturation centerFreq q asig+diode :: D -> Sig -> Sig -> Sig -> Sig+diode isaturation cfq fbk asig = diode_ladder asig cfq (17 * fbk) `withDs` [1, isaturation]++-- | Faster diode, but lesser quality+--+-- > fdiode saturation centerFreq q asig+fdiode :: D -> Sig -> Sig -> Sig -> Sig+fdiode isaturation cfq fbk asig = diode_ladder asig cfq (17 * fbk) `withDs` [2, isaturation]++-- | Linear diode, no saturation involved+--+-- > linDiode centerFreq q asig+linDiode :: Sig -> Sig -> Sig -> Sig+linDiode cfq fbk asig = diode_ladder asig cfq (17 * fbk) `withDs` [0]++-- | Korg35 resonant low-pass filter. Q is unipolar [0, 1]+--+-- > korg_lp saturation centerFreq q asig+korg_lp :: D -> Sig -> Sig -> Sig -> Sig+korg_lp isaturation cfq q asig = k35_lpf asig cfq (uon 1 10 q) `withDs` [1, isaturation]++-- | Korg35 resonant high-pass filter. Q is unipolar [0, 1]+--+-- > korg_hp saturation centerFreq q asig+korg_hp :: D -> Sig -> Sig -> Sig -> Sig+korg_hp isaturation cfq q asig = k35_hpf asig cfq (uon 1 10 q) `withDs` [1, isaturation]++-- | Korg35 resonant band-pass filter. Q is unipolar [0, 1]+--+-- > korg_bp saturation centerFreq q asig+korg_bp :: D -> Sig -> Sig -> Sig -> Sig+korg_bp isaturation cfq q asig = korg_hp isaturation cfq q $ korg_lp isaturation cfq q asig++-- | Linear Korg35 resonant low-pass filter+--+-- > linKorg_lp centerFreq q asig+linKorg_lp :: Sig -> Sig -> Sig -> Sig+linKorg_lp cfq q asig = k35_lpf asig cfq (uon 1 10 q) `withDs` [0]++-- | Linear Korg35 resonant high-pass filter+--+-- > linKorg_hp centerFreq q asig+linKorg_hp :: Sig -> Sig -> Sig -> Sig+linKorg_hp cfq q asig = k35_hpf asig cfq (uon 1 10 q) `withDs` [0]++-- Linear Korg35 resonant band-pass filter+linKorg_bp :: Sig -> Sig -> Sig -> Sig+linKorg_bp cfq q asig = linKorg_hp cfq q $ linKorg_lp cfq q asig++-- | Alias for korg_lp+klp :: D -> Sig -> Sig -> Sig -> Sig+klp = korg_lp++-- | Alias for korg_hp+khp :: D -> Sig -> Sig -> Sig -> Sig+khp = korg_hp++-- | Alias for korg_bp+kbp :: D -> Sig -> Sig -> Sig -> Sig+kbp = korg_bp
src/Csound/Air/Fx.hs view
@@ -1,6 +1,6 @@ {-# Language FlexibleContexts #-} -- | Effects-module Csound.Air.Fx( +module Csound.Air.Fx( -- * Reverbs reverbsc1, rever1, rever2, reverTime, smallRoom, smallHall, largeHall, magicCave,@@ -11,8 +11,8 @@ -- ** Impulse Responce convolution reverbs -- -- | Be careful with volumes. Some IRs can require scaling with really small coefficients like 0.01.- -- - monoIR, stereoIR, stereoIR2, pmonoIR, pstereoIR, pstereoIR2, + --+ monoIR, stereoIR, stereoIR2, pmonoIR, pstereoIR, pstereoIR2, monoIR', stereoIR', stereoIR2', ZConvSpec(..), zconv, zconv', @@ -21,6 +21,11 @@ echo, fvdelay, fvdelays, funDelays, tabDelay, PingPongSpec(..), pingPong, pingPong', csdPingPong, + -- ** Tape echo+ EchoGain, RandomSpreadSig,+ tapeRead, tapeWrite,+ tapeEcho,+ -- * Distortion distortion, @@ -41,12 +46,12 @@ DriveSig, SensitivitySig, BaseCps, Resonance, TimeSig, BitsReductionSig, FoldoverSig, TremWaveSig, RatioSig, FftSize, - fxDistort, stChorus2, fxPhaser, - fxFlanger, analogDelay, fxEcho, fxFilter, + fxDistort, stChorus2, fxPhaser,+ fxFlanger, analogDelay, fxEcho, fxFilter, fxWhite, fxPink, equalizer, eq4, eq7,- fxGain, + fxGain, - fxAnalogDelay, fxDistortion, fxFollower, fxReverse, fxLoFi, fxChorus2, fxAutoPan, fxTrem, fxPitchShifter, fxFreqShifter, {- , + fxAnalogDelay, fxDistortion, fxFollower, fxReverse, fxLoFi, fxChorus2, fxAutoPan, fxTrem, fxPitchShifter, fxFreqShifter, {- , fxRingModulator, , -} fxCompress, @@ -70,12 +75,12 @@ import Csound.Air.Wave(Lfo, unipolar, oscBy, utri, white, pink) import Csound.Air.Filter import Csound.Typed.Plugins hiding(pitchShifterDelay,- fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, + fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, fxPanTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2) import qualified Csound.Typed.Plugins as P(pitchShifterDelay,- fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi, - fxPanTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong)+ fxAnalogDelay, fxDistortion, fxEnvelopeFollower, fxFlanger, fxFreqShifter, fxLoFi,+ fxPanTrem, fxPhaser, fxPitchShifter, fxReverse, fxRingModulator, fxChorus2, fxPingPong, tapeRead, tapeWrite) -- | Mono version of the cool reverberation opcode reverbsc. --@@ -90,7 +95,7 @@ -- | Reverb with given time. reverTime :: DelayTime -> Sig -> Sig-reverTime dt a = nreverb a dt 0.3 +reverTime dt a = nreverb a dt 0.3 -- | Mono reverb (based on reverbsc) --@@ -139,25 +144,25 @@ --------------------------------------------------------------------------------- --- | An alias for +-- | An alias for -- -- > let room dryWet asig = mixAt dryWet smallRoom2 asig room :: MixAt Sig2 Sig2 a => Sig -> a -> AtOut Sig2 Sig2 a room mx ain = mixAt mx smallRoom2 ain --- | An alias for +-- | An alias for -- -- > let room dryWet asig = mixAt dryWet smallHall2 asig chamber :: MixAt Sig2 Sig2 a => Sig -> a -> AtOut Sig2 Sig2 a chamber mx ain = mixAt mx smallHall2 ain --- | An alias for +-- | An alias for -- -- > let room dryWet asig = mixAt dryWet largeHall2 asig hall :: MixAt Sig2 Sig2 a => Sig -> a -> AtOut Sig2 Sig2 a hall mx ain = mixAt mx largeHall2 ain --- | An alias for +-- | An alias for -- -- > let room dryWet asig = mixAt dryWet magicCave2 asig cave :: MixAt Sig2 Sig2 a => Sig -> a -> AtOut Sig2 Sig2 a@@ -210,8 +215,8 @@ pstereoIR2 :: (FilePath, FilePath) -> Sig2 -> Sig2 pstereoIR2 (file1, file2) (ainL, ainR) = (pmonoIR file1 ainL, pmonoIR file2 ainR)- + --------------------------------------------------------------------------------- -- Delays @@ -233,7 +238,7 @@ echo :: MaxDelayTime -> Feedback -> Sig -> Sig echo len fb x = x + flanger x (sig len) fb `withD` (len + 0.005) --- | Delay with feedback. +-- | Delay with feedback. -- -- > fdelay maxDelayLength delayLength feedback balance fvdelay :: MaxDelayTime -> DelayTime -> Feedback -> Sig -> Sig@@ -245,12 +250,12 @@ -- > fdelay maxDelayLength delays balance asig fvdelays :: MaxDelayTime -> [(DelayTime, Feedback)] -> Balance -> Sig -> SE Sig fvdelays len dtArgs mx a = funDelays len (zip dts fs) mx a- where + where (dts, fbks) = unzip dtArgs fs = map (*) fbks --- | Generic multitap delay. It's just like @fvdelays@ but instead of constant feedbackLevel +-- | Generic multitap delay. It's just like @fvdelays@ but instead of constant feedbackLevel -- it expects a function for processing a delayed signal on the tap. -- -- > fdelay maxDelayLength delays balance asig@@ -259,7 +264,7 @@ _ <- delayr len aDels <- mapM deltap3 dts delayw $ a + sum (zipWith ($) fs aDels)- return $ a + mx * sum aDels + return $ a + mx * sum aDels where (dts, fs) = unzip dtArgs -- | Delay for functions that use some table (as a buffer). As granular synth or mincer.@@ -267,13 +272,13 @@ -- > tabDelay fn maxDelayTime delayTime feedback balance asig tabDelay :: (Tab -> Sig -> SE Sig) -> MaxDelayTime -> DelayTime -> Feedback -> Balance -> Sig -> SE Sig tabDelay go maxLength delTim kfeed kbalance asig = do- buf <- newTab tabLen + buf <- newTab tabLen ptrRef <- newRef (0 :: Sig)- aresRef <- newRef (0 :: Sig) + aresRef <- newRef (0 :: Sig) ptr <- readRef ptrRef when1 (ptr >=* sig tabLen) $ do writeRef ptrRef 0- ptr <- readRef ptrRef + ptr <- readRef ptrRef let kphs = (ptr / sig tabLen) - (delTim/(sig $ tabLen / getSampleRate)) awet <-go buf (wrap kphs 0 1)@@ -284,37 +289,37 @@ where tabLen = tabSizeSecondsPower2 maxLength --- | Aux parameters for ping pong delay. +-- | Aux parameters for ping pong delay. -- They are maximum delay time, low pass filter center frequency and Pan width. -- The defaults are @(5 sec, 3500, 0.3)@. data PingPongSpec = PingPongSpec { pingPongMaxTime :: MaxDelayTime, pingPongDamp :: Sig,- pingPongWidth :: Sig + pingPongWidth :: Sig } instance Default PingPongSpec where def = PingPongSpec { pingPongMaxTime = 5, pingPongDamp = 3500,- pingPongWidth = 0.6 + pingPongWidth = 0.6 } --- | Ping-pong delay. +-- | Ping-pong delay. -- -- > pingPong delayTime feedback mixLevel pingPong :: DelayTime -> Feedback -> Balance -> Sig2 -> Sig2 pingPong delTime feedback mixLevel (ainL, ainR) = pingPong' def delTime feedback mixLevel (ainL, ainR) --- | Ping-pong delay with miscellaneous arguments. +-- | Ping-pong delay with miscellaneous arguments. -- -- > pingPong' spec delayTime feedback mixLevel-pingPong' :: PingPongSpec -> DelayTime -> Feedback -> Balance -> Sig2 -> Sig2 -pingPong' (PingPongSpec maxTime damp width) delTime feedback mixLevel (ainL, ainR) = +pingPong' :: PingPongSpec -> DelayTime -> Feedback -> Balance -> Sig2 -> Sig2+pingPong' (PingPongSpec maxTime damp width) delTime feedback mixLevel (ainL, ainR) = csdPingPong maxTime delTime damp feedback width mixLevel (ainL, ainR) -- | Ping-pong delay defined in csound style. All arguments are present (nothing is hidden).--- +-- -- > csdPingPong maxTime delTime damp feedback width mixLevel (ainL, ainR) csdPingPong :: MaxDelayTime -> DelayTime -> Sig -> Feedback -> Sig -> Balance -> Sig2 -> Sig2 csdPingPong maxTime delTime damp feedback width mixLevel (ainL, ainR) = P.fxPingPong maxTime mixLevel width damp delTime feedback (ainL, ainR)@@ -324,7 +329,7 @@ {- substituted with Csound UDO implementation csdPingPong :: MaxDelayTime -> DelayTime -> Sig -> Feedback -> Sig -> Balance -> Sig2 -> SE Sig2 csdPingPong maxTime delTime damp feedback width mixLevel (ainL, ainR) = do- afirst <- offsetDelay ainL + afirst <- offsetDelay ainL atapL <- channelDelay afirst atapR <- channelDelay ainR return $ mixControl $ widthControl afirst (atapL, atapR)@@ -355,7 +360,7 @@ -- Distortion --- | Distortion. +-- | Distortion. -- -- > distort distLevel asig distortion :: Sig -> Sig -> Sig@@ -387,7 +392,7 @@ -- | First order phaser. phase1 :: Sig -> Lfo -> Feedback -> Balance -> Sig -> Sig-phase1 ord alfo fbk mx asig = ntrpol asig (phaser1 asig (20 + unipolar alfo) ord fbk) mx +phase1 ord alfo fbk mx asig = ntrpol asig (phaser1 asig (20 + unipolar alfo) ord fbk) mx -- | Second order phaser. Sweeping gaps in the timbre are placed harmonicaly harmPhase :: Sig -> Lfo -> Sig -> Sig -> Feedback -> Balance -> Sig -> Sig@@ -408,7 +413,7 @@ logScale steep (min, max) a = scale (logcurve a steep) max min dryWetMix :: Sig -> (Sig, Sig)-dryWetMix kmix = (kDry, kWet) +dryWetMix kmix = (kDry, kWet) where iWet = setSize 1024 $ elins [0, 1, 1] iDry = setSize 1024 $ elins [1, 1, 0]@@ -419,7 +424,7 @@ fxWet mix ain aout = mul dry ain + mul wet aout where (dry, wet) = dryWetMix mix --- Distortion +-- Distortion -- | Distortion --@@ -444,7 +449,7 @@ -- > stChorus2 mix rate depth width sigIn stChorus2 :: Balance -> RateSig -> DepthSig -> WidthSig -> Sig2 -> Sig2 stChorus2 kmix krate' kdepth kwidth (al, ar) = fxWet kmix (al, ar) (aoutL, aoutR)- where + where krate = expScale 20 (0.001, 7) krate' ilfoshape = setSize 131072 $ sines4 [(1, 0.5, 0, 0.5)] kporttime = linseg [0, 0.001, 0.02]@@ -469,13 +474,13 @@ -- | Filter effect (a pair of butterworth low and high pass filters). ----- > fxFilter lowPassfFreq highPassFreq gain +-- > fxFilter lowPassfFreq highPassFreq gain fxFilter :: Sig -> Sig -> Sig -> Sig -> Sig-fxFilter kLPF' kHPF' kgain' ain = mul kgain $ app (blp kLPF) $ app (bhp kHPF) $ ain - where +fxFilter kLPF' kHPF' kgain' ain = mul kgain $ app (blp kLPF) $ app (bhp kHPF) $ ain+ where app f = f . f- kLPF = scaleFreq kLPF' - kHPF = scaleFreq kHPF' + kLPF = scaleFreq kLPF'+ kHPF = scaleFreq kHPF' kgain = scale kgain' 20 0 scaleFreq x = expScale 4 (20, 20000) x @@ -543,30 +548,30 @@ kporttime = linseg [0,0.001,0.1] kTime = portk ktime (kporttime*3) --- | Instrument plays an input signal in different modes. --- The segments of signal can be played back and forth. --- +-- | Instrument plays an input signal in different modes.+-- The segments of signal can be played back and forth.+-- -- > trackerSplice maxLength segLength mode--- +-- -- * @maxLength@ -- the maximum length of the played segment (in seconds) -- -- * @segLength@ -- the segment length in seconds -- -- * @mode@ -- mode of the playing. If it's 1 - only a part of the sample is plyaed and -- it's played forward. The portion of the signal starts from the current playback point.--- It lasts for segLength. If it's 2 - the segment is played in reverse. +-- It lasts for segLength. If it's 2 - the segment is played in reverse. -- Other values produce the normal input signal. -- -- Original author: Rory Walsh -- -- Example: ----- > main = dac $ do +-- > main = dac $ do -- > let ev ch1 ch2 dt = fmap (\x -> (x, dt)) $ mconcat [--- > fmap (const 1.5) $ charOn ch1 --- > , fmap (const 2.5) $ charOn ch2 +-- > fmap (const 1.5) $ charOn ch1+-- > , fmap (const 2.5) $ charOn ch2 -- > , fmap (const 0) $ charOff ch1 <> charOff ch2]--- > +-- > -- > (k, dt) <- stepper (0, 0.1) $ ev 'q' 'w' 0.1 <> ev 'a' 's' 0.2 <> ev 'z' 'x' 0.4 -- > mul 1.3 $ trackerSplice 0.8 dt (int' k) $ fst $ loopWav 1 "drumLoop.wav" trackerSplice :: D -> Sig -> Sig -> Sig -> SE Sig@@ -585,10 +590,10 @@ let apos = samphold (andx1 * sig (ftlen buf)) (sig ksamp) whens [- (kmode >=* 1 &&* kmode `lessThan` 2, do - kindx <- readRef kindxRef - writeRef kindxRef $ ifB (kindx >* segLength) 0 (kindx + 1) + (kmode >=* 1 &&* kmode `lessThan` 2, do kindx <- readRef kindxRef+ writeRef kindxRef $ ifB (kindx >* segLength) 0 (kindx + 1)+ kindx <- readRef kindxRef when1 (kindx + apos >* sig (ftlen buf)) $ do writeRef kindxRef $ (-segLength) @@ -596,12 +601,12 @@ writeRef aoutRef $ table (apos + kindx) buf `withDs` [0, 1] writeRef ksampRef 0- ), (kmode >=* 2 &&* kmode `lessThan` 3, do + ), (kmode >=* 2 &&* kmode `lessThan` 3, do kindx <- readRef kindxRef writeRef kindxRef $ ifB ((kindx+apos) <=* 0) (sig (ftlen buf) - apos) (kindx-1) kindx <- readRef kindxRef writeRef aoutRef $ table (apos+kindx) buf `withDs` [0, 1]- writeRef ksampRef 0 + writeRef ksampRef 0 )] (do writeRef ksampRef 1 writeRef aoutRef asig)@@ -619,9 +624,9 @@ -- rename the arguments and comment -- | PitchShifterDelay--- +-- -- A pitch shifter effect that employs delay lines--- +-- -- > pitchShifterDelay maxDelayTime delayTime (feedback1, feedback2) transposeRatio ain -- -- Arguments@@ -630,11 +635,11 @@ -- -- * @transposeRatio @ -- pitch transposition (in semitones) ----- * @delayTime @ -- delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt) +-- * @delayTime @ -- delay time employed by the pitch shifter effect (should be within the range ksmps/sr and imaxdlt) -- -- * @feedback1 @ -- feedback using method 1 (output from delay taps are fed back directly into their own buffers before enveloping and mixing) ----- * @feedback2 @ -- feedback using method 2 (enveloped and mixed output from both taps is fed back into both buffers)-- +-- * @feedback2 @ -- feedback using method 2 (enveloped and mixed output from both taps is fed back into both buffers)-- -- -- * @ain @ -- input audio to be pitch shifted pitchShifterDelay :: MaxDelayTime -> (Feedback, Feedback) -> DelayTime -> Sig -> Sig -> Sig@@ -663,7 +668,7 @@ type BaseCps = Sig type Resonance = Sig --- | Envelope follower. +-- | Envelope follower. -- -- > fxFollower sensitivity baseFrequencyRatio resonance ain --@@ -688,9 +693,9 @@ fxReverse ktime = P.fxReverse ktime -- | A flanger effect following the typical design of a so called 'stomp box'--- --- > fxFlanger rate depth delayTime feedback ain = --+-- > fxFlanger rate depth delayTime feedback ain =+-- -- Arguments -- -- * @rate @ -- rate control of the lfo of the effect *NOT IN HERTZ* (range 0 to 1)@@ -708,18 +713,18 @@ -- | Phaser -- -- An phase shifting effect that mimics the design of a so called 'stomp box'--- +-- -- > fxPhaser rate depth freq fback ain--- +-- -- Arguments:--- +-- -- * @rate @ -- rate of lfo of the effect (range 0 to 1) -- -- * @depth @ -- depth of lfo of the effect (range 0 to 1) -- -- * @freq @ -- centre frequency of the phase shifting effect in octaves (suggested range 6 to 11) ----- * @fback @ -- feedback and therefore intensity of the effect (range 0 to 1) +-- * @fback @ -- feedback and therefore intensity of the effect (range 0 to 1) -- -- * @ain @ -- input audio to be pitch shifted fxPhaser :: RateSig -> DepthSig -> BaseCps -> Feedback -> Sig -> Sig@@ -729,29 +734,29 @@ type FoldoverSig = Sig -- | LoFi--- +-- -- 'Low Fidelity' distorting effects of bit reduction and downsampling (foldover)--- +-- -- > fxLoFi bits fold ain = ...--- +-- -- Arguments--- +-- -- * @bits @ -- bit depth reduction (range 0 to 1) ----- * @fold @ -- amount of foldover (range 0 to 1) +-- * @fold @ -- amount of foldover (range 0 to 1) -- -- * @ain @ -- input audio to have low fidelity distortion effects applied fxLoFi :: BitsReductionSig -> FoldoverSig -> Sig -> Sig fxLoFi kbits kfold ain = P.fxLoFi (0.6 * kbits) kfold ain -- | Stereo Chorus--- +-- -- A stereo chorus effect--- +-- -- > fxChorus2 rate depth width (ainLeft, ainRight)--- +-- -- Arguments--- +-- -- * @rate @ -- rate control of the lfo of the effect *NOT IN HERTZ* (range 0 to 1) -- -- * @depth @ -- depth of the lfo of the effect (range 0 to 1)@@ -765,11 +770,11 @@ type TremWaveSig = Sig -- | Auto pan--- +-- -- > fxAutoPan wave rate depth ain--- +-- -- ; Arguments:--- +-- -- * @wave @ -- waveform used by the lfo (0=sine 1=triangle 2=square) -- -- * @rate @ -- rate control of the lfo of the effect *NOT IN HERTZ* (range 0 to 1)@@ -783,13 +788,13 @@ fxAutoPan tremWave kdepth krate = P.fxPanTrem kdepth krate 0 tremWave -- | Tremolo--- +-- -- tremolo effect--- +-- -- > fxTrem wave rate depth ain--- +-- -- ; Arguments:--- +-- -- * @wave @ -- waveform used by the lfo (0=sine 1=triangle 2=square) -- -- * @rate @ -- rate control of the lfo of the effect *NOT IN HERTZ* (range 0 to 1)@@ -806,20 +811,20 @@ type FftSize = D -- | PitchShifter--- +-- -- A pitch shifter effect based on FFT technology--- +-- -- > fxPitchShifter fftSize mixRatio transposeRatio feedback ain--- +-- -- Arguments--- +-- -- * @fftSize @ -- size for FFT analysis (good values 1024, 512, 256, 2048), the higher values introduce latency but lower values are less accurate. -- -- * @mix @ -- dry / wet mix of the output signal (range 0 to 1) -- -- * @transpose@ -- pitch ratio ----- * @feedback @ -- control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1) +-- * @feedback @ -- control of the amount of output signal fed back into the input of the effect (suggested range 0 to 1) -- -- * @ain @ -- input audio to be pitch shifted fxPitchShifter :: FftSize -> Balance -> RatioSig -> Feedback -> Sig -> Sig@@ -847,7 +852,7 @@ -- > fxCompress thresh (loknee, hiknee) ratio (att, rel) gain ain fxCompress :: Sig -> (Sig, Sig) -> Sig -> (Sig, Sig) -> Sig -> Sig -> Sig fxCompress thresh (loknee, hiknee) ratio (att, rel) gain x = gain' * compress x x thresh' loknee' hiknee' ratio' att' rel' 0.05- where + where gain' = ampdb $ onLin (-36, 36) gain thresh' = onLin (0, 120) thresh att' = onExp (0, 1) att@@ -858,3 +863,53 @@ onLin (min, max) val = min + val * (max - min) onExp (min, max) val = scale (expcurve val 4) max min++-------------------------------+-- tape echo++{-}+opcode TapeEcho4, a, akkkkk+ aIn, kDelay, kEchoGain, kFbGain, kTone, kRandomSpread xin++ aDummy delayr 16+ aEcho1 tapeRead aIn, kDelay, kRandomSpread+ aEcho2 tapeRead aIn, (kDelay * 2), kRandomSpread+ aEcho3 tapeRead aIn, (kDelay * 4), kRandomSpread+ aEcho4 tapeRead aIn, (kDelay * 8), kRandomSpread+ aOut = aIn + kEchoGain * aEcho1 + 0.5 * kEchoGain * aEcho2 + 0.25 * kEchoGain * aEcho3 + 0.2 * kEchoGain * aEcho4++ aOut tone aOut, kTone+ tapeWrite aIn, aOut, kFbGain+ xout aOut+endop+-}++type EchoGain = Sig+type RandomSpreadSig = Sig++-- | Tape echo - simulates tape echo/delay+--+-- > tapeEcho size feedback echoGain tone randomSpread ain+--+-- * size - how many heads in the tape+-- * feedback+-- * echo gain+-- * tone - normalized center frequency of the filter (0 to 1)+-- * randomSpread - quality of the tape (the higher - the worser)+tapeEcho :: Int -> DelayTime -> Feedback -> EchoGain -> ToneSig -> RandomSpreadSig -> Sig -> SE Sig+tapeEcho n dt fb echoGain ktoneNorm spread ain = do+ aDummy <- delayr minDt+ aout <- fmap ((\echoes -> tone (ain + echoGain * echoes) ktone) . sum . zipWith (*) halves) $+ mapM (\step -> tapeRead ain (dt * step) spread) doubles+ tapeWrite ain aout fb+ return aout+ where+ halves = take n $ iterate ( / 2) 1+ doubles = take n $ iterate ( * 2) 1++ minDt = int $ 16 `max` (n * 4)++ ktone = fromNormTone ktoneNorm++fromNormTone :: Sig -> Sig+fromNormTone ktoneNorm = portk (scale (expcurve ktoneNorm 4) 12000 100) 0.1
src/Csound/Air/Fx/FxBox.hs view
@@ -3,6 +3,7 @@ -- | A friendly family of effects. These functions are kindly provided by Iain McCurdy (designed in Csound). module Csound.Air.Fx.FxBox( adele, pongy, tort, fowler, revsy, flan, phasy, crusher, chory, pany, oscPany, triPany, sqrPany, tremy, oscTremy, triTremy, sqrTremy, ringo, EnvelopeModSig,+ magnus, -- * Presets -- | For all presets we have 5 levels of strength. They are signified by numbers from 1 to 5. Also for some effects (delay and distortion)@@ -135,6 +136,9 @@ uiAdele1b, uiAdele2b, uiAdele3b, uiAdele4b, uiAdele5b, uiAdele1m, uiAdele2m, uiAdele3m, uiAdele4m, uiAdele5m, + -- ** Tape echo+ uiMagnus,+ -- ** Ping Pong Delay uiPongy1, uiPongy2, uiPongy3, uiPongy4, uiPongy5, uiPongy1b, uiPongy2b, uiPongy3b, uiPongy4b, uiPongy5b,@@ -201,7 +205,9 @@ import Csound.Air.Fx(Balance, DelayTime, Feedback, ToneSig, SensitivitySig, BaseCps, Resonance, DepthSig, RateSig, TremWaveSig, FoldoverSig, BitsReductionSig, DriveSig, TimeSig, WidthSig,- rever2, pingPong, pingPong', PingPongSpec(..))+ rever2, pingPong, pingPong', PingPongSpec(..),+ EchoGain, RandomSpreadSig,+ tapeEcho) import Csound.Air.Live(fxBox, fxColor) import Csound.Air.Wav(toMono)@@ -462,6 +468,10 @@ adele4m = adeleByM size4 adele5m = adeleByM size5 +-- Tape echo+magnus :: Sigs a => Int -> DelayTime -> Feedback -> EchoGain -> ToneSig -> RandomSpreadSig -> a -> SE a+magnus size delt fb echoGain ktone randomSpread = bindSig (tapeEcho size delt fb echoGain ktone randomSpread)+ -- Ping Pong delay -- | Ping-pong delay@@ -763,6 +773,13 @@ uiAdele3m = uiAdeleByM size3 uiAdele4m = uiAdeleByM size4 uiAdele5m = uiAdeleByM size5++-- Tape echo++uiMagnus :: Sigs a => Int -> Double -> Double -> Double -> Double -> Double -> Source (Fx a)+uiMagnus size initDelayTime initFeedback initEchoGain initTone initSpread = mapSource bindSig $ paintTo adeleColor $ fxBox "Tape echo" fx True [("del time", initDelayTime), ("fbk", initFeedback), ("echo gain", initEchoGain), ("tone", initTone), ("tape qty", initSpread)]+ where+ fx [delayTime, feedback, echoGain, tone, spread] = magnus size delayTime feedback echoGain tone spread -- Ping-pong delay
src/Csound/Air/Wav.hs view
@@ -127,7 +127,7 @@ readSnd :: String -> (Sig, Sig) readSnd fileName | isMp3 fileName = mp3in (text fileName)- | otherwise = diskin2 (text fileName) 1+ | otherwise = diskin2 (text fileName) -- | Reads stereo signal from the sound-file (wav or mp3 or aiff) -- and loops it with the given period (in seconds).@@ -142,24 +142,24 @@ -- | Reads the wav file with the given speed (if speed is 1 it's a norma playback). -- We can use negative speed to read file in reverse. readWav :: Sig -> String -> (Sig, Sig)-readWav speed fileName = diskin2 (text fileName) speed+readWav speed fileName = diskin2 (text fileName) `withSig` speed -- | Reads th wav file and loops over it. loopWav :: Sig -> String -> (Sig, Sig)-loopWav speed fileName = flip withDs [0, 1] $ ar2 $ diskin2 (text fileName) speed+loopWav speed fileName = flip withDs [0, 1] $ ar2 $ diskin2 (text fileName) `withSig` speed -- | Reads a segment from wav file. readSegWav :: D -> D -> Sig -> String -> (Sig, Sig)-readSegWav start end speed fileName = takeSnd (end - start) $ diskin2 (text fileName) speed `withDs` [start, 1]+readSegWav start end speed fileName = takeSnd (end - start) $ (diskin2 (text fileName) `withSig` speed) `withDs` [start, 1] -- | Reads the wav file with the given speed (if speed is 1 it's a norma playback). -- We can use negative speed to read file in reverse. Scales the tempo with first argument. tempoReadWav :: Sig -> String -> (Sig, Sig)-tempoReadWav speed fileName = mapSig (scaleSpec (1 / abs speed)) $ diskin2 (text fileName) speed+tempoReadWav speed fileName = mapSig (scaleSpec (1 / abs speed)) $ diskin2 (text fileName) `withSig` speed -- | Reads th wav file and loops over it. Scales the tempo with first argument. tempoLoopWav :: Sig -> String -> (Sig, Sig)-tempoLoopWav speed fileName = mapSig (scaleSpec (1 / abs speed)) $ flip withDs [0, 1] $ ar2 $ diskin2 (text fileName) speed+tempoLoopWav speed fileName = mapSig (scaleSpec (1 / abs speed)) $ flip withDs [0, 1] $ ar2 $ diskin2 (text fileName) `withSig` speed -- Mono @@ -167,7 +167,7 @@ readSnd1 :: String -> Sig readSnd1 fileName | isMp3 fileName = toMono $ readSnd fileName- | otherwise = diskin2 (text fileName) 1+ | otherwise = diskin2 (text fileName) -- | The mono variant of the function @loopSndBy@. loopSndBy1 :: D -> String -> Sig@@ -179,15 +179,15 @@ -- | The mono variant of the function @readWav@. readWav1 :: Sig -> String -> Sig-readWav1 speed fileName = diskin2 (text fileName) speed+readWav1 speed fileName = diskin2 (text fileName) `withSig` speed -- | The mono variant of the function @loopWav@. loopWav1 :: Sig -> String -> Sig-loopWav1 speed fileName = flip withDs [0, 1] $ diskin2 (text fileName) speed+loopWav1 speed fileName = flip withDs [0, 1] $ diskin2 (text fileName) `withSig` speed -- | Reads a segment from wav file. readSegWav1 :: D -> D -> Sig -> String -> Sig-readSegWav1 start end speed fileName = takeSnd (end - start) $ diskin2 (text fileName) speed `withDs` [start, 1]+readSegWav1 start end speed fileName = takeSnd (end - start) $ diskin2 (text fileName) `withSig` speed `withDs` [start, 1] -- | Reads the mono wav file with the given speed (if speed is 1 it's a norma playback). -- We can use negative speed to read file in reverse. Scales the tempo with first argument.@@ -278,44 +278,6 @@ ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- -- mincer---- | mincer — Phase-locked vocoder processing.------ mincer implements phase-locked vocoder processing--- using function tables containing sampled-sound sources,--- with GEN01, and mincer will accept deferred allocation tables.------ This opcode allows for time and frequency-independent scaling.--- Time is controlled by a time index (in seconds) to the function--- table position and can be moved forward and backward at any--- chosen speed, as well as stopped at a given position ("frozen").--- The quality of the effect is generally improved with phase locking switched on.------ > asig mincer atimpt, kamp, kpitch, ktab, klock[,ifftsize,idecim]------ csound doc: <http://www.csounds.com/manual/html/mincer.html>-mincer :: Sig -> Sig -> Sig -> Tab -> Sig -> Sig-mincer b1 b2 b3 b4 b5 = Sig $ f <$> unSig b1 <*> unSig b2 <*> unSig b3 <*> unTab b4 <*> unSig b5- where f a1 a2 a3 a4 a5 = opcs "mincer" [(Ar,[Ar,Kr,Kr,Kr,Kr,Ir,Ir])] [a1,a2,a3,a4,a5]---- | temposcal — Phase-locked vocoder processing with onset detection/processing, 'tempo-scaling'.------ temposcal implements phase-locked vocoder processing using function tables containing--- sampled-sound sources, with GEN01, and temposcal will accept deferred allocation tables.------ This opcode allows for time and frequency-independent scaling. Time is advanced internally,--- but controlled by a tempo scaling parameter; when an onset is detected, timescaling is--- momentarily stopped to avoid smearing of attacks. The quality of the effect is generally--- improved with phase locking switched on.------ temposcal will also scale pitch, independently of frequency, using a transposition factor (k-rate).------ > asig temposcal ktimescal, kamp, kpitch, ktab, klock [,ifftsize, idecim, ithresh]------ csound doc: <http://www.csounds.com/manual/html/temposcal.html>-temposcal :: Sig -> Sig -> Sig -> Tab -> Sig -> Sig-temposcal b1 b2 b3 b4 b5 = Sig $ f <$> unSig b1 <*> unSig b2 <*> unSig b3 <*> unTab b4 <*> unSig b5- where f a1 a2 a3 a4 a5 = opcs "temposcal" [(Ar,[Kr,Kr,Kr,Kr,Kr,Ir,Ir,Ir])] [a1,a2,a3,a4,a5] -- | Mincer. We can playback a table and scale by tempo and pitch. --
src/Csound/Air/Wave.hs view
@@ -1,8 +1,8 @@--- | Basic waveforms that are used most often. +-- | Basic waveforms that are used most often. -- A waveform function takes in a time varied frequency (in Hz). module Csound.Air.Wave (- Wave, - + Wave,+ -- * Bipolar osc, oscBy, saw, isaw, pulse, sqr, pw, tri, ramp, blosc, @@ -10,7 +10,7 @@ osc', oscBy', saw', isaw', pulse', sqr', pw', tri', ramp', blosc', -- ** With random phase- rndOsc, rndOscBy, rndSaw, rndIsaw, rndPulse, rndSqr, rndPw, rndTri, rndRamp, rndBlosc, + rndOsc, rndOscBy, rndSaw, rndIsaw, rndPulse, rndSqr, rndPw, rndTri, rndRamp, rndBlosc, rndPhs, -- ** Raw analog waves (no band limiting)@@ -24,7 +24,7 @@ uosc', uoscBy', usaw', uisaw', upulse', usqr', upw', utri', uramp', ublosc', -- ** With random phase- urndOsc, urndOscBy, urndSaw, urndIsaw, urndPulse, urndSqr, urndPw, urndTri, urndRamp, urndBlosc, + urndOsc, urndOscBy, urndSaw, urndIsaw, urndPulse, urndSqr, urndPw, urndTri, urndRamp, urndBlosc, -- ** Raw analog waves (no band limiting) -- | Analogue-like waves with no band-limiting. Can be useful for LFOs.@@ -49,7 +49,7 @@ urspline, birspline, -- * Buzzes- buz, gbuz, buz', gbuz' + buz, gbuz, buz', gbuz' ) where import Csound.Typed@@ -61,7 +61,7 @@ -- | A pure tone (sine wave). osc :: Sig -> Sig-osc cps = oscil3 1 cps sine +osc cps = oscil3 1 cps sine -- | A pure tone (sine wave) with initial phase (the first argiment). osc' :: D -> Sig -> Sig@@ -119,7 +119,7 @@ -- | Unipolar random splines. -- It generates the splines with unipolar output (ranges from 0 to 1).--- Arguments affect the frequency for generation of new values. +-- Arguments affect the frequency for generation of new values. -- -- > urspline cpsMin cpsMax urspline :: Sig -> Sig -> SE Sig@@ -127,7 +127,7 @@ -- | Bipolar random splines. -- It generates the splines with bipolar output (ranges from -1 to 1).--- Arguments affect the frequency for generation of new values. +-- Arguments affect the frequency for generation of new values. -- -- > birspline cpsMin cpsMax birspline :: Sig -> Sig -> SE Sig@@ -177,13 +177,13 @@ -- unipolar oscils with phase control unipolar' :: (D -> Sig -> Sig) -> (D -> Sig -> Sig)-unipolar' f phs cps = unipolar $ f phs cps +unipolar' f phs cps = unipolar $ f phs cps uosc' = unipolar' osc'-uoscBy' a = unipolar' (oscBy' a) +uoscBy' a = unipolar' (oscBy' a) usaw' = unipolar' saw'-uisaw' = unipolar' isaw' -upulse' = unipolar' pulse' +uisaw' = unipolar' isaw'+upulse' = unipolar' pulse' usqr' = unipolar' sqr' upw' a = unipolar' (pw' a) utri' = unipolar' tri'@@ -199,7 +199,7 @@ rndOsc = rndPhs osc' rndOscBy a = rndPhs (oscBy' a)-rndSaw = rndPhs saw' +rndSaw = rndPhs saw' rndIsaw = rndPhs isaw' rndPulse = rndPhs pulse' rndSqr = rndPhs sqr'@@ -213,7 +213,7 @@ urndOsc = rndPhs uosc' urndOscBy a = rndPhs (uoscBy' a)-urndSaw = rndPhs usaw' +urndSaw = rndPhs usaw' urndIsaw = rndPhs uisaw' urndPulse = rndPhs upulse' urndSqr = rndPhs usqr'@@ -228,13 +228,13 @@ -- | Constant random signal. It updates random numbers with given frequency. ----- > constRnd freq +-- > constRnd freq rndh :: Sig -> SE Sig rndh = randh 1 -- | Linear random signal. It updates random numbers with given frequency. ----- > rndi freq +-- > rndi freq rndi :: Sig -> SE Sig rndi = randi 1 @@ -247,7 +247,7 @@ urndi = fmap unipolar . rndi -- | White noise.-white :: SE Sig +white :: SE Sig white = noise 1 0 -- | Pink noise.@@ -273,26 +273,26 @@ -- -- > detune (semitone 2 * cent 15) osc detune :: Sig -> (Sig -> a) -> (Sig -> a)-detune k f cps = f (k * cps) +detune k f cps = f (k * cps) -------------------------------------------------------------------------- -linRange n amount = fmap (\x -> amount * sig (2 * double x - 1)) [0, (1 / fromIntegral n) .. 1] +linRange n amount = fmap (\x -> amount * sig (2 * double x - 1)) [0, (1 / fromIntegral n) .. 1] --- | Unision by Hertz. It creates n oscillators that are playing +-- | Unision by Hertz. It creates n oscillators that are playing -- the same pitch slightly detuned. The oscillatos's pitch is evenly distributed in Hz. -- -- > multiHz numberOfUnits amountHz wave-multiHz :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a) +multiHz :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a) multiHz n amount f cps = mean $ fmap (f . (cps + )) $ linRange n amount --- | Unision by Cents. It creates n oscillators that are playing +-- | Unision by Cents. It creates n oscillators that are playing -- the same pitch slightly detuned. The oscillatos's pitch is evenly distributed in cents. -- -- > multiCent numberOfUnits amountCent wave-multiCent :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a) +multiCent :: Fractional a => Int -> Sig -> (Sig -> a) -> (Sig -> a) multiCent n amount f cps = mean $ fmap (f . (cps * ) . cent) $ linRange n amount- + -- | Oscillators are detuned randomly in the given interval. -- -- > multiRnd numberOfUnits amountCent wave
src/Csound/Air/Wave/Sync.hs view
@@ -29,7 +29,7 @@ -- *** With absolute slave frequency rawTriSyncAbs, rawSqrSyncAbs, rawSawSyncAbs, rawPwSyncAbs, rawTriSyncAbsBy, rawSqrSyncAbsBy, rawSawSyncAbsBy, rawPwSyncAbsBy,- + -- * Soft sync -- *** With relative slave frequency@@ -55,7 +55,7 @@ rndPhsSync f ratio cps = fmap (\x -> f x ratio cps) $ rnd 1 -- | Hard sync with saw waveform and randomized phase.-rndSawSync :: Sig -> Sig -> SE Sig +rndSawSync :: Sig -> Sig -> SE Sig rndSawSync = rndPhsSync sawSync' -- | Hard sync with integral saw waveform and randomized phase.@@ -63,11 +63,11 @@ rndIsawSync = rndPhsSync isawSync' -- | Hard sync with pulse waveform and randomized phase.-rndPulseSync :: Sig -> Sig -> SE Sig +rndPulseSync :: Sig -> Sig -> SE Sig rndPulseSync = rndPhsSync pulseSync' -- | Hard sync with square waveform and randomized phase.-rndSqrSync :: Sig -> Sig -> SE Sig +rndSqrSync :: Sig -> Sig -> SE Sig rndSqrSync = rndPhsSync sqrSync' -- | Hard sync with triangle waveform and randomized phase.@@ -75,7 +75,7 @@ rndTriSync = rndPhsSync triSync' -- | Hard sync with band-limited table waveform waveform and randomized phase.-rndBloscSync :: Tab -> Sig -> Sig -> SE Sig +rndBloscSync :: Tab -> Sig -> Sig -> SE Sig rndBloscSync t = rndPhsSync (bloscSync' t) -------------------------------------------------------------------------@@ -161,14 +161,14 @@ -- | Hard-sync with non-bandlimited waves. oscSyncAbsBy :: Tab -> SyncSmooth -> Sig -> Sig -> Sig oscSyncAbsBy tab smoothType slaveCps cps = (\smoothFun -> syncOsc smoothFun tab (ar slaveCps) (ar cps)) $ case smoothType of- RawSync -> (\_ _ -> 1) - SawSync -> (\amaster _ -> (1 - amaster)) - TriSync -> (const $ readSync uniTriTab) - TrapSync -> (const $ readSync uniTrapTab) - UserSync gen -> (const $ readSync gen) + RawSync -> (\_ _ -> 1)+ SawSync -> (\amaster _ -> (1 - amaster))+ TriSync -> (const $ readSync uniTriTab)+ TrapSync -> (const $ readSync uniTrapTab)+ UserSync gen -> (const $ readSync gen) where- readSync ft async = table3 async ft `withD` 1 - + readSync ft async = table3 async ft `withD` 1+ uniSawTab = setSize 4097 $ elins [1, 0] uniTriTab = setSize 4097 $ elins [0, 1, 0] uniTrapTab = setSize 4097 $ elins [1, 1, 0]@@ -263,10 +263,10 @@ TriSync -> smoothTabWave uniTriTab cps TrapSync -> smoothTabWave uniTrapTab cps UserSync t -> smoothTabWave t cps- where - rawSync = wave (ar $ ar slaveCps * (ar $ cpsSwitchWave cps)) + where+ rawSync = wave (ar $ ar slaveCps * (ar $ cpsSwitchWave cps)) ------------------------------------------------------ -- PW and Ramp hard sync --- pwSync +-- pwSync
+ src/Csound/Compat.hs view
@@ -0,0 +1,17 @@+-- | The compatibility functions. Functions to work with older versions of Csound.+--+-- The module contains opcodes that work in old versions of Csound.+-- Some opcodes are initialy implemented as UDOs. And if they are super cool+-- Csound developers decide to reimplement them in C and built in the Csound core.+-- It makes the opcodes faster.+--+-- But if your version of Csound is not so modern and opcode version is not+-- available for you. You can still use the UDO version, which is less efficient+-- but should work.+--+-- This module is not imported by default and intended to be used qualified.+module Csound.Compat(+ module X+) where++import Csound.Compat.Filter as X
+ src/Csound/Compat/Filter.hs view
@@ -0,0 +1,24 @@+-- | Use this module if your version of Csound is pre 6.09.+module Csound.Compat.Filter(+ -- One pole filters+ zdf1, zlp1, zhp1, zap1,++ -- Two pole filters+ zdf2, zlp, zbp, zhp, zdf2_notch, zbr,++ -- Ladder filter+ zladder,++ -- * TB303 filter+ diode, linDiode, noNormDiode,++ -- Korg 35 filters+ linKorg_lp, linKorg_hp, korg_lp, korg_hp+) where++import Csound.Typed.Plugins(+ zdf1, zlp1, zhp1, zap1,+ zdf2, zlp, zbp, zhp, zdf2_notch, zbr,+ zladder,+ diode, linDiode, noNormDiode,+ linKorg_lp, linKorg_hp, korg_lp, korg_hp)