Oscillators
Digital oscillator models for signal synthesis and analysis, suitable for real-time audio processing, including reference implementations of the Resonate algorithm in Swift and C++.
Install / Use
npx skills add alexandrefrancois/OscillatorsInstalls into whichever agent you are using.
README
Oscillators
Copyright (c) 2022-2026 Alexandre R. J. François
Released under MIT License.
This package implements digital sinusoidal oscillator models for signal synthesis and analysis, suitable for real-time audio processing,
The main motivation behind the development of this package is to provide reference Swift and C++ implementations of the Resonate algorithm, a low latency, low memory footprint, and low computational cost algorithm for evaluating perceptually relevant spectral information from audio signals, at the same time resolution as that of the input signal.
The package offers various implementations of resonator banks independently tuned at arbitrary frequencies, as well as tracking resonator banks that continuously self-tune to the frequency components in the input signal. The best candidates on hardware that supports SIMD acceleration are the vectorized implementation that uses the Accelerate framework, namely:
ResonatorBankVec(Swift) or its C++ counterpart for fixed resonant frequency resonator banks, andTrackingResonatorBankVec(Swift) or its C++ counterpart for tracking resonator banks.
Phasor
Overview
An oscillator is defined by its frequency and amplitude. The sinusoidal waveform values are computed recursively using a complex phasor.
A complex phasor Z = Zc + i Zs allows to recursively compute sinusoidals at a specified frequency and sampling rate. At each step, of duration 1 / sampleRate:
Z <- Z * W
where:
- W = Wc + i Ws
- w = 2 * PI * frequency / sampleRate
- Wc = cos(w), Ws = sin(w)
Zc and Zs are cosine and sine (resp.) waveforms of same frequency; Z has magnitude 1, which can be used to regularly correct for accumulation of numerical approximations.
Classes
Phasor: the base class for individual oscillators, adoptsPhasorProtocol
Oscillator
Overview
The phasor readily provides a sinusoidal signal to generate a signal at the chosen sampling rate and frequency.
At each tick of the clock (driven by the sampling rate of the output signal),
- iterate the phasor value calculation
- take the current value of either Zc (cosine) or Zs (sine)
- output the value scaled by the amplitude
Classes
Oscillator: a simple sinusoidal signal generator class, adoptsOscillatorProtocol
Resonators
Overview
A resonator is an oscillator which, when submitted to an input signal, oscillates with a larger amplitude when its resnonant frequency is present in the input signal. A resonator is characterized by its (resonant) frequency. The sinusoidal waveform is provided by the phasor.
The resonator accumulates the signal's contribution over time using the Exponentially Weighted Moving Average (EWMA), also known as a low-pass filter in signal processing.
The resonator's amplitude is updated at each tick of the clock, i.e. for each input sample, from the resonator's current amplitude value a (in [0,1]), its current waveform value w (in [-1,1]), and the input sample value s (in [-1,1]):
a <- (1-k) * a + k * s * w, where k in [0,1]
The pattern v <- (1-k) * v + k * s, where k is a constant in [0,1] is the iterative implementation of the EWMA. The single parameter k, which can be related to a time constant, controls the dynamics of the system, i.e. how quickly it adapts to variations in the input signal, as well as the frequency resolution.
The instantaneous contribution of each input sample value to the amplitude is proportional to s * w, which intuitively will be maximal when peaks in the input signal and peaks in the resonator's waveform are both equally spaced and aligned, i.e. when they have same frequency and are in phase.
In order to account for phase offset, the above calculation is performed at 2 phase values (there are only 2 degrees of freedom). For a sine waveform sin(x), the natural candidates are phases 0 and 𝜋/2, i.e. sin(x) and sin(x+𝜋/2) = cos(x), which are conveniently computed by the oscillator's phasor.
The resonator maintains two values, real and imaginary parts of a complex number P = Pc + i Ps, updated at each tick of the clock. For each input sample, from the current value of P, the current phasor value Z (of norm 1), and the input sample value s:
P <- (1-k) * P + k * s * Z, where k in [0,1]
This is followed by another EWMA to dampen amplitude and phase oscillations.
At any tick, the resonator's amplitude is the norm of P, i.e. sqrt(pcpc + psps), and the phase offset is arctan(ps/pc).
In the presence of significant response to an input signal, the instantaneous frequency can be estimated from the phase change of the complex state after processing each input sample. The tracking resonator adjusts its resonant frequency to track that instantaneous frequency.
Classes
Resonator: computes contributions at 0 and PI/2 (sine and cosine); adoptsResonatorProtocolTrackingResonator: computes contributions at 0 and PI/2 (sine and cosine), estimates phase differential and tracks estimated frequency; adoptsTrackingResonatorProtocol
Resonator Banks
Overview
Resonator banks implement independents resonators initially tuned to various frequencies within a range. Plain resonators have fixed resonant frequencies, while tracking resonator banks continuously self-tune to the frequency components in the input signal.
Classes
ResonatorBankVec: a bank of independent resonators implemented as a single array (i.e. vectorized), to allow single calls to Accelerate functions across the resonators. The use of unsafe pointers and of SIMD parallelism makes this implementation extremely efficient on most hardware.ResonatorBankArray: a bank of independent resonators implemented as instances of the Swift resonator class. The update function for live processing triggers resonator updates in concurrent task groups.TrackingResonatorBankVec: a bank of independent resonators implemented as a single array (i.e. vectorized), to allow single calls to Accelerate functions across the resonators. The use of unsafe pointers and of SIMD parallelism makes this implementation extremely efficient on most hardware.TrackingResonatorBankArray: a bank of independent resonators implemented as instances of the Swift resonator class. The update function for live processing triggers resonator updates in concurrent task groups.
Concurrency
The Swift ResonatorBankArray and TrackingResonatorBankArray classes implements 2 update functions each:
updatecalls the update function for each resonator sequentiallyupdateConcurrentcalls update for each resonator concurrently, with update calls grouped in a fixed number of concurrent tasks
C++ Implementation
The package features C++ version of the Phasor, Oscillator, Resonator, ResonatorBank (as a vector of Resonator instances), ResonatorBankVec (vectorized implementation), TrackingResonator and TrackingResonatorBankVec, in an Objective-C++ wrapper to bridge with Swift. The wrapper provides similar interfaces to the Swift implementations to facilitate comparative performance evaluation.
C++ classes
oscillator_cpp::Phasor: the base class for independent oscillatorsoscillator_cpp::Oscillator: a simple sinusoidal generator classoscillator_cpp::Resonator: resonator (same computations as the SwiftResonatorimplementation)oscillator_cpp::ResonatorBank: resonator bank as vector of Resonator instances. The update function for live processing triggers resonator updates in sequential or concurrent task groups (using Apple's Grand Central Dispatch).oscillator_cpp::ResonatorBankVec: a bank of independent resonators implemented as a single vector, to allow single calls to Accelerate functions across the resonators. SIMD parallelism makes this implementation extremely efficient on most hardware.oscillator_cpp::TrackingResonator: tracking resonator (same computations as the SwiftTrackingResonatorimplementation)oscillator_cpp::TrackingResonatorBank: tracking resonator bank as vector of TrackingResonator instances. The update function for live processing triggers resonator updates in sequential or concurrent task groups (using Apple's Grand Central Dispatch).oscillator_cpp::TrackingResonatorBankVec: a bank of independent tracking resonators implemented as a single vector, to allow single calls to Accelerate functions across the resonators. SIMD parallelism makes this implementation extremely efficient on most hardware.
Concurrency
The C++ oscillator_cpp::ResonatorBank class by defaults utilizes Apple's Grand Central Dispatch to implement the concurrent update function updateConcurrent.
The code also provides a sample implementation of the updateConcurrent function utilizing std::async, which is not used by default.
These methods are not thoroughly tested.
Objective-C++ wrappers
These classes provide an Objective-C++ interface for the C++ classes so they can be used in Swift code.
PhasorCppPhasorCppProtectedResonatorCppResonatorBankCppResonatorBankVecCppTrackingResonatorCppTrackingResonatorBankCppTrackingResonatorBankVecCpp
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.7kCommit, push, and open a PR
