Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ if(MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mstackrealign")
endif()

add_subdirectory(src/filters)
add_subdirectory(src/generators)
add_subdirectory(src/pv)
add_subdirectory(src/rubberband)
Expand All @@ -113,17 +114,19 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
endif()
endif()

install(TARGETS generators pv rubberband
install(TARGETS filters generators pv rubberband
LIBRARY DESTINATION Plugins
)
install(FILES
src/filters/filters.sc
src/generators/generators.sc
src/pv/pv.sc
src/rubberband/rubberband.sc
DESTINATION Classes
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
install(FILES
src/filters/FIR.schelp
src/generators/ImpulseDropout.schelp
src/generators/ImpulseJitter.schelp
src/generators/LoopPhasor.schelp
Expand All @@ -139,7 +142,7 @@ install(FILES
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
if(SUPERNOVA)
install(TARGETS generators_supernova pv_supernova rubberband_supernova
install(TARGETS filters_supernova generators_supernova pv_supernova rubberband_supernova
LIBRARY DESTINATION Plugins
)
endif()
Expand Down
16 changes: 16 additions & 0 deletions src/filters/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Create the project library
add_library(filters MODULE filters.cpp)
add_library(fir STATIC fir.cpp)
set_target_properties(fir PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(filters PRIVATE
fir
)

if(SUPERNOVA)
add_library(filters_supernova MODULE filters.cpp)
set_property(TARGET filters_supernova
PROPERTY COMPILE_DEFINITIONS SUPERNOVA)
target_link_libraries(filters_supernova PRIVATE
fir
)
endif()
56 changes: 56 additions & 0 deletions src/filters/FIR.schelp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
class:: FIR
summary:: No-nonsense FIR filter
related:: Classes/Convolution3, Classes/FOS, Classes/SOS, Classes/OneZero
categories:: Libraries>FlexUGens, UGens>Filters>Linear

Description::
A no-nonsense FIR filter where you provide your own coefficients. FIR duplicates the functionality
of link::Classes/Convolution3::. The difference is that FIR does not require you to load your
filter coefficients into a link::Classes/Buffer::. Instead, you can provide them directly as a
link::Classes/Ref:: in the same way as is done in link::Classes/DynKlank::.

classmethods::

method::ar

argument::coefs
A link::Classes/Ref:: to a list of FIR filter coefficients. The number of coefficients can change
over time, but can never exceed the server block size (if it does, extra coefficients will be truncated).

argument::in
The input signal to filter

argument::mul
The signal will be multiplied by this scalar

argument::add
This scalar will be added to the signal

Examples::

A 5-tap lowpass filter
code::
{
var sig = Saw.ar(440);
sig = FIR.ar(`[0.2, 0.2, 0.2, 0.2, 0.2], sig);
}.play;
::

A 19-tap control signal smoother
code::
{
var sig;
sig = LFPulse.kr(10);
[sig, FIR.kr(`((1/19)!19), sig)];
}.plot(0.3);
::

Changing coefficients
code::
{
var sig;
sig = LFPulse.kr(10);
[sig, FIR.kr(`[SinOsc.kr(10), SinOsc.kr(15)], sig)];
}.plot(0.3);
::

33 changes: 33 additions & 0 deletions src/filters/filters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
File: filters.cpp
Author: Jeff Martin

Description:
A collection of SuperCollider filter UGens

Copyright © 2026 by Jeffrey Martin. All rights reserved.
Website: https://www.jeffreymartincomposer.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "SC_PlugIn.h"
#include "fir.hpp"

InterfaceTable *ft;

PluginLoad(flex_filters) {
ft = inTable;
registerUnit<FIR>(ft, "FIR", false);
}
45 changes: 45 additions & 0 deletions src/filters/filters.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// File: filters.sc
// Author: Jeff Martin
//
// Description:
// A collection of SuperCollider filter UGens
//
// Copyright © 2026 by Jeffrey Martin. All rights reserved.
// Website: https://www.jeffreymartincomposer.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

FIR : UGen {
*ar {
arg coefs, in, mul=1, add=0;
coefs = coefs.multichannelExpandRef(1);
^this.multiNewList(['audio', in, coefs]).madd(mul, add)
}
*kr {
arg coefs, in, mul=1, add=0;
coefs = coefs.multichannelExpandRef(1);
^this.multiNewList(['control', in, coefs]).madd(mul, add)
}
*new1 {
arg rate, in, coefs;
var derefCoefs;
derefCoefs = coefs.dereference;
derefCoefs = derefCoefs.flop.flat;
^super.new.rate_(rate).addToSynth.init([in] ++ derefCoefs)
}
init {
arg theInputs;
inputs = theInputs;
}
}
59 changes: 59 additions & 0 deletions src/filters/fir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
File: fir.cpp
Author: Jeff Martin

Description:
A raw FIR filter

Copyright © 2026 by Jeffrey Martin. All rights reserved.
Website: https://www.jeffreymartincomposer.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "fir.hpp"
extern InterfaceTable *ft;

FIR::FIR() {
m_z = static_cast<float*>(RTAlloc(mWorld, fullBufferSize() * sizeof(float)));
for (size_t i = 0; i < fullBufferSize(); i++) {
m_z[i] = 0.f;
}
set_calc_function<FIR, &FIR::next>();
next(1);
}

FIR::~FIR() {
if (m_z) RTFree(mWorld, m_z);
}

void FIR::next(int inNumSamples) {
size_t numCoefs = static_cast<size_t>(mNumInputs - 1);
numCoefs = sc_clip(numCoefs, 0, static_cast<size_t>(fullBufferSize()));
const float *inBuf = in(0);
float *outBuf = out(0);
for (size_t xxi = 0; xxi < inNumSamples; xxi++) {
float convResult = 0.f;
// unit delay
for (size_t xxj = fullBufferSize() - 1; xxj > 0; xxj--) {
m_z[xxj] = m_z[xxj-1];
}
m_z[0] = inBuf[xxi];
// convolve
for (size_t xxk = 0; xxk < numCoefs; xxk++) {
convResult += in0(1+xxk) * m_z[xxk];
}
outBuf[xxi] = convResult;
}
}
38 changes: 38 additions & 0 deletions src/filters/fir.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
File: fir.hpp
Author: Jeff Martin

Description:
A raw FIR filter

Copyright © 2026 by Jeffrey Martin. All rights reserved.
Website: https://www.jeffreymartincomposer.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "SC_PlugIn.hpp"

class FIR : public SCUnit {
public:
FIR();
~FIR();

private:
void next(int inNumSamples);
float *m_z;
size_t m_delaySize;
};
Loading