-- | The Csound types. -- -- There are several primitive types: -- -- * @Sig@ - signals -- -- * @D@ - numbers -- -- * @Str@ - strings -- -- * @Tab@ - 1-dimensional arrays -- -- * @Spec@ and @Wspec@ - sound spectrums -- -- A signal is a stream of numbers. Signals carry sound or time varied -- control values. Numbers are constants. 1-dimensional arrays contain some useful -- data which is calculated at the initial run of the program. -- -- There is only one compound type. It's a tuple of Csound values. The empty tuple -- is signified with special type called @Unit@. -- module Csound.Types( -- * Primitive types Sig, D, Tab, Str, Spec, Wspec, BoolSig, BoolD, Val(..), SigOrD, Sig2, Sig3, Sig4, Sig5, Sig6, Sig8, Sig2_2, Sig2_3, Sig2_4, Sig2_5, Sig2_6, Sig2_7, Sig2_8, -- ** Constructors double, int, text, -- ** Constants idur, getSampleRate, getControlRate, getBlockSize, -- ** BPM getBpm, setBpm, syn, takt, -- ** Converters ar, kr, ir, sig, -- ** Init values withInits, withDs, withSigs, withTabs, withD, withSig, withTab, withSeed, -- ** Numeric functions quot', rem', div', mod', ceil', floor', round', int', frac', -- ** Logic functions boolSig, when1, whens, whenElse, whenD1, whenDs, whileDo, untilDo, whileDoD, untilDoD, whenElseD, compareWhenD, equalsTo, notEqualsTo, lessThan, greaterThan, lessThanEquals, greaterThanEquals, -- ** Aliases -- | Handy for functions that return tuples to specify the utput type -- -- > (aleft, aright) = ar2 $ diskin2 "file.wav" 1 -- -- or -- -- > asig = ar1 $ diskin2 "file.wav" 1 ar1, ar2, ar4, ar6, ar8, -- * Tuples Tuple(..), makeTupleMethods, Unit, unit, atTuple, -- *** Logic functions ifTuple, guardedTuple, caseTuple, -- * Instruments -- | An instrument is a function that takes a tpule of csound values as an argument -- and returns a tuple of signals as an output. The type of the instrument is: -- -- > (Arg a, Out b) => a -> b -- ** Arguments Arg, atArg, -- *** Logic functions ifArg, guardedArg, caseArg, -- ** Monophonic arguments MonoArg(..), MonoAdsr, adsrMonoSynt, monoAdsr, -- ** Outputs Sigs, -- * Arrays Arr, newLocalArr, newGlobalArr, newLocalCtrlArr, newGlobalCtrlArr, writeArr, readArr, modifyArr, mixArr, -- ** Type inference helpers Arr1, DArr1, Arr2, DArr2, Arr3, DArr3, arr1, darr1, arr2, darr2, arr3, darr3, -- ** Traverse and fold foreachArr, foreachArrD, forRowArr, forColumnArr, forRowArrD, forColumnArrD, foldArr, foldRowArr, foldColumnArr, foldRowsArrD, foldColumnsArrD, -- ** Array opcodes fillLocalArr, fillGlobalArr, fillLocalCtrlArr, fillGlobalCtrlArr, maparrayNew, lenarray, copyf2array, copya2ftab, minarray, maxarray, sumarray, scalearray, slicearrayNew, maparrayCopy, slicearrayCopy, -- * Pure Arrays (read-only) PureArr, newPureArr, readPureArr, PureArrD, newPureArrD, readPureArrD, -- ** Spectral opcodes SpecArr, fftNew, fftinvNew, rfftNew, rifftNew, pvs2tab, tab2pvs, cmplxprodNew, rect2polNew, pol2rectNew, pol2rect2New, windowArrayNew, r2cNew, c2rNew, magsArrayNew, phsArrayNew, fftCopy, fftinvCopy, rfftCopy, rifftCopy, cmplxprodCopy, rect2polCopy, pol2rectCopy, pol2rect2Copy, windowArrayCopy, r2cCopy, c2rCopy, magsArrayCopy, phsArrayCopy ) where import Data.Boolean import Csound.Typed.Types import Csound.Typed.Control -- | Gets an init-rate value from the list by index. atArg :: (Tuple a) => [a] -> Sig -> a atArg as ind = readPureArr arr ind where arr = newPureArr as -- guardedArg (zip (fmap (\x -> sig (int x) ==* ind) [0 .. ]) as) (head as) -- | Gets an control/audio-rate value from the list by index. atTuple :: (Tuple a) => [a] -> Sig -> a atTuple as ind = readPureArr arr ind where arr = newPureArr as -- guardedTuple (zip (fmap (\x -> sig (int x) ==* ind) [0 .. ]) as) (head as) whenElseD :: BoolD -> SE () -> SE () -> SE () whenElseD condition ifDo elseDo = whenDs [(condition, ifDo)] elseDo whenElse :: BoolSig -> SE () -> SE () -> SE () whenElse condition ifDo elseDo = whens [(condition, ifDo)] elseDo -- | Performs tree search f the first argument lies within the interval it performs the corresponding procedure. compareWhenD :: D -> [(D, SE ())] -> SE () compareWhenD val conditions = case conditions of [] -> return () [(_condition, ifDo)] -> ifDo (condition1, do1):(_condition2, do2): [] -> whenElseD (val `lessThan` condition1) do1 do2 _ -> whenElseD (val `lessThan` rootcondition) (compareWhenD val less) (compareWhenD val more) where (less, more) = splitAt (length conditions `div` 2) conditions rootcondition = fst $ last less -- | It's used to synchronize changes with BPM. -- Useful with LFO's or delay times. syn :: Sig -> Sig syn x = (bpm / 60) * x where bpm = getBpm -- | Calculates seconditions in ratio to global BPM. -- It measures time according to changes in the BPM. -- It's reciprocal to @syn@. takt :: Sig -> Sig takt = recip . syn