You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+28-8Lines changed: 28 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,9 +5,12 @@ Released under MIT License.
5
5
6
6
This package implements digital sinusoidal oscillator models for signal synthesis and analysis, suitable for real-time audio processing,
7
7
8
-
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.
8
+
The main motivation behind the development of this package is to provide reference Swift and C++ implementations of the [_Resonate_](http://alexandrefrancois.org/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.
9
9
10
-
The package offers various implementations of resonator banks independently tuned at arbitrary frequencies. The best candidates on hardware that supports SIMD acceleration are `ResonatorBankVec` (Swift) or its C++ counterpart, which offer a vectorized implementation that uses the Accelerate framework.
10
+
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.
11
+
The best candidates on hardware that supports SIMD acceleration are the vectorized implementation that uses the Accelerate framework, namely:
12
+
-`ResonatorBankVec` (Swift) or its C++ counterpart for fixed resonant frequency resonator banks, and
13
+
-`TrackingResonatorBankVec` (Swift) or its C++ counterpart for tracking resonator banks.
11
14
12
15
13
16
## Phasor
@@ -46,7 +49,7 @@ At each tick of the clock (driven by the sampling rate of the output signal),
46
49
47
50
### Classes
48
51
49
-
-`Oscillator`: a simple generator class, adopts `OscillatorProtocol`
52
+
-`Oscillator`: a simple sinusoidal signal generator class, adopts `OscillatorProtocol`
50
53
51
54
## Resonators
52
55
@@ -58,7 +61,7 @@ The resonator accumulates the signal's contribution over time using the Exponent
58
61
59
62
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]):
60
63
61
-
_a <- (1-k) * a + k * s * w, where k in [0,1]_
64
+
_a <- (1-k) * a + k * s * w, where k in [0,1]_
62
65
63
66
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.
64
67
@@ -74,45 +77,59 @@ This is followed by another EWMA to dampen amplitude and phase oscillations.
74
77
75
78
At any tick, the resonator's amplitude is the norm of P, i.e. _sqrt(pc*pc + ps*ps)_, and the phase offset is _arctan(ps/pc)_.
76
79
80
+
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.
77
81
78
82
### Classes
79
83
80
-
-`Resonator`: computes contributions at 0 and PI/2 (sine and cosine), adopts `ResonatorProtocol`
84
+
-`Resonator`: computes contributions at 0 and PI/2 (sine and cosine); adopts `ResonatorProtocol`
85
+
-`TrackingResonator`: computes contributions at 0 and PI/2 (sine and cosine), estimates phase differential and tracks estimated frequency; adopts `TrackingResonatorProtocol`
86
+
81
87
82
88
## Resonator Banks
83
89
84
90
### Overview
85
91
86
-
Resonator banks implement independents resonators typically tuned to various frequencies within a range.
92
+
Resonator banks implement independents resonators initially tuned to various frequencies within a range.
93
+
Plain resonators have fixed resonant frequencies, while tracking resonator banks continuously self-tune to the frequency components in the input signal.
87
94
88
95
### Classes
89
96
90
97
-`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.
91
98
-`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.
99
+
-`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.
100
+
-`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.
101
+
92
102
93
103
### Concurrency
94
104
95
-
The Swift `ResonatorBankArray`class implements 2 update functions:
105
+
The Swift `ResonatorBankArray`and `TrackingResonatorBankArray` classes implements 2 update functions each:
96
106
-`update` calls the update function for each resonator sequentially
97
107
-`updateConcurrent` calls update for each resonator concurrently, with update calls grouped in a fixed number of concurrent tasks
98
108
109
+
99
110
## C++ Implementation
100
111
101
-
The package features C++ version of the Oscillator, Resonator and ResonatorBank (as a vector of Resonator instances), in an Objective-C++ wrapper to bridge with Swift. The wrapper provides similar interfaces to the Swift implementations to facilitate comparative performance evaluation.
112
+
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.
102
113
103
114
### C++ classes
104
115
105
116
-`oscillator_cpp::Phasor`: the base class for independent oscillators
117
+
-`oscillator_cpp::Oscillator`: a simple sinusoidal generator class
106
118
-`oscillator_cpp::Resonator`: resonator (same computations as the Swift `Resonator` implementation)
107
119
-`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).
108
120
-`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.
121
+
-`oscillator_cpp::TrackingResonator`: tracking resonator (same computations as the Swift `TrackingResonator` implementation)
122
+
-`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).
123
+
-`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.
109
124
110
125
### Concurrency
111
126
112
127
The C++ `oscillator_cpp::ResonatorBank` class by defaults utilizes Apple's Grand Central Dispatch to implement the concurrent update function `updateConcurrent`.
113
128
114
129
The code also provides a sample implementation of the `updateConcurrent` function utilizing `std::async`, which is not used by default.
115
130
131
+
These methods are not thoroughly tested.
132
+
116
133
### Objective-C++ wrappers
117
134
118
135
These classes provide an Objective-C++ interface for the C++ classes so they can be used in Swift code.
@@ -122,3 +139,6 @@ These classes provide an Objective-C++ interface for the C++ classes so they can
0 commit comments