From 5f77ab8bcbb7c205400146a43fdcdd00be523cf9 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Mon, 29 Jul 2024 22:42:49 +0100 Subject: [PATCH] Add TriggerMult node --- README.md | 2 +- docs/library/index.md | 1 + docs/library/operators/index.md | 1 + docs/library/operators/triggermult/index.md | 13 +++++++ .../signalflow/node/operators/trigger-mult.h | 25 ++++++++++++++ source/include/signalflow/signalflow.h | 1 + source/src/CMakeLists.txt | 1 + source/src/node/operators/trigger-mult.cpp | 34 +++++++++++++++++++ source/src/python/nodes.cpp | 5 ++- 9 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 docs/library/operators/triggermult/index.md create mode 100644 source/include/signalflow/node/operators/trigger-mult.h create mode 100644 source/src/node/operators/trigger-mult.cpp diff --git a/README.md b/README.md index 36007f3e..77581ba4 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ The following Node classes are currently included with the base distribution: | **Control** | [MouseX](https://signalflow.dev/library/control/mousex/), [MouseY](https://signalflow.dev/library/control/mousey/), [MouseDown](https://signalflow.dev/library/control/mousedown/) | | **Envelope** | [ADSREnvelope](https://signalflow.dev/library/envelope/adsrenvelope/), [ASREnvelope](https://signalflow.dev/library/envelope/asrenvelope/), [DetectSilence](https://signalflow.dev/library/envelope/detectsilence/), [Envelope](https://signalflow.dev/library/envelope/envelope/), [Line](https://signalflow.dev/library/envelope/line/), [RectangularEnvelope](https://signalflow.dev/library/envelope/rectangularenvelope/) | | **FFT** | [FFTContinuousPhaseVocoder](https://signalflow.dev/library/fft/fftcontinuousphasevocoder/), [FFTConvolve](https://signalflow.dev/library/fft/fftconvolve/), [FFTContrast](https://signalflow.dev/library/fft/fftcontrast/), [FFTCrossFade](https://signalflow.dev/library/fft/fftcrossfade/), [FFTLFO](https://signalflow.dev/library/fft/fftlfo/), [FFTMagnitudePhaseArray](https://signalflow.dev/library/fft/fftmagnitudephasearray/), [FFTRandomPhase](https://signalflow.dev/library/fft/fftrandomphase/), [FFTScaleMagnitudes](https://signalflow.dev/library/fft/fftscalemagnitudes/), [FFTTransform](https://signalflow.dev/library/fft/ffttransform/), [FFT](https://signalflow.dev/library/fft/fft/), [FFTNode](https://signalflow.dev/library/fft/fftnode/), [FFTOpNode](https://signalflow.dev/library/fft/fftopnode/), [FFTFindPeaks](https://signalflow.dev/library/fft/fftfindpeaks/), [IFFT](https://signalflow.dev/library/fft/ifft/), [FFTLPF](https://signalflow.dev/library/fft/fftlpf/), [FFTNoiseGate](https://signalflow.dev/library/fft/fftnoisegate/), [FFTPhaseVocoder](https://signalflow.dev/library/fft/fftphasevocoder/), [FFTTonality](https://signalflow.dev/library/fft/ffttonality/), [FFTZeroPhase](https://signalflow.dev/library/fft/fftzerophase/) | -| **Operators** | [Add](https://signalflow.dev/library/operators/add/), [AmplitudeToDecibels](https://signalflow.dev/library/operators/amplitudetodecibels/), [DecibelsToAmplitude](https://signalflow.dev/library/operators/decibelstoamplitude/), [ChannelArray](https://signalflow.dev/library/operators/channelarray/), [ChannelCrossfade](https://signalflow.dev/library/operators/channelcrossfade/), [ChannelMixer](https://signalflow.dev/library/operators/channelmixer/), [ChannelSelect](https://signalflow.dev/library/operators/channelselect/), [Equal](https://signalflow.dev/library/operators/equal/), [NotEqual](https://signalflow.dev/library/operators/notequal/), [GreaterThan](https://signalflow.dev/library/operators/greaterthan/), [GreaterThanOrEqual](https://signalflow.dev/library/operators/greaterthanorequal/), [LessThan](https://signalflow.dev/library/operators/lessthan/), [LessThanOrEqual](https://signalflow.dev/library/operators/lessthanorequal/), [Modulo](https://signalflow.dev/library/operators/modulo/), [Abs](https://signalflow.dev/library/operators/abs/), [If](https://signalflow.dev/library/operators/if/), [Divide](https://signalflow.dev/library/operators/divide/), [FrequencyToMidiNote](https://signalflow.dev/library/operators/frequencytomidinote/), [MidiNoteToFrequency](https://signalflow.dev/library/operators/midinotetofrequency/), [Multiply](https://signalflow.dev/library/operators/multiply/), [Pow](https://signalflow.dev/library/operators/pow/), [RoundToScale](https://signalflow.dev/library/operators/roundtoscale/), [Round](https://signalflow.dev/library/operators/round/), [ScaleLinExp](https://signalflow.dev/library/operators/scalelinexp/), [ScaleLinLin](https://signalflow.dev/library/operators/scalelinlin/), [Subtract](https://signalflow.dev/library/operators/subtract/), [Sum](https://signalflow.dev/library/operators/sum/), [TimeShift](https://signalflow.dev/library/operators/timeshift/), [Sin](https://signalflow.dev/library/operators/sin/), [Cos](https://signalflow.dev/library/operators/cos/), [Tan](https://signalflow.dev/library/operators/tan/), [Tanh](https://signalflow.dev/library/operators/tanh/) | +| **Operators** | [Add](https://signalflow.dev/library/operators/add/), [AmplitudeToDecibels](https://signalflow.dev/library/operators/amplitudetodecibels/), [DecibelsToAmplitude](https://signalflow.dev/library/operators/decibelstoamplitude/), [ChannelArray](https://signalflow.dev/library/operators/channelarray/), [ChannelCrossfade](https://signalflow.dev/library/operators/channelcrossfade/), [ChannelMixer](https://signalflow.dev/library/operators/channelmixer/), [ChannelSelect](https://signalflow.dev/library/operators/channelselect/), [Equal](https://signalflow.dev/library/operators/equal/), [NotEqual](https://signalflow.dev/library/operators/notequal/), [GreaterThan](https://signalflow.dev/library/operators/greaterthan/), [GreaterThanOrEqual](https://signalflow.dev/library/operators/greaterthanorequal/), [LessThan](https://signalflow.dev/library/operators/lessthan/), [LessThanOrEqual](https://signalflow.dev/library/operators/lessthanorequal/), [Modulo](https://signalflow.dev/library/operators/modulo/), [Abs](https://signalflow.dev/library/operators/abs/), [If](https://signalflow.dev/library/operators/if/), [Divide](https://signalflow.dev/library/operators/divide/), [FrequencyToMidiNote](https://signalflow.dev/library/operators/frequencytomidinote/), [MidiNoteToFrequency](https://signalflow.dev/library/operators/midinotetofrequency/), [Multiply](https://signalflow.dev/library/operators/multiply/), [Pow](https://signalflow.dev/library/operators/pow/), [RoundToScale](https://signalflow.dev/library/operators/roundtoscale/), [Round](https://signalflow.dev/library/operators/round/), [ScaleLinExp](https://signalflow.dev/library/operators/scalelinexp/), [ScaleLinLin](https://signalflow.dev/library/operators/scalelinlin/), [Subtract](https://signalflow.dev/library/operators/subtract/), [Sum](https://signalflow.dev/library/operators/sum/), [TimeShift](https://signalflow.dev/library/operators/timeshift/), [TriggerMult](https://signalflow.dev/library/operators/triggermult/), [Sin](https://signalflow.dev/library/operators/sin/), [Cos](https://signalflow.dev/library/operators/cos/), [Tan](https://signalflow.dev/library/operators/tan/), [Tanh](https://signalflow.dev/library/operators/tanh/) | | **Oscillators** | [Constant](https://signalflow.dev/library/oscillators/constant/), [Impulse](https://signalflow.dev/library/oscillators/impulse/), [LFO](https://signalflow.dev/library/oscillators/lfo/), [SawLFO](https://signalflow.dev/library/oscillators/sawlfo/), [SawOscillator](https://signalflow.dev/library/oscillators/sawoscillator/), [SineLFO](https://signalflow.dev/library/oscillators/sinelfo/), [SineOscillator](https://signalflow.dev/library/oscillators/sineoscillator/), [SquareLFO](https://signalflow.dev/library/oscillators/squarelfo/), [SquareOscillator](https://signalflow.dev/library/oscillators/squareoscillator/), [TriangleLFO](https://signalflow.dev/library/oscillators/trianglelfo/), [TriangleOscillator](https://signalflow.dev/library/oscillators/triangleoscillator/), [Wavetable](https://signalflow.dev/library/oscillators/wavetable/), [Wavetable2D](https://signalflow.dev/library/oscillators/wavetable2d/) | | **Processors** | [Clip](https://signalflow.dev/library/processors/clip/), [Fold](https://signalflow.dev/library/processors/fold/), [Smooth](https://signalflow.dev/library/processors/smooth/), [WetDry](https://signalflow.dev/library/processors/wetdry/), [Wrap](https://signalflow.dev/library/processors/wrap/) | | **Processors: Delays** | [AllpassDelay](https://signalflow.dev/library/processors/delays/allpassdelay/), [CombDelay](https://signalflow.dev/library/processors/delays/combdelay/), [OneTapDelay](https://signalflow.dev/library/processors/delays/onetapdelay/), [Stutter](https://signalflow.dev/library/processors/delays/stutter/) | diff --git a/docs/library/index.md b/docs/library/index.md index 2257fa9c..d2e4bbda 100644 --- a/docs/library/index.md +++ b/docs/library/index.md @@ -102,6 +102,7 @@ - **[Subtract](operators/subtract/index.md)**: Subtract each sample of b from each sample of a. Can also be written as a - b - **[Sum](operators/sum/index.md)**: Sums the output of all of the input nodes, by sample. - **[TimeShift](operators/timeshift/index.md)**: TimeShift +- **[TriggerMult](operators/triggermult/index.md)**: Distribute any triggers to all output nodes. - **[Sin](operators/sin/index.md)**: Outputs sin(a), per sample. - **[Cos](operators/cos/index.md)**: Outputs cos(a), per sample. - **[Tan](operators/tan/index.md)**: Outputs tan(a), per sample. diff --git a/docs/library/operators/index.md b/docs/library/operators/index.md index 820715eb..1351fbd7 100644 --- a/docs/library/operators/index.md +++ b/docs/library/operators/index.md @@ -30,6 +30,7 @@ - **[Subtract](subtract/index.md)**: Subtract each sample of b from each sample of a. Can also be written as a - b - **[Sum](sum/index.md)**: Sums the output of all of the input nodes, by sample. - **[TimeShift](timeshift/index.md)**: TimeShift +- **[TriggerMult](triggermult/index.md)**: Distribute any triggers to all output nodes. - **[Sin](sin/index.md)**: Outputs sin(a), per sample. - **[Cos](cos/index.md)**: Outputs cos(a), per sample. - **[Tan](tan/index.md)**: Outputs tan(a), per sample. diff --git a/docs/library/operators/triggermult/index.md b/docs/library/operators/triggermult/index.md new file mode 100644 index 00000000..9cead960 --- /dev/null +++ b/docs/library/operators/triggermult/index.md @@ -0,0 +1,13 @@ +title: TriggerMult node documentation +description: TriggerMult: Distribute any triggers to all output nodes. + +[Reference library](../../index.md) > [Operators](../index.md) > [TriggerMult](index.md) + +# TriggerMult + +```python +TriggerMult(a=0) +``` + +Distribute any triggers to all output nodes. + diff --git a/source/include/signalflow/node/operators/trigger-mult.h b/source/include/signalflow/node/operators/trigger-mult.h new file mode 100644 index 00000000..1b800865 --- /dev/null +++ b/source/include/signalflow/node/operators/trigger-mult.h @@ -0,0 +1,25 @@ +#pragma once + +#include "signalflow/core/constants.h" +#include "signalflow/node/node.h" + +namespace signalflow +{ + +/**--------------------------------------------------------------------------------* + * Distribute any triggers to all output nodes. + *---------------------------------------------------------------------------------*/ +class TriggerMult : public UnaryOpNode +{ + +public: + TriggerMult(NodeRef a = 0); + + virtual void process(Buffer &out, int num_frames) override; + virtual void trigger(std::string = SIGNALFLOW_DEFAULT_TRIGGER, + float value = SIGNALFLOW_NULL_FLOAT) override; +}; + +REGISTER(TriggerMult, "trigger-mult") + +} diff --git a/source/include/signalflow/signalflow.h b/source/include/signalflow/signalflow.h index 46be3645..e9c2a19e 100644 --- a/source/include/signalflow/signalflow.h +++ b/source/include/signalflow/signalflow.h @@ -44,6 +44,7 @@ #include #include #include +#include #include /*------------------------------------------------------------------------ diff --git a/source/src/CMakeLists.txt b/source/src/CMakeLists.txt index 9b5638f6..388dbed9 100644 --- a/source/src/CMakeLists.txt +++ b/source/src/CMakeLists.txt @@ -98,6 +98,7 @@ set(SRC ${SRC} ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/subtract.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/sum.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/trigonometry.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/trigger-mult.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/comparison.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/operators/time-shift.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/oscillators/constant.cpp diff --git a/source/src/node/operators/trigger-mult.cpp b/source/src/node/operators/trigger-mult.cpp new file mode 100644 index 00000000..fa5a1bfa --- /dev/null +++ b/source/src/node/operators/trigger-mult.cpp @@ -0,0 +1,34 @@ +#include "signalflow/node/operators/trigger-mult.h" +#include + +namespace signalflow +{ + +TriggerMult::TriggerMult(NodeRef a) + : UnaryOpNode(a) +{ + this->name = "trigger-mult"; +} + +void TriggerMult::process(Buffer &out, int num_frames) +{ + for (int channel = 0; channel < this->num_output_channels; channel++) + { + for (int frame = 0; frame < num_frames; frame++) + { + float value = this->input->out[channel][frame]; + out[channel][frame] = value; + } + } +} + +void TriggerMult::trigger(std::string name, float value) +{ + for (auto output : this->get_outputs()) + { + auto output_node = output.first; + output_node->trigger(name, value); + } +} + +} diff --git a/source/src/python/nodes.cpp b/source/src/python/nodes.cpp index cac0abb7..16434e04 100644 --- a/source/src/python/nodes.cpp +++ b/source/src/python/nodes.cpp @@ -52,7 +52,7 @@ void init_python_nodes(py::module &m) .def(py::init(), "buffer"_a = nullptr, "input"_a = 0.0, "delay_time"_a = 0.1); py::class_>(m, "SegmentPlayer", "Trigger segments of `buffer` at the given list of `onsets` positions, in seconds. `index` determines the index of the onset to play back at, which can also be passed as an argument to trigger(). `rate` determines the playback rate, and `clock` can be used to retrigger based on the output of another Node. If `continue_after_segment` is non-zero, playback will continue after the subsequent onset.") - .def(py::init, NodeRef, NodeRef, NodeRef, NodeRef>(), "buffer"_a = nullptr, "onsets"_a = 0, "index"_a = nullptr, "rate"_a = 1.0, "clock"_a = nullptr, "continue_after_segment"_a = 0); + .def(py::init, NodeRef, NodeRef, NodeRef, NodeRef, NodeRef>(), "buffer"_a = nullptr, "onsets"_a = 0, "index"_a = nullptr, "rate"_a = 1.0, "start_offset"_a = nullptr, "clock"_a = nullptr, "continue_after_segment"_a = 0); py::class_>(m, "SegmentedGranulator", "Segmented Granulator.") .def(py::init, std::vector, NodeRef, NodeRef, NodeRef, NodeRef>(), "buffer"_a = nullptr, "onset_times"_a = 0, "durations"_a = 0, "index"_a = 0.0, "rate"_a = 1.0, "clock"_a = 0, "max_grains"_a = 2048); @@ -244,6 +244,9 @@ void init_python_nodes(py::module &m) py::class_>(m, "TimeShift", "TimeShift") .def(py::init(), "a"_a = 0); + py::class_>(m, "TriggerMult", "Distribute any triggers to all output nodes.") + .def(py::init(), "a"_a = 0); + py::class_>(m, "Sin", "Outputs sin(a), per sample.") .def(py::init(), "a"_a = 0);