Vital
Loading...
Searching...
No Matches
iir_halfband_decimator.cpp
Go to the documentation of this file.
2
3namespace vital {
4
10 poly_float IirHalfbandDecimator::kTaps9[kNumTaps9] = {
11 { 0.167135116548925f, 0.0413554705262319f },
12 { 0.742130012538075f, 0.3878932830211427f },
13 };
14
20 poly_float IirHalfbandDecimator::kTaps25[kNumTaps25] = {
21 { 0.093022421467960f, 0.024388383731296f },
22 { 0.312318050871736f, 0.194029987625265f },
23 { 0.548379093159427f, 0.433855675727187f },
24 { 0.737198546150414f, 0.650124972769370f },
25 { 0.872234992057129f, 0.810418671775866f },
26 { 0.975497791832324f, 0.925979700943193f }
27 };
28
33 : Processor(kNumInputs, 1), sharp_cutoff_(false) {
35 }
36
44 void IirHalfbandDecimator::process(int num_samples) {
45 int num_taps = kNumTaps9;
46 const poly_float* taps = kTaps9;
47 if (sharp_cutoff_) {
48 num_taps = kNumTaps25;
49 taps = kTaps25;
50 }
51
52 const poly_float* audio = input(kAudio)->source->buffer;
53 int output_buffer_size = num_samples;
54 VITAL_ASSERT(input(kAudio)->source->buffer_size >= 2 * output_buffer_size);
55
56 poly_float* audio_out = output()->buffer;
57
58 // Main loop: for each output sample, combine two input samples and update the delay lines
59 for (int i = 0; i < output_buffer_size; ++i) {
60 int audio_in_index = 2 * i;
61
62 // Consolidate two adjacent input samples into one poly_float
63 poly_float result = utils::consolidateAudio(audio[audio_in_index],
64 audio[audio_in_index + 1]);
65
66 // Run through each tap in the IIR filter
67 for (int tap_index = 0; tap_index < num_taps; ++tap_index) {
68 // Compute difference between current signal and stored output
69 poly_float delta = result - out_memory_[tap_index];
70 // Multiply-accumulate with the tap coefficient
71 poly_float new_result = utils::mulAdd(in_memory_[tap_index], taps[tap_index], delta);
72
73 // Update delay lines
74 in_memory_[tap_index] = result;
75 out_memory_[tap_index] = new_result;
76
77 // The filter output at this stage
78 result = new_result;
79 }
80
81 // Sum the poly_float lanes and scale by 0.5f
82 audio_out[i] = utils::sumSplitAudio(result) * 0.5f;
83 }
84 }
85
93 for (int i = 0; i < kNumTaps25; ++i) {
94 in_memory_[i] = 0.0f;
95 out_memory_[i] = 0.0f;
96 }
97 }
98} // namespace vital
static constexpr int kNumTaps9
Number of taps in the lighter (9-tap) filter mode.
Definition iir_halfband_decimator.h:22
virtual void process(int num_samples) override
Processes audio data by decimating it (halving the sample rate).
Definition iir_halfband_decimator.cpp:44
static poly_float kTaps25[kNumTaps25]
Coefficients for the 25-tap IIR half-band filter, stored as pairs of poly_float.
Definition iir_halfband_decimator.h:37
static poly_float kTaps9[kNumTaps9]
Coefficients for the 9-tap IIR half-band filter, stored as pairs of poly_float.
Definition iir_halfband_decimator.h:32
static constexpr int kNumTaps25
Number of taps in the sharper (25-tap) filter mode.
Definition iir_halfband_decimator.h:27
IirHalfbandDecimator()
Constructs an IirHalfbandDecimator and initializes its memory.
Definition iir_halfband_decimator.cpp:32
@ kAudio
Main audio input for decimation.
Definition iir_halfband_decimator.h:44
void reset(poly_mask reset_mask) override
Resets the filter states (delay lines) for the specified voices.
Definition iir_halfband_decimator.cpp:92
Base class for all signal-processing units in Vital.
Definition processor.h:212
force_inline Input * input(unsigned int index=0) const
Retrieves the Input pointer at a given index.
Definition processor.h:587
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
#define VITAL_ASSERT(x)
Definition common.h:11
const poly_mask kFullMask
A mask covering all lanes of a poly_float vector.
Definition synth_constants.h:257
force_inline poly_float consolidateAudio(poly_float one, poly_float two)
Interleaves two stereo poly_floats into a single vector with left channels first, then right channels...
Definition poly_utils.h:491
force_inline poly_float mulAdd(poly_float a, poly_float b, poly_float c)
Performs a fused multiply-add on SIMD data: (a * b) + c.
Definition poly_utils.h:61
force_inline poly_float sumSplitAudio(poly_float sum)
Adds two stereo lanes for each voice, returning a combined mono result in each lane.
Definition poly_utils.h:517
Contains classes and functions used within the Vital synthesizer framework.
const Output * source
The output from which this input reads samples.
Definition processor.h:134
poly_float * buffer
Pointer to the output buffer.
Definition processor.h:110
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56