From 27356fef04870c04b8327ad8391881898a74e70b Mon Sep 17 00:00:00 2001 From: Gregory White Date: Fri, 2 Feb 2024 17:04:07 +0000 Subject: [PATCH 1/3] Documentation: Examples Producing further examples for: * ASREnvelope * Line * AllPassDelay * CombDelay * EQ * SVFilter * StereoBalance * StereoPanner * WhiteNoise --- .../library/envelope/asrenvelope/example-1.py | 27 +++++++++++++++++++ docs/library/envelope/line/example-1.py | 26 ++++++++++++++++++ .../delays/allpassdelay/example-0.py | 20 ++++++++++++++ .../delays/allpassdelay/example-1.py | 26 ++++++++++++++++++ .../processors/delays/combdelay/example-0.py | 21 +++++++++++++++ .../processors/filters/eq/example-0.py | 14 ++++++++++ .../processors/filters/svfilter/example-0.py | 11 ++++++++ .../processors/filters/svfilter/example-1.py | 27 +++++++++++++++++++ .../panning/stereobalance/example-0.py | 22 +++++++++++++++ .../panning/stereopanner/example-0.py | 18 +++++++++++++ .../panning/stereopanner/example-1.py | 26 ++++++++++++++++++ .../stochastic/whitenoise/example-0.py | 14 ++++++++++ .../stochastic/whitenoise/example-1.py | 17 ++++++++++++ 13 files changed, 269 insertions(+) create mode 100644 docs/library/envelope/asrenvelope/example-1.py create mode 100644 docs/library/envelope/line/example-1.py create mode 100644 docs/library/processors/delays/allpassdelay/example-0.py create mode 100644 docs/library/processors/delays/allpassdelay/example-1.py create mode 100644 docs/library/processors/delays/combdelay/example-0.py create mode 100644 docs/library/processors/filters/eq/example-0.py create mode 100644 docs/library/processors/filters/svfilter/example-0.py create mode 100644 docs/library/processors/filters/svfilter/example-1.py create mode 100644 docs/library/processors/panning/stereobalance/example-0.py create mode 100644 docs/library/processors/panning/stereopanner/example-0.py create mode 100644 docs/library/processors/panning/stereopanner/example-1.py create mode 100644 docs/library/stochastic/whitenoise/example-0.py create mode 100644 docs/library/stochastic/whitenoise/example-1.py diff --git a/docs/library/envelope/asrenvelope/example-1.py b/docs/library/envelope/asrenvelope/example-1.py new file mode 100644 index 00000000..5f54303e --- /dev/null +++ b/docs/library/envelope/asrenvelope/example-1.py @@ -0,0 +1,27 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using ASREnvelope to shape the sound of an oscillator over time. +# The Line node generates a continuously-changing value which we use as the +# release time. +#------------------------------------------------------------------------------- + +clock = Impulse(8.0) +CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 +FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 +arpeggios = CMaj7 + FMaj9 +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = TriangleOscillator(frequency) +release = Line(0.1, 0.5, 6, True) +envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +voice = oscillator * envelope + +pan = SineLFO(0.1667, -1.0, 1.0) + +output = StereoPanner(voice, pan) +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/envelope/line/example-1.py b/docs/library/envelope/line/example-1.py new file mode 100644 index 00000000..af49d5c2 --- /dev/null +++ b/docs/library/envelope/line/example-1.py @@ -0,0 +1,26 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using Line to repeatedly alter the release value of an envelope applied to the +# main synth voice, in time with the music. +#------------------------------------------------------------------------------- + +clock = Impulse(8.0) +CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 +FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 +arpeggios = CMaj7 + FMaj9 +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = TriangleOscillator(frequency) +release = Line(0.1, 0.5, 6, True) +envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +voice = oscillator * envelope + +pan = SineLFO(0.1667, -1.0, 1.0) + +output = StereoPanner(voice, pan) +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/allpassdelay/example-0.py b/docs/library/processors/delays/allpassdelay/example-0.py new file mode 100644 index 00000000..7d51a4f7 --- /dev/null +++ b/docs/library/processors/delays/allpassdelay/example-0.py @@ -0,0 +1,20 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using AllpassDelay to add a delay effect to a simple melodic sequence. +# The original oscillator can be heard in the left channel. +# The delay effect can be heard in the right channel. +#------------------------------------------------------------------------------- +clock = Impulse(1.0) +sequence = Sequence([ 60, 62, 64, 65, 67, 69, 71, 72 ], clock) +frequency = MidiNoteToFrequency(sequence) +oscillator = TriangleOscillator(frequency) +envelope= ASREnvelope(0, 0.2, 0.3, 1.0, clock) +voice = oscillator * envelope + +delayed = AllpassDelay(voice, 0.4, 0.8, 0.5) + +output = ChannelArray([ voice, delayed ]) * 0.75 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/allpassdelay/example-1.py b/docs/library/processors/delays/allpassdelay/example-1.py new file mode 100644 index 00000000..fd3a2bcb --- /dev/null +++ b/docs/library/processors/delays/allpassdelay/example-1.py @@ -0,0 +1,26 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using AllpassDelay to add a dreamy atmosphere to synth arpeggios +#------------------------------------------------------------------------------- +clock = Impulse(3.5) + +Am7 = [ 67, 64, 60, 57 ] * 4 +D7 = [ 62, 66, 69, 72] * 4 +arpeggios = Am7 + D7 +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = SquareOscillator(frequency) +envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) +voice = oscillator * envelope * 0.3 +filtered = SVFilter(voice, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 4000, 0.3) +delayed = AllpassDelay(filtered, 0.15, 0.8, 0.5) + +pan = TriangleLFO(0.1, -1.0, 1.0) + +output = StereoPanner(delayed, pan) +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/combdelay/example-0.py b/docs/library/processors/delays/combdelay/example-0.py new file mode 100644 index 00000000..4bafa5a2 --- /dev/null +++ b/docs/library/processors/delays/combdelay/example-0.py @@ -0,0 +1,21 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using CombDelay to change the character of a saw wave oscillator. +#------------------------------------------------------------------------------- +clock = Impulse(4) +arpeggio = [60, 62, 64, 66, 68, 70, + 72, 70, 68, 66, 64, 62] +sequence = Sequence(arpeggio, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = SawOscillator(frequency) +envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) +voice = oscillator * envelope + +comb = CombDelay(voice, 0.09, 0.6, 0.9) + +output = StereoPanner(comb) * 0.5 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/filters/eq/example-0.py b/docs/library/processors/filters/eq/example-0.py new file mode 100644 index 00000000..267498cb --- /dev/null +++ b/docs/library/processors/filters/eq/example-0.py @@ -0,0 +1,14 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using EQ to shape white noise. The low band (below 500Hz) is reduced. The mid +# band is boosted. The high band (above 2000Hz) is reduced drastically. +#------------------------------------------------------------------------------- +noise = WhiteNoise() + +eq = EQ(noise, 0.6, 1.5, 0.1, 500, 2000) + +output = StereoPanner(eq) * 0.5 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/filters/svfilter/example-0.py b/docs/library/processors/filters/svfilter/example-0.py new file mode 100644 index 00000000..a84d7fcb --- /dev/null +++ b/docs/library/processors/filters/svfilter/example-0.py @@ -0,0 +1,11 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using SVFilter as a low-pass filter on white noise. +#------------------------------------------------------------------------------- +noise = WhiteNoise() +filtered = SVFilter(noise, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 1000, 0.6) +output = StereoPanner(filtered) +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/filters/svfilter/example-1.py b/docs/library/processors/filters/svfilter/example-1.py new file mode 100644 index 00000000..dd3a40f1 --- /dev/null +++ b/docs/library/processors/filters/svfilter/example-1.py @@ -0,0 +1,27 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using SVFilter as a low-pass filter to reduce the harshness of a square wave +# oscillator. +#------------------------------------------------------------------------------- +clock = Impulse(3.5) + +Am7 = [ 67, 64, 60, 57 ] * 4 +D7 = [ 62, 66, 69, 72] * 4 +arpeggios = Am7 + D7 +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = SquareOscillator(frequency) +envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) +voice = oscillator * envelope +filtered = SVFilter(voice, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 4000, 0.3) +delayed = AllpassDelay(filtered, 0.15, 0.8, 0.5) + +pan = TriangleLFO(0.1, -1.0, 1.0) + +output = StereoPanner(delayed, pan) +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereobalance/example-0.py b/docs/library/processors/panning/stereobalance/example-0.py new file mode 100644 index 00000000..2d35c4be --- /dev/null +++ b/docs/library/processors/panning/stereobalance/example-0.py @@ -0,0 +1,22 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Demonstrating the effects of StereoBalance. Two tones are first panned hard +# left and hard right with StereoPanner. +# Setting StereoBalance's balance value to 0.0 will mean both tones are heard +# equally. A value of -1.0 will result in only the left channel being heard. +# A value of 1.0 will result in only the right channel being heard. +#------------------------------------------------------------------------------- + +low = TriangleOscillator(220) +high = TriangleOscillator(660) + +left = StereoPanner(low, -1.0) +right = StereoPanner(high, 1.0) +panned = (left + right) + +balanced = StereoBalance(panned, -1.0) + +balanced.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereopanner/example-0.py b/docs/library/processors/panning/stereopanner/example-0.py new file mode 100644 index 00000000..ea505252 --- /dev/null +++ b/docs/library/processors/panning/stereopanner/example-0.py @@ -0,0 +1,18 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using StereoPanner to pan a low pitch to the left and a high pitch to the +# right. +#------------------------------------------------------------------------------- + +low = TriangleOscillator(220) +high = TriangleOscillator(660) + +left = StereoPanner(low, -0.8) +right = StereoPanner(high, 0.8) + +output = (left + right) * 0.5 +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereopanner/example-1.py b/docs/library/processors/panning/stereopanner/example-1.py new file mode 100644 index 00000000..76187818 --- /dev/null +++ b/docs/library/processors/panning/stereopanner/example-1.py @@ -0,0 +1,26 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using StereoPanner to repeatedly pan an arpeggiating oscillator between the +# left and right channels. +#------------------------------------------------------------------------------- + +clock = Impulse(8.0) +CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 +FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 +arpeggios = CMaj7 + FMaj9 +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = TriangleOscillator(frequency) +release = Line(0.1, 0.5, 12, True) +envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +voice = oscillator * envelope + +pan = SineLFO(0.1667, -1.0, 1.0) + +output = StereoPanner(voice, pan) +output.play() + +graph.wait() \ No newline at end of file diff --git a/docs/library/stochastic/whitenoise/example-0.py b/docs/library/stochastic/whitenoise/example-0.py new file mode 100644 index 00000000..4c79375d --- /dev/null +++ b/docs/library/stochastic/whitenoise/example-0.py @@ -0,0 +1,14 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using white noise to control the pitch of an oscillator. +# A new pitch is determined once every second. Interpolation is turned off so +# that the oscillator jumps to the new pitch instead of smoothly moving to it. +# Random interval is turned off so that pitch changes occur at a regular rate. +#------------------------------------------------------------------------------- +frequency = WhiteNoise(1, 100, 1000, False, False) +oscillator = SineOscillator(frequency) +output = StereoPanner(oscillator) +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/stochastic/whitenoise/example-1.py b/docs/library/stochastic/whitenoise/example-1.py new file mode 100644 index 00000000..26334fb2 --- /dev/null +++ b/docs/library/stochastic/whitenoise/example-1.py @@ -0,0 +1,17 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using white noise to simulate the sound of wind. +# White noise is generated at audio rate and passed into a band-pass filter. +# The cutoff of the filter is controlled by another white noise generator, which +# generates a new value between 100 and 300 at randomly-spaced intervals every +# second, and smoothly interpolates between these values. +#------------------------------------------------------------------------------- +noise = WhiteNoise() +cutoff = WhiteNoise(1, 100, 300, True, True) + +filtered = SVFilter(noise, SIGNALFLOW_FILTER_TYPE_BAND_PASS, cutoff, 0.8) +output = StereoPanner(filtered) +output.play() +graph.wait() \ No newline at end of file From e0b61be37026004e02a96f4e5243e03f4b462bbe Mon Sep 17 00:00:00 2001 From: Gregory White Date: Fri, 9 Feb 2024 12:56:53 +0000 Subject: [PATCH 2/3] Documentation: Requested changes and QOL improvements * Improving QOL for oscillator examples by making them stereo and reducing volume -- let me know if this should be done differently? * Making formatting more consistent across examples * For node classes with more arguments, explicitly typing them out to help the reader understand --- docs/library/envelope/asrenvelope/example-1.py | 9 +++++---- docs/library/envelope/line/example-0.py | 2 +- docs/library/envelope/line/example-1.py | 5 +---- docs/library/oscillators/impulse/example-0.py | 2 +- docs/library/oscillators/sawlfo/example-0.py | 3 ++- .../oscillators/sawoscillator/example-0.py | 2 +- docs/library/oscillators/sinelfo/example-0.py | 3 ++- .../oscillators/sineoscillator/example-0.py | 2 +- docs/library/oscillators/squarelfo/example-0.py | 3 ++- .../oscillators/squareoscillator/example-0.py | 2 +- docs/library/oscillators/trianglelfo/example-0.py | 3 ++- .../oscillators/triangleoscillator/example-0.py | 2 +- .../processors/delays/allpassdelay/example-0.py | 8 +++++--- .../processors/delays/allpassdelay/example-1.py | 15 +++++++-------- .../processors/delays/combdelay/example-0.py | 8 +++++--- docs/library/processors/filters/eq/example-0.py | 9 ++++++--- .../processors/filters/svfilter/example-0.py | 5 ++++- .../processors/filters/svfilter/example-1.py | 12 ++++++------ .../processors/panning/stereobalance/example-0.py | 15 +++++---------- .../processors/panning/stereopanner/example-0.py | 2 -- .../processors/panning/stereopanner/example-1.py | 5 +---- docs/library/stochastic/whitenoise/example-0.py | 8 ++++++-- docs/library/stochastic/whitenoise/example-1.py | 8 +++++--- 23 files changed, 70 insertions(+), 63 deletions(-) diff --git a/docs/library/envelope/asrenvelope/example-1.py b/docs/library/envelope/asrenvelope/example-1.py index 5f54303e..45e32820 100644 --- a/docs/library/envelope/asrenvelope/example-1.py +++ b/docs/library/envelope/asrenvelope/example-1.py @@ -6,7 +6,6 @@ # The Line node generates a continuously-changing value which we use as the # release time. #------------------------------------------------------------------------------- - clock = Impulse(8.0) CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 @@ -16,12 +15,14 @@ oscillator = TriangleOscillator(frequency) release = Line(0.1, 0.5, 6, True) -envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +envelope = ASREnvelope(attack=0.0, + sustain=0.0, + release=release, + curve=1.0, + clock=clock) voice = oscillator * envelope pan = SineLFO(0.1667, -1.0, 1.0) - output = StereoPanner(voice, pan) output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/envelope/line/example-0.py b/docs/library/envelope/line/example-0.py index a3f7caf8..b6ba742a 100644 --- a/docs/library/envelope/line/example-0.py +++ b/docs/library/envelope/line/example-0.py @@ -8,6 +8,6 @@ clock = Impulse(frequency=1.0) line = Line(0.0, 0.5, 0.5, False, clock) osc = SawOscillator(200) -output = osc * line +output = StereoPanner(osc * line) output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/envelope/line/example-1.py b/docs/library/envelope/line/example-1.py index af49d5c2..d01cbf54 100644 --- a/docs/library/envelope/line/example-1.py +++ b/docs/library/envelope/line/example-1.py @@ -5,7 +5,6 @@ # Using Line to repeatedly alter the release value of an envelope applied to the # main synth voice, in time with the music. #------------------------------------------------------------------------------- - clock = Impulse(8.0) CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 @@ -15,12 +14,10 @@ oscillator = TriangleOscillator(frequency) release = Line(0.1, 0.5, 6, True) -envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +envelope = ASREnvelope(0.0, 0.0, release, 1.0, clock) voice = oscillator * envelope pan = SineLFO(0.1667, -1.0, 1.0) - output = StereoPanner(voice, pan) output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/impulse/example-0.py b/docs/library/oscillators/impulse/example-0.py index c326cb2d..2046edef 100644 --- a/docs/library/oscillators/impulse/example-0.py +++ b/docs/library/oscillators/impulse/example-0.py @@ -7,6 +7,6 @@ clock = Impulse(1.0) osc = TriangleOscillator(250) envelope = ASREnvelope(0.01, 0.0, 0.5, 1.0, clock) -output = osc * envelope +output = StereoPanner(osc * envelope) output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/sawlfo/example-0.py b/docs/library/oscillators/sawlfo/example-0.py index 5d9e9522..a6d5ad49 100644 --- a/docs/library/oscillators/sawlfo/example-0.py +++ b/docs/library/oscillators/sawlfo/example-0.py @@ -6,5 +6,6 @@ #------------------------------------------------------------------------------- lfo = SawLFO(1, 200, 1000) sine = SineOscillator(lfo) -sine.play() +output = StereoPanner(sine) * 0.5 +output.play() graph.wait() diff --git a/docs/library/oscillators/sawoscillator/example-0.py b/docs/library/oscillators/sawoscillator/example-0.py index 954874b3..4d346adb 100644 --- a/docs/library/oscillators/sawoscillator/example-0.py +++ b/docs/library/oscillators/sawoscillator/example-0.py @@ -6,6 +6,6 @@ #------------------------------------------------------------------------------- saw = SawOscillator(440) envelope = ASREnvelope(0.05, 0.1, 0.5) -output = saw * envelope +output = StereoPanner(saw * envelope) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/sinelfo/example-0.py b/docs/library/oscillators/sinelfo/example-0.py index 5ed2970c..10c532d8 100644 --- a/docs/library/oscillators/sinelfo/example-0.py +++ b/docs/library/oscillators/sinelfo/example-0.py @@ -6,5 +6,6 @@ #------------------------------------------------------------------------------- lfo = SineLFO(1, 200, 1000) saw = SawOscillator(lfo) -saw.play() +output = StereoPanner(saw) * 0.3 +output.play() graph.wait() diff --git a/docs/library/oscillators/sineoscillator/example-0.py b/docs/library/oscillators/sineoscillator/example-0.py index 487ca00d..530264fd 100644 --- a/docs/library/oscillators/sineoscillator/example-0.py +++ b/docs/library/oscillators/sineoscillator/example-0.py @@ -6,6 +6,6 @@ #------------------------------------------------------------------------------- sine = SineOscillator(440) envelope = ASREnvelope(0.1, 0.1, 0.5) -output = sine * envelope +output = StereoPanner(sine * envelope) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/squarelfo/example-0.py b/docs/library/oscillators/squarelfo/example-0.py index fde6d0de..c5ef3c17 100644 --- a/docs/library/oscillators/squarelfo/example-0.py +++ b/docs/library/oscillators/squarelfo/example-0.py @@ -6,5 +6,6 @@ #------------------------------------------------------------------------------- lfo = SquareLFO(1, 200, 400) sine = SineOscillator(lfo) -sine.play() +output = StereoPanner(sine) * 0.5 +output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/squareoscillator/example-0.py b/docs/library/oscillators/squareoscillator/example-0.py index 79b9aade..4e3d42b1 100644 --- a/docs/library/oscillators/squareoscillator/example-0.py +++ b/docs/library/oscillators/squareoscillator/example-0.py @@ -6,6 +6,6 @@ #------------------------------------------------------------------------------- square = SquareOscillator(440) envelope = ASREnvelope(0, 0.1, 0.5) -output = square * envelope +output = StereoPanner(square * envelope) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/trianglelfo/example-0.py b/docs/library/oscillators/trianglelfo/example-0.py index 45dbd112..8a401bc1 100644 --- a/docs/library/oscillators/trianglelfo/example-0.py +++ b/docs/library/oscillators/trianglelfo/example-0.py @@ -6,5 +6,6 @@ #----------------------------------------------------------------------------------- lfo = TriangleLFO(3, 200, 900) sine = SineOscillator(lfo) -sine.play() +output = StereoPanner(sine) * 0.5 +output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/oscillators/triangleoscillator/example-0.py b/docs/library/oscillators/triangleoscillator/example-0.py index d9dd874d..5e4ca6c6 100644 --- a/docs/library/oscillators/triangleoscillator/example-0.py +++ b/docs/library/oscillators/triangleoscillator/example-0.py @@ -6,6 +6,6 @@ #------------------------------------------------------------------------------- tri = TriangleOscillator(440) envelope = ASREnvelope(0.1, 0.1, 0.5) -output = tri * envelope +output = StereoPanner(tri * envelope) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/allpassdelay/example-0.py b/docs/library/processors/delays/allpassdelay/example-0.py index 7d51a4f7..2255eaa4 100644 --- a/docs/library/processors/delays/allpassdelay/example-0.py +++ b/docs/library/processors/delays/allpassdelay/example-0.py @@ -9,11 +9,13 @@ clock = Impulse(1.0) sequence = Sequence([ 60, 62, 64, 65, 67, 69, 71, 72 ], clock) frequency = MidiNoteToFrequency(sequence) + oscillator = TriangleOscillator(frequency) -envelope= ASREnvelope(0, 0.2, 0.3, 1.0, clock) +envelope = ASREnvelope(0, 0.2, 0.3, 1.0, clock) voice = oscillator * envelope - -delayed = AllpassDelay(voice, 0.4, 0.8, 0.5) +delayed = AllpassDelay(input=voice, + delay_time=0.4, + feedback=0.8) output = ChannelArray([ voice, delayed ]) * 0.75 output.play() diff --git a/docs/library/processors/delays/allpassdelay/example-1.py b/docs/library/processors/delays/allpassdelay/example-1.py index fd3a2bcb..14bdf4f7 100644 --- a/docs/library/processors/delays/allpassdelay/example-1.py +++ b/docs/library/processors/delays/allpassdelay/example-1.py @@ -5,7 +5,6 @@ # Using AllpassDelay to add a dreamy atmosphere to synth arpeggios #------------------------------------------------------------------------------- clock = Impulse(3.5) - Am7 = [ 67, 64, 60, 57 ] * 4 D7 = [ 62, 66, 69, 72] * 4 arpeggios = Am7 + D7 @@ -13,14 +12,14 @@ frequency = MidiNoteToFrequency(sequence) oscillator = SquareOscillator(frequency) -envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) -voice = oscillator * envelope * 0.3 -filtered = SVFilter(voice, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 4000, 0.3) -delayed = AllpassDelay(filtered, 0.15, 0.8, 0.5) +envelope = ASREnvelope(0.1, 0, 0.2, 1.0, clock) +voice = oscillator * envelope +filtered = SVFilter(voice, "low_pass", 4000, 0.3) +delayed = AllpassDelay(input=filtered, + delay_time=0.15, + feedback=0.8) pan = TriangleLFO(0.1, -1.0, 1.0) - -output = StereoPanner(delayed, pan) +output = StereoPanner(delayed, pan) * 0.5 output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/combdelay/example-0.py b/docs/library/processors/delays/combdelay/example-0.py index 4bafa5a2..e52a7924 100644 --- a/docs/library/processors/delays/combdelay/example-0.py +++ b/docs/library/processors/delays/combdelay/example-0.py @@ -11,10 +11,12 @@ frequency = MidiNoteToFrequency(sequence) oscillator = SawOscillator(frequency) -envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) +envelope = ASREnvelope(0.1, 0, 0.2, 1.0, clock) voice = oscillator * envelope - -comb = CombDelay(voice, 0.09, 0.6, 0.9) +comb = CombDelay(input=voice, + delay_time=0.09, + feedback=0.6, + max_delay_time=0.9) output = StereoPanner(comb) * 0.5 output.play() diff --git a/docs/library/processors/filters/eq/example-0.py b/docs/library/processors/filters/eq/example-0.py index 267498cb..2618e369 100644 --- a/docs/library/processors/filters/eq/example-0.py +++ b/docs/library/processors/filters/eq/example-0.py @@ -6,9 +6,12 @@ # band is boosted. The high band (above 2000Hz) is reduced drastically. #------------------------------------------------------------------------------- noise = WhiteNoise() - -eq = EQ(noise, 0.6, 1.5, 0.1, 500, 2000) - +eq = EQ(input=noise, + low_gain=0.0, + mid_gain=1.5, + high_gain=0.2, + low_freq=1000, + high_freq=2000) output = StereoPanner(eq) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/processors/filters/svfilter/example-0.py b/docs/library/processors/filters/svfilter/example-0.py index a84d7fcb..6cc1152a 100644 --- a/docs/library/processors/filters/svfilter/example-0.py +++ b/docs/library/processors/filters/svfilter/example-0.py @@ -5,7 +5,10 @@ # Using SVFilter as a low-pass filter on white noise. #------------------------------------------------------------------------------- noise = WhiteNoise() -filtered = SVFilter(noise, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 1000, 0.6) +filtered = SVFilter(input=noise, + filter_type="low_pass", + cutoff=1000, + resonance=0.6) output = StereoPanner(filtered) output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/processors/filters/svfilter/example-1.py b/docs/library/processors/filters/svfilter/example-1.py index dd3a40f1..2c8aacf4 100644 --- a/docs/library/processors/filters/svfilter/example-1.py +++ b/docs/library/processors/filters/svfilter/example-1.py @@ -6,7 +6,6 @@ # oscillator. #------------------------------------------------------------------------------- clock = Impulse(3.5) - Am7 = [ 67, 64, 60, 57 ] * 4 D7 = [ 62, 66, 69, 72] * 4 arpeggios = Am7 + D7 @@ -14,14 +13,15 @@ frequency = MidiNoteToFrequency(sequence) oscillator = SquareOscillator(frequency) -envelope= ASREnvelope(0.1, 0, 0.2, 1.0, clock) +envelope = ASREnvelope(0.1, 0, 0.2, 1.0, clock) voice = oscillator * envelope -filtered = SVFilter(voice, SIGNALFLOW_FILTER_TYPE_LOW_PASS, 4000, 0.3) +filtered = SVFilter(input=voice, + filter_type= "low_pass", + cutoff=4000, + resonance=0.3) delayed = AllpassDelay(filtered, 0.15, 0.8, 0.5) pan = TriangleLFO(0.1, -1.0, 1.0) - -output = StereoPanner(delayed, pan) +output = StereoPanner(delayed, pan) * 0.3 output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereobalance/example-0.py b/docs/library/processors/panning/stereobalance/example-0.py index 2d35c4be..eef2da1d 100644 --- a/docs/library/processors/panning/stereobalance/example-0.py +++ b/docs/library/processors/panning/stereobalance/example-0.py @@ -2,21 +2,16 @@ graph = AudioGraph() #------------------------------------------------------------------------------- -# Demonstrating the effects of StereoBalance. Two tones are first panned hard -# left and hard right with StereoPanner. +# Demonstrating the effects of StereoBalance. First a low tone is assigned to +# the left channel and a high tone is assigned to the right channel. # Setting StereoBalance's balance value to 0.0 will mean both tones are heard # equally. A value of -1.0 will result in only the left channel being heard. # A value of 1.0 will result in only the right channel being heard. +# In this example, an LFO is modulating the balance value between -1.0 and 1.0. #------------------------------------------------------------------------------- - low = TriangleOscillator(220) high = TriangleOscillator(660) - -left = StereoPanner(low, -1.0) -right = StereoPanner(high, 1.0) -panned = (left + right) - -balanced = StereoBalance(panned, -1.0) - +panned = ChannelArray([low, high]) +balanced = StereoBalance(panned, TriangleLFO(0.2, -1, 1)) * 0.5 balanced.play() graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereopanner/example-0.py b/docs/library/processors/panning/stereopanner/example-0.py index ea505252..4ec6fa26 100644 --- a/docs/library/processors/panning/stereopanner/example-0.py +++ b/docs/library/processors/panning/stereopanner/example-0.py @@ -5,7 +5,6 @@ # Using StereoPanner to pan a low pitch to the left and a high pitch to the # right. #------------------------------------------------------------------------------- - low = TriangleOscillator(220) high = TriangleOscillator(660) @@ -14,5 +13,4 @@ output = (left + right) * 0.5 output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereopanner/example-1.py b/docs/library/processors/panning/stereopanner/example-1.py index 76187818..8a148ce1 100644 --- a/docs/library/processors/panning/stereopanner/example-1.py +++ b/docs/library/processors/panning/stereopanner/example-1.py @@ -5,7 +5,6 @@ # Using StereoPanner to repeatedly pan an arpeggiating oscillator between the # left and right channels. #------------------------------------------------------------------------------- - clock = Impulse(8.0) CMaj7 = [ 60, 64, 67, 71, 74, 76 ] * 8 FMaj9 = [ 65, 69, 72, 76, 77, 81 ] * 8 @@ -15,12 +14,10 @@ oscillator = TriangleOscillator(frequency) release = Line(0.1, 0.5, 12, True) -envelope= ASREnvelope(0.0, 0.0, release, 1.0, clock) +envelope = ASREnvelope(0.0, 0.0, release, 1.0, clock) voice = oscillator * envelope pan = SineLFO(0.1667, -1.0, 1.0) - output = StereoPanner(voice, pan) output.play() - graph.wait() \ No newline at end of file diff --git a/docs/library/stochastic/whitenoise/example-0.py b/docs/library/stochastic/whitenoise/example-0.py index 4c79375d..49179dc7 100644 --- a/docs/library/stochastic/whitenoise/example-0.py +++ b/docs/library/stochastic/whitenoise/example-0.py @@ -7,8 +7,12 @@ # that the oscillator jumps to the new pitch instead of smoothly moving to it. # Random interval is turned off so that pitch changes occur at a regular rate. #------------------------------------------------------------------------------- -frequency = WhiteNoise(1, 100, 1000, False, False) +frequency = WhiteNoise( frequency=1, + min=100, + max=1000, + interpolate=False, + random_interval=False) oscillator = SineOscillator(frequency) -output = StereoPanner(oscillator) +output = StereoPanner(oscillator) * 0.5 output.play() graph.wait() \ No newline at end of file diff --git a/docs/library/stochastic/whitenoise/example-1.py b/docs/library/stochastic/whitenoise/example-1.py index 26334fb2..a155de40 100644 --- a/docs/library/stochastic/whitenoise/example-1.py +++ b/docs/library/stochastic/whitenoise/example-1.py @@ -10,8 +10,10 @@ #------------------------------------------------------------------------------- noise = WhiteNoise() cutoff = WhiteNoise(1, 100, 300, True, True) - -filtered = SVFilter(noise, SIGNALFLOW_FILTER_TYPE_BAND_PASS, cutoff, 0.8) -output = StereoPanner(filtered) +filtered = SVFilter(input=noise, + filter_type= "band_pass", + cutoff=cutoff, + resonance=0.8) +output = StereoPanner(filtered) * 0.5 output.play() graph.wait() \ No newline at end of file From 913147a9b99e5615bc0e67725f01642df63d9398 Mon Sep 17 00:00:00 2001 From: Gregory White Date: Fri, 9 Feb 2024 15:46:23 +0000 Subject: [PATCH 3/3] Documentation: More examples Adding examples for ChannelArray, OneTapDelay, Resample, StereoWidth. Updating documentation for Line. --- .../operators/channelarray/example-0.py | 11 ++++++++ .../delays/onetapdelay/example-0.py | 16 ++++++++++++ .../delays/onetapdelay/example-1.py | 26 +++++++++++++++++++ .../distortion/resample/example-0.py | 11 ++++++++ .../panning/stereowidth/example-0.py | 12 +++++++++ .../include/signalflow/node/envelope/line.h | 2 +- 6 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 docs/library/operators/channelarray/example-0.py create mode 100644 docs/library/processors/delays/onetapdelay/example-0.py create mode 100644 docs/library/processors/delays/onetapdelay/example-1.py create mode 100644 docs/library/processors/distortion/resample/example-0.py create mode 100644 docs/library/processors/panning/stereowidth/example-0.py diff --git a/docs/library/operators/channelarray/example-0.py b/docs/library/operators/channelarray/example-0.py new file mode 100644 index 00000000..bf311435 --- /dev/null +++ b/docs/library/operators/channelarray/example-0.py @@ -0,0 +1,11 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using ChannelArray to pan a low tone to the left and a high tone to the right. +#------------------------------------------------------------------------------- +low = TriangleOscillator(220) +high = TriangleOscillator(660) +panned = ChannelArray([low, high]) * 0.3 +panned.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/onetapdelay/example-0.py b/docs/library/processors/delays/onetapdelay/example-0.py new file mode 100644 index 00000000..ee67527f --- /dev/null +++ b/docs/library/processors/delays/onetapdelay/example-0.py @@ -0,0 +1,16 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using OneTapDelay to create a delay effect with no feedback. +# The original sound is heard in the left channel, and the delayed sound in the +# right channel. +#------------------------------------------------------------------------------- +clock = Impulse(1) +oscillator = TriangleOscillator(440) +envelope = ASREnvelope(0.001, 0, 0.3, 1.0, clock) +voice = oscillator * envelope +delayed = OneTapDelay(voice, 0.25) * 0.5 +output = ChannelArray([voice, delayed]) * 0.5 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/delays/onetapdelay/example-1.py b/docs/library/processors/delays/onetapdelay/example-1.py new file mode 100644 index 00000000..14ae4c74 --- /dev/null +++ b/docs/library/processors/delays/onetapdelay/example-1.py @@ -0,0 +1,26 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using OneTapDelay to bring controlled rhythmic interest to a melodic sequence +#------------------------------------------------------------------------------- +clock = Impulse(3.5) +Dm = [ 62, 65, 69 ] * 2 +Bdim = [ 59, 62, 65 ] * 2 +Gm = [55, 58, 62 ] * 2 +Bb = [77, 74, 70 ] +A = [ 76, 73, 69 ] + +arpeggios = Dm + Bdim + Gm + Bb + A +sequence = Sequence(arpeggios, clock) +frequency = MidiNoteToFrequency(sequence) + +oscillator = SquareOscillator(frequency) +envelope = ASREnvelope(0.1, 0, 0.2, 1.0, clock) +voice = oscillator * envelope +filtered = SVFilter(voice, "low_pass", 4000, 0.3) +delayed = filtered + OneTapDelay(filtered, 0.4) * 0.5 + +output = StereoPanner(delayed) * 0.3 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/distortion/resample/example-0.py b/docs/library/processors/distortion/resample/example-0.py new file mode 100644 index 00000000..6c527db1 --- /dev/null +++ b/docs/library/processors/distortion/resample/example-0.py @@ -0,0 +1,11 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using Resample to distort a sine wave. +#------------------------------------------------------------------------------- +sine = SineOscillator(440) +crushed = Resample(sine, 11025, 4) +output = StereoPanner(crushed) * 0.3 +output.play() +graph.wait() \ No newline at end of file diff --git a/docs/library/processors/panning/stereowidth/example-0.py b/docs/library/processors/panning/stereowidth/example-0.py new file mode 100644 index 00000000..57cd21b1 --- /dev/null +++ b/docs/library/processors/panning/stereowidth/example-0.py @@ -0,0 +1,12 @@ +from signalflow import * +graph = AudioGraph() + +#------------------------------------------------------------------------------- +# Using StereoWidth to continuously alter the width of a stereo signal. +#------------------------------------------------------------------------------- +low = TriangleOscillator(220) +high = TriangleOscillator(660) +panned = ChannelArray([low, high]) +width = StereoWidth(panned, TriangleLFO(0.5, 0, 1)) * 0.3 +width.play() +graph.wait() \ No newline at end of file diff --git a/source/include/signalflow/node/envelope/line.h b/source/include/signalflow/node/envelope/line.h index 5cde9b07..a4bf57a4 100644 --- a/source/include/signalflow/node/envelope/line.h +++ b/source/include/signalflow/node/envelope/line.h @@ -6,7 +6,7 @@ namespace signalflow { /**--------------------------------------------------------------------------------* - * Line segment with the given start/end values and duration. + * Line segment with the given start/end values, and duration (in seconds). * If loop is true, repeats indefinitely. * Retriggers on a clock signal. *---------------------------------------------------------------------------------*/