Basic signals
These are commonly used operators that either make signals directly or transform signals in some way. Some key concepts to pay attention to include fanout and feedback.
Synth.konst — Functionkonst(v::Real)Makes a constant valued signal. Useful with functions that accept signals but we only want to use a constant value for it.
Synth.clip — Functionclip(dur :: Float64, s :: Signal)Clips the given signal to the given duration. Usually you'd use a "soft" version of this like a raised cosine or ADSR, but clip could be useful on its own.
Synth.sigfun — Functionsigfun(f::Function) :: SigFunTreats a simple function of time (in seconds) as a signal.
Synth.fanout — Functionfanout(s :: Signal)A signal, once constructed, can only be used by one "consumer" via structure composition. In some situations, we want a signal to be plugged into multiple consumers (to make a signal flow DAG). For these occasions, make the signal fanout by calling fanout on it and use the aliasble signal everywhere you need it instead. Note that fanout is an idempotent operator (i.e. if s = fanout(sig), then fanout(s) = s).
It only makes sense to make a single fanout version of a signal. Repeated evaluation of a signal is avoided by fanout by storing the recently computed value for a given time. So it assumes that time progresses linearly.
The word "alias" has two meanings - one in the context of signals where frequency shifting it can cause wrap around effects in the spectrum due to sampling, and in the context of a programming language where a value referenced in multiple data structures is said to be "aliased". It is in the latter sense that we use the word fanout in this case.
Synth.feedback — Functionfeedback()Constructs a feedback node which can be connected to a signal later on after construction. This is intended to be used in feedback loops and introduces a single sample delay to prevent infinite recursion.
You can later on connect a signal to the feedback point by calling connect(::Signal,::Feedback). Just as fanout is used to make DAG signal flow graphs possible, feedback is used to make graphs with loops possible.
Synth.connect — Functionconnect(s :: Signal, fb :: Feedback)Connects a signal to a feedback point.
Synth.clock — Functionclock(speed :: Real, t_end :: Real = Inf)
clock(speed :: Signal, t_end :: Real = Inf)Constructs different kinds of clocks. Clocks can be speed controlled. Clocks used for audio signals should be made using the clock constructor and those for scheduling purposes using clock_bpm.
Synth.clock_bpm — Functionclock_bpm(tempo_bpm=60.0, t_end :: Real = Inf) :: Signal
clock_bpm(tempo_bpm :: Signal, t_end :: Real = Inf) :: SignalConstructs different kinds of clocks. Clocks can be speed controlled. Clocks used for audio signals should be made using the clock constructor and those for scheduling purposes using clock_bpm.
Base.clamp — Functionclamp(sig::Signal, minval::Real, maxval::Real)
clamp(sig::Stereo{L,R}, minval::Real, maxval::Real) where {L <: Signal, R <: Signal}Clamps the given signal to the give minimum and maximum values. Supports stereo signals and clamps the individual channels.
Synth.mix — Functionmix(w1 :: Real, s1 :: Signal, w2 :: Real, s2 :: Signal)Creates a mixed signal from the two given signals, using the two constant weights. This is the basis of the support for + and - between signals. This and modulate remove some unnecessary combinations and reduce them down to simpler forms where possible.
Synth.modulate — Functionmodulate(m :: Signal, s :: Signal)Basically performs multiplication between two signals and is the basis of * operator support. This and mix together implement some expression simplifications that remove unnecessary combinations.
Synth.krate — Functionkrate(rate_hz :: Float64, s :: Signal)Short for "control-rate limited" signal. Useful with signals that vary slowly but are computationally expensive to do at audio rates. Same idea as in the original CSound and in many audio synthesis kits.
Produces a signal that will evaluate the given signal at a much lower sampling interval and linearly interpolate between the values to reduce computation. The given signal will effectively be "sampled" at the lower given interval. For example, krate(100.0, sinosc(0.5f0, 10.0f0)) will construct a 10Hz sine that is sampled only 100 times a second and interpolated, instead of having to calculate sines 48000 times a second.