Skip to content

Commit fb4c83a

Browse files
committed
Fix it
1 parent 27bb337 commit fb4c83a

File tree

2 files changed

+46
-30
lines changed

2 files changed

+46
-30
lines changed

modules/yup_dsp/filters/yup_LinkwitzRileyFilter.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ class LinkwitzRileyFilter
185185
for (int i = 0; i < numSamples; ++i)
186186
{
187187
processSample (inputLeft[i],
188-
inputRight[i],
189-
outputLowLeft[i],
190-
outputLowRight[i],
191-
outputHighLeft[i],
192-
outputHighRight[i]);
188+
inputRight[i],
189+
outputLowLeft[i],
190+
outputLowRight[i],
191+
outputHighLeft[i],
192+
outputHighRight[i]);
193193
}
194194
}
195195

@@ -277,20 +277,23 @@ class LinkwitzRileyFilter
277277
// Apply coefficients to biquad stages
278278
for (int stage = 0; stage < numStages; ++stage)
279279
{
280-
// Each stage gets two identical coefficients (cascade)
281-
const auto& lowCoeff = lowCoeffs[stage * 2]; // Both cascades use same coeffs
282-
const auto& highCoeff = highCoeffs[stage * 2]; // Both cascades use same coeffs
283-
284-
// Set coefficients for both cascades (identical for Linkwitz-Riley)
285-
lowPassStage1.leftChannelStages[stage].setCoefficients (lowCoeff);
286-
lowPassStage1.rightChannelStages[stage].setCoefficients (lowCoeff);
287-
lowPassStage2.leftChannelStages[stage].setCoefficients (lowCoeff);
288-
lowPassStage2.rightChannelStages[stage].setCoefficients (lowCoeff);
289-
290-
highPassStage1.leftChannelStages[stage].setCoefficients (highCoeff);
291-
highPassStage1.rightChannelStages[stage].setCoefficients (highCoeff);
292-
highPassStage2.leftChannelStages[stage].setCoefficients (highCoeff);
293-
highPassStage2.rightChannelStages[stage].setCoefficients (highCoeff);
280+
// Each cascade needs its own coefficients
281+
const auto& lowCoeff1 = lowCoeffs[stage * 2]; // First cascade
282+
const auto& lowCoeff2 = lowCoeffs[stage * 2 + 1]; // Second cascade
283+
const auto& highCoeff1 = highCoeffs[stage * 2]; // First cascade
284+
const auto& highCoeff2 = highCoeffs[stage * 2 + 1]; // Second cascade
285+
286+
// Set coefficients for first cascade
287+
lowPassStage1.leftChannelStages[stage].setCoefficients (lowCoeff1);
288+
lowPassStage1.rightChannelStages[stage].setCoefficients (lowCoeff1);
289+
highPassStage1.leftChannelStages[stage].setCoefficients (highCoeff1);
290+
highPassStage1.rightChannelStages[stage].setCoefficients (highCoeff1);
291+
292+
// Set coefficients for second cascade (different coefficients)
293+
lowPassStage2.leftChannelStages[stage].setCoefficients (lowCoeff2);
294+
lowPassStage2.rightChannelStages[stage].setCoefficients (lowCoeff2);
295+
highPassStage2.leftChannelStages[stage].setCoefficients (highCoeff2);
296+
highPassStage2.rightChannelStages[stage].setCoefficients (highCoeff2);
294297
}
295298
}
296299

@@ -311,7 +314,7 @@ class LinkwitzRileyFilter
311314

312315
//==============================================================================
313316
CoeffType frequency = static_cast<CoeffType> (1000.0);
314-
double sampleRate = 44100.0;
317+
double sampleRate = 0.0;
315318

316319
FilterStage lowPassStage1, lowPassStage2;
317320
FilterStage highPassStage1, highPassStage2;

tests/yup_dsp/yup_LinkwitzRileyFilter.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,35 +175,48 @@ TEST_F (LinkwitzRileyFilterTests, LR8ProcessSampleDoesNotCrash)
175175
TEST_F (LinkwitzRileyFilterTests, ComplementaryResponse)
176176
{
177177
LinkwitzRiley2Filter<float> filter (1000.0);
178+
filter.setSampleRate (sampleRate);
179+
filter.reset();
178180

179-
// Test that low + high outputs sum to approximately unity at crossover frequency
181+
// Now do the actual test
180182
float lowLeft, lowRight, highLeft, highRight;
181-
float sumLeft = 0.0f, sumRight = 0.0f;
182183

183-
// Process sine wave at crossover frequency
184+
// Let the filter settle by processing some samples first
185+
for (int i = 0; i < blockSize; ++i)
186+
filter.processSample (sineTestLeft[i], sineTestRight[i], lowLeft, lowRight, highLeft, highRight);
187+
188+
// Test that low + high outputs sum to approximately unity at crossover frequency
189+
std::vector<float> summedLeft (blockSize);
190+
std::vector<float> summedRight (blockSize);
191+
192+
// Process sine wave at crossover frequency (second pass for steady state)
184193
for (int i = 0; i < blockSize; ++i)
185194
{
186195
filter.processSample (sineTestLeft[i], sineTestRight[i], lowLeft, lowRight, highLeft, highRight);
187-
sumLeft += (lowLeft + highLeft) * (lowLeft + highLeft);
188-
sumRight += (lowRight + highRight) * (lowRight + highRight);
196+
summedLeft[i] = lowLeft + highLeft;
197+
summedRight[i] = lowRight + highRight;
189198
}
190199

191-
// RMS of sum should be close to RMS of input
200+
// Calculate RMS of summed outputs
201+
float sumRmsLeft = 0.0f, sumRmsRight = 0.0f;
192202
float inputRmsLeft = 0.0f, inputRmsRight = 0.0f;
203+
193204
for (int i = 0; i < blockSize; ++i)
194205
{
206+
sumRmsLeft += summedLeft[i] * summedLeft[i];
207+
sumRmsRight += summedRight[i] * summedRight[i];
195208
inputRmsLeft += sineTestLeft[i] * sineTestLeft[i];
196209
inputRmsRight += sineTestRight[i] * sineTestRight[i];
197210
}
198211

199-
sumLeft = std::sqrt (sumLeft / blockSize);
200-
sumRight = std::sqrt (sumRight / blockSize);
212+
sumRmsLeft = std::sqrt (sumRmsLeft / blockSize);
213+
sumRmsRight = std::sqrt (sumRmsRight / blockSize);
201214
inputRmsLeft = std::sqrt (inputRmsLeft / blockSize);
202215
inputRmsRight = std::sqrt (inputRmsRight / blockSize);
203216

204217
// Allow for some tolerance due to filter transient and numerical precision
205-
EXPECT_NEAR (sumLeft, inputRmsLeft, 0.1f);
206-
EXPECT_NEAR (sumRight, inputRmsRight, 0.1f);
218+
EXPECT_NEAR (sumRmsLeft, inputRmsLeft, 0.1f);
219+
EXPECT_NEAR (sumRmsRight, inputRmsRight, 0.1f);
207220
}
208221

209222
TEST_F (LinkwitzRileyFilterTests, ResetClearsState)

0 commit comments

Comments
 (0)