Skip to content

test: expand cabinet IR and DSP stability coverage#207

Merged
sudip-mondal-2002 merged 20 commits into
sudip-mondal-2002:mainfrom
YASHcode-IIITV:test/cabinet-ir-coverage
May 25, 2026
Merged

test: expand cabinet IR and DSP stability coverage#207
sudip-mondal-2002 merged 20 commits into
sudip-mondal-2002:mainfrom
YASHcode-IIITV:test/cabinet-ir-coverage

Conversation

@YASHcode-IIITV

@YASHcode-IIITV YASHcode-IIITV commented May 23, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Expands cabinet IR and DSP stability test coverage for the cabinet simulation pipeline.

Adds regression and edge-case tests for:

  • Missing IR file handling
  • Malformed WAV file rejection
  • Long-run numerical stability
  • Silence propagation correctness
  • Unit impulse identity behavior
  • Delayed impulse convolution behavior

Related Issue

Fixes #184

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • ♻️ Refactor / code cleanup
  • 📝 Documentation
  • ✅ Tests
  • 🔧 Build / CI / Configuration

How Was This Tested?

  • Platform(s) tested on:

    • Windows 11 x64
    • MSVC + CMake + Ninja
  • Test command run:
    build\amplitron-tests.exe

  • Manual test steps (if applicable):

    • Built project in Release mode
    • Executed full test suite after adding new cabinet IR tests
    • Verified all tests pass successfully

Results:

  • 232 passed
  • 0 failed

Checklist

  • Code compiles and builds successfully on my platform
  • All existing tests pass (./amplitron-tests)
  • New tests added for new functionality (if applicable)
  • Documentation updated (README, code comments) if applicable
  • No blocking calls on the audio thread (no std::mutex::lock() on the hot path)
  • Tested on: Windows 11 x64

Screenshots / Demo

N/A — test coverage changes only.

Summary by CodeRabbit

  • Tests
    • Added comprehensive unit tests for audio subsystems: WAV loading/truncation/resampling, convolution engine behavior, cabinet-simulation IR handling, and effect stability.
    • Expanded coverage for error handling (missing/truncated/malformed files), sample-length limits, state reset/clear and passthrough when disabled, long-run stability, block-size edge cases, and cleanup of temporary test artifacts.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds unit tests for WAV loading/resampling, ConvolutionEngine state and block processing, CabinetSim IR loading/metadata/error paths and effects stability, and registers two new test sources in the test target.

Changes

Test Coverage for Audio Processing Pipeline

Layer / File(s) Summary
WAV helpers and loader/resample tests
tests/test_wav_loader.cpp
Adds LE writers, write_pcm16_wav/write_zero_frame_wav, TempFile, and tests for zero-frame/truncated/malformed WAVs, resampling, and truncation/limit behavior.
ConvolutionEngine state, kernel, and block processing
tests/test_convolution_engine.cpp
Adds tests for reset() clearing state, has_kernel() transitions, overlap-add block processing finiteness, clearing kernel, small-block processing, and zero-input silence.
CabinetSim IR loading, metadata, and processing stability
tests/test_cabinet_sim_ir.cpp (lines 98-183, 211-308)
Adds tests for load_ir failure modes (missing vs malformed), IR metadata getters (ir_name, ir_path, ir_duration_ms), clear_ir() and set_sample_rate() semantics, long-run processing finiteness, and ensures WAV output streams are closed on successful write.
Effects processing silence and long-run stability
tests/test_effects.cpp (lines 328-355)
Adds tests that zero input remains near-silent and that 1000-block runs produce finite outputs with sustained energy.
Test build configuration
CMakeLists.txt (lines 515-516)
Registers tests/test_wav_loader.cpp and tests/test_convolution_engine.cpp in TEST_SOURCES for the amplitron-tests target.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

level:intermediate, quality:clean

Suggested reviewers

  • sudip-mondal-2002

Poem

🐰 I hop through tests with ears attuned,
I write tiny WAVs beneath the moon,
Kernels reset and overlap-adds play,
IRs load or fail, then clear away,
Happy rabbit tests — hooray today!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: expand cabinet IR and DSP stability coverage' directly and clearly summarizes the main change: expanding test coverage for cabinet impulse response and DSP stability components.
Linked Issues check ✅ Passed The PR adds comprehensive test coverage for wav_loader.cpp, convolution_engine.cpp, cabinet_sim.cpp, and related components as required by issue #184, with new tests for IR loading, error handling, DSP stability, and edge cases.
Out of Scope Changes check ✅ Passed All changes are directly related to test coverage expansion as specified in issue #184; no unrelated code modifications, functionality changes, or scope creep detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@YASHcode-IIITV

Copy link
Copy Markdown
Contributor Author

@sudip-mondal-2002 i have completed the changes and it is ready for the merger

@github-actions

github-actions Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Report 📊

Line Coverage: 72.2%

✅ Coverage meets threshold: 72.2% >= 60%

Full Coverage Summary
Summary coverage rate:
  lines......: 72.2% (3044 of 4217 lines)
  functions..: 86.0% (448 of 521 functions)
  branches...: no data found

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/test_cabinet_sim_ir.cpp (1)

123-171: ⚡ Quick win

Make processing-path intent explicit in stability/silence tests.

CabinetSim_IR_LongRunStability and CabinetSim_IR_SilenceRemainsSilent should explicitly enable the effect before process(...) to avoid relying on constructor defaults.

Small clarity fix
 TEST(CabinetSim_IR_LongRunStability) {
@@
     ASSERT_TRUE(cab.load_ir(path));
+    cab.set_enabled(true);
@@
 }

 TEST(CabinetSim_IR_SilenceRemainsSilent) {
@@
     ASSERT_TRUE(cab.load_ir(path));
+    cab.set_enabled(true);
@@
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cabinet_sim_ir.cpp` around lines 123 - 171, The tests rely on the
default processing state; explicitly enable the cabinet processing after loading
the IR and before calling process(...) in both CabinetSim_IR_LongRunStability
and CabinetSim_IR_SilenceRemainsSilent by calling the CabinetSim enable API
(e.g., cab.set_enabled(true) or cab.enable(true)) after cab.load_ir(path) so the
intent is clear and the tests do not depend on constructor defaults.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_cabinet_sim_ir.cpp`:
- Around line 98-121: The tests for failed IR loads do not verify that a failed
CabinetSim::load_ir(...) clears any previously-loaded IR state; update the tests
to first load a valid IR (or otherwise set a positive state via
CabinetSim::load_ir and confirm cab.has_ir() is true), then perform the failing
loads in TEST(CabinetSim_IR_MissingFileReturnsFalse) and
TEST(CabinetSim_IR_MalformedFileReturnsFalse), assert the load_ir(...) returns
false, and finally assert cab.has_ir() is false to ensure stale state is
cleared; use CabinetSim::set_sample_rate as before and clean up temporary files
as currently done.

In `@tests/test_convolution_engine.cpp`:
- Around line 51-75: The test currently only checks finiteness but should verify
that block-wise processing with ConvolutionEngine::process yields the same
result as a reference (non-streamed) convolution; fix it by computing a
reference output by performing a direct time-domain convolution of the input
buffer with the impulse response used to construct ConvolutionKernel (ir) and
then assert element-wise equality (or near-equality with a small tolerance)
between the streamed buffer (after repeated calls to ConvolutionEngine::process)
and the reference buffer; reference the existing symbols ConvolutionEngine,
ConvolutionKernel, ConvolutionEngine::process, and the test
ConvolutionEngine_OverlapAddConsistency when locating where to add the reference
computation and ASSERT_NEAR comparisons.
- Around line 29-33: The test currently only checks std::isfinite after
conv.process, which can hide leaked residual state; call conv.reset() before
conv.process(silent.data(), 256) (or ensure the reset happens immediately prior)
and replace the isfinite loop with assertions that each sample in silent is
approximately zero (e.g., use ASSERT_NEAR(s, 0.0f, <small_tolerance>) or
equivalent) to verify reset cleared internal state; reference conv.reset(),
conv.process(...), and the silent buffer in the change.

---

Nitpick comments:
In `@tests/test_cabinet_sim_ir.cpp`:
- Around line 123-171: The tests rely on the default processing state;
explicitly enable the cabinet processing after loading the IR and before calling
process(...) in both CabinetSim_IR_LongRunStability and
CabinetSim_IR_SilenceRemainsSilent by calling the CabinetSim enable API (e.g.,
cab.set_enabled(true) or cab.enable(true)) after cab.load_ir(path) so the intent
is clear and the tests do not depend on constructor defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5403e7f9-bf10-4008-b94f-cdfd5fa143d5

📥 Commits

Reviewing files that changed from the base of the PR and between 8b197e1 and 747b3fd.

📒 Files selected for processing (5)
  • CMakeLists.txt
  • tests/test_cabinet_sim_ir.cpp
  • tests/test_convolution_engine.cpp
  • tests/test_effects.cpp
  • tests/test_wav_loader.cpp

Comment thread tests/test_cabinet_sim_ir.cpp
Comment thread tests/test_convolution_engine.cpp
Comment thread tests/test_convolution_engine.cpp Outdated
@github-actions

github-actions Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

PR Preview Removed

The GitHub Pages preview for this PR has been removed because the PR was closed.

@MohitBareja16

Copy link
Copy Markdown
Collaborator
Screenshot_2026-05-23-17-08-10-67_40deb401b9ffe8e1df2f1cc5ba480b12 Screenshot_2026-05-23-17-07-39-75_40deb401b9ffe8e1df2f1cc5ba480b12 convulation_engine and wav_loader files don't have enough coverage. Make it 90+. Also cabinet_sim is good but try to make it 90+

@YASHcode-IIITV

Copy link
Copy Markdown
Contributor Author

@MohitBareja16 plz review it .

@sudip-mondal-2002

Copy link
Copy Markdown
Owner

wav_loader is still red, if possible get it 90+, if not possible let us know why

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_wav_loader.cpp (1)

77-89: ⚡ Quick win

Use unique temp file paths and guaranteed cleanup for test isolation.

Line 77 and Line 127 use fixed filenames in the working directory, which can make tests flaky under parallel execution and can leak artifacts if an assertion fails before Line 88/Line 140.

Suggested change
+#include <filesystem>
 ...
 TEST(WavLoader_LoadMalformedFileReturnsEmpty) {
-    const std::string path = "bad_wav.wav";
+    const auto path = (std::filesystem::temp_directory_path() /
+                       ("bad_wav_" + std::to_string(std::rand()) + ".wav")).string();
+    struct Cleanup { std::string p; ~Cleanup(){ std::remove(p.c_str()); } } cleanup{path};
 ...
-    std::remove(path.c_str());
 }
 ...
 TEST(WavLoader_MaxLengthLimit) {
-    const std::string path = "limit_test.wav";
+    const auto path = (std::filesystem::temp_directory_path() /
+                       ("limit_test_" + std::to_string(std::rand()) + ".wav")).string();
+    struct Cleanup { std::string p; ~Cleanup(){ std::remove(p.c_str()); } } cleanup{path};
 ...
-    std::remove(path.c_str());
 }

Also applies to: 127-141

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_wav_loader.cpp` around lines 77 - 89, The test uses a fixed
filename "bad_wav.wav" which can collide in parallel runs and may not be removed
if an assertion fails; change the test to create a unique temporary file path
(e.g. using std::filesystem::temp_directory_path with a generated unique
filename or std::tmpnam) and write the invalid data there, then call
load_wav_file(path) and assert on WavData; ensure guaranteed cleanup by removing
the temp file in a scope guard/RAII destructor or a try/finally-style block so
std::filesystem::remove is executed even if ASSERT_TRUE fails; apply the same
pattern for the other test around Line 127 that currently uses a fixed filename.
tests/test_cabinet_sim_ir.cpp (1)

271-290: ⚡ Quick win

Consolidate duplicated clear_ir() coverage into one test.

CabinetSim_ClearIRRemovesState duplicates the core behavior already covered by CabinetSim_ClearIR_ResetsState (load IR → clear_ir()has_ir()==false). Consider removing this test or merging any unique assertions into the existing one to reduce maintenance noise.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cabinet_sim_ir.cpp` around lines 271 - 290, Duplicate test
coverage: remove or merge the redundant TEST named
CabinetSim_ClearIRRemovesState which repeats the load_ir → clear_ir →
has_ir()==false behavior already covered by CabinetSim_ClearIR_ResetsState;
either delete the entire CabinetSim_ClearIRRemovesState test or move any unique
assertions (e.g., file creation via write_wav_mono_pcm16 or the path removal)
into CabinetSim_ClearIR_ResetsState and keep calls to CabinetSim::load_ir,
CabinetSim::clear_ir and CabinetSim::has_ir as the single authoritative check
for reset behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_wav_loader.cpp`:
- Around line 137-139: Change the truncation assertion to require an exact size
of 512 instead of allowing <=512: update the test that checks wav.samples.size()
so it asserts equality with 512 (use ASSERT_EQ or equivalent), ensuring you
compare types consistently (cast or use size_t(512)) so the test fails if
samples are truncated too much; locate the assertion referencing
wav.samples.size() in tests/test_wav_loader.cpp and replace the <= 512 check
with an equality check to 512.

---

Nitpick comments:
In `@tests/test_cabinet_sim_ir.cpp`:
- Around line 271-290: Duplicate test coverage: remove or merge the redundant
TEST named CabinetSim_ClearIRRemovesState which repeats the load_ir → clear_ir →
has_ir()==false behavior already covered by CabinetSim_ClearIR_ResetsState;
either delete the entire CabinetSim_ClearIRRemovesState test or move any unique
assertions (e.g., file creation via write_wav_mono_pcm16 or the path removal)
into CabinetSim_ClearIR_ResetsState and keep calls to CabinetSim::load_ir,
CabinetSim::clear_ir and CabinetSim::has_ir as the single authoritative check
for reset behavior.

In `@tests/test_wav_loader.cpp`:
- Around line 77-89: The test uses a fixed filename "bad_wav.wav" which can
collide in parallel runs and may not be removed if an assertion fails; change
the test to create a unique temporary file path (e.g. using
std::filesystem::temp_directory_path with a generated unique filename or
std::tmpnam) and write the invalid data there, then call load_wav_file(path) and
assert on WavData; ensure guaranteed cleanup by removing the temp file in a
scope guard/RAII destructor or a try/finally-style block so
std::filesystem::remove is executed even if ASSERT_TRUE fails; apply the same
pattern for the other test around Line 127 that currently uses a fixed filename.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b0c1350-9125-4076-a61d-d3e9e8daf4f6

📥 Commits

Reviewing files that changed from the base of the PR and between 747b3fd and ffe5f35.

⛔ Files ignored due to path filters (1)
  • resample_test.wav is excluded by !**/*.wav
📒 Files selected for processing (3)
  • tests/test_cabinet_sim_ir.cpp
  • tests/test_convolution_engine.cpp
  • tests/test_wav_loader.cpp

Comment thread tests/test_wav_loader.cpp Outdated
@YASHcode-IIITV

Copy link
Copy Markdown
Contributor Author

wav_loader is still red, if possible get it 90+, if not possible let us know why

image you can see that the test time is of yesterday at 12 pm can you check the current report with the current time test .

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/test_wav_loader.cpp (1)

262-263: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Strengthen the truncation assertion to exact expected size.

Line 263 asserts <= 512, which can hide regressions that truncate too aggressively. The loader should cap at exactly max_length_samples when exceeded.

Proposed fix
-    ASSERT_TRUE(
-    static_cast<int>(wav.samples.size()) <= 512);
+    ASSERT_EQ(static_cast<int>(wav.samples.size()), 512);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_wav_loader.cpp` around lines 262 - 263, Test currently uses a weak
assertion (<= 512) for wav.samples.size(), which can hide over-truncation;
change the assertion to require exact truncation to max_length_samples by
replacing the <= check with an equality check (e.g.,
ASSERT_EQ(static_cast<int>(wav.samples.size()), max_length_samples) or
ASSERT_EQ(..., 512)), referencing wav.samples.size() and the max_length_samples
test variable to guarantee the loader caps to the expected length.
🧹 Nitpick comments (1)
tests/test_wav_loader.cpp (1)

317-345: ⚡ Quick win

Consider verifying that stereo samples are actually mixed down to mono.

The test checks wav.channels == 2 (original format metadata) and that samples are finite, but doesn't verify the core mix-down contract. According to the loader implementation, stereo frames should be averaged to mono. For left=1.0f and right=-1.0f, the expected mono result is 0.0f.

Suggested verification

Add assertions to confirm mix-down behavior:

     ASSERT_EQ(wav.sample_rate, 48000);
 
+    ASSERT_EQ(static_cast<int>(wav.samples.size()), 512);
+
     for (float s : wav.samples) {
         ASSERT_TRUE(std::isfinite(s));
+        ASSERT_NEAR(s, 0.0f, 1e-5f);
     }

This verifies that:

  • Sample count matches frame count (mono, not interleaved stereo)
  • Mix-down correctly averages left and right channels
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_wav_loader.cpp` around lines 317 - 345, The test
WavLoader_StereoMixdown currently only checks metadata and finiteness but not
that stereo was mixed to mono; update the test to verify mix-down by asserting
that wav.channels reflects mono output (1) or that the number of samples equals
the number of frames and that each sample equals the average of left and right
(for left=1.0f and right=-1.0f expect 0.0f). Locate the test function
WavLoader_StereoMixdown and add assertions after load_wav_file(path) that check
either wav.channels == 1 (or samples.size() == left.size()) and that all entries
in wav.samples are approximately 0.0f (use the existing isfinite loop pattern to
iterate and assert exact/near-zero values).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@tests/test_wav_loader.cpp`:
- Around line 262-263: Test currently uses a weak assertion (<= 512) for
wav.samples.size(), which can hide over-truncation; change the assertion to
require exact truncation to max_length_samples by replacing the <= check with an
equality check (e.g., ASSERT_EQ(static_cast<int>(wav.samples.size()),
max_length_samples) or ASSERT_EQ(..., 512)), referencing wav.samples.size() and
the max_length_samples test variable to guarantee the loader caps to the
expected length.

---

Nitpick comments:
In `@tests/test_wav_loader.cpp`:
- Around line 317-345: The test WavLoader_StereoMixdown currently only checks
metadata and finiteness but not that stereo was mixed to mono; update the test
to verify mix-down by asserting that wav.channels reflects mono output (1) or
that the number of samples equals the number of frames and that each sample
equals the average of left and right (for left=1.0f and right=-1.0f expect
0.0f). Locate the test function WavLoader_StereoMixdown and add assertions after
load_wav_file(path) that check either wav.channels == 1 (or samples.size() ==
left.size()) and that all entries in wav.samples are approximately 0.0f (use the
existing isfinite loop pattern to iterate and assert exact/near-zero values).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9776237f-eced-45cf-9362-8ce82a04e155

📥 Commits

Reviewing files that changed from the base of the PR and between ffe5f35 and 89ff940.

⛔ Files ignored due to path filters (1)
  • stereo_test.wav is excluded by !**/*.wav
📒 Files selected for processing (1)
  • tests/test_wav_loader.cpp

@sudip-mondal-2002 sudip-mondal-2002 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep the assets inside tests/assets folder

otherwise LGTM

@sudip-mondal-2002 sudip-mondal-2002 added Audio Processing Related to DSP, effects, or signal processing level:advanced Advanced task · 45 GSSoC points type:testing Unit tests, integration tests, or test coverage labels May 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
tests/test_wav_loader.cpp (1)

1-173: ⚡ Quick win

Consider adding multi-channel (stereo) test coverage.

Issue #184 specifically mentions testing "stereo vs. mono" handling, but all tests in this file use mono (single-channel) WAVs. To fully satisfy the objectives, consider adding test cases that:

  1. Load a stereo WAV and verify it is correctly mixed down to mono.
  2. Validate that the mono mix-down averages channels correctly (per wav_loader.cpp:86-95).
  3. Test truncation and resampling behavior with stereo sources.

Example test structure:

TEST(WavLoader_Stereo_MixedToMono) {
    // Create stereo WAV with distinct left/right values
    // Load and verify samples = (left + right) / 2
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_wav_loader.cpp` around lines 1 - 173, Add stereo test coverage by
writing tests that create 2-channel PCM16 WAVs (use write_pcm16_wav with
num_channels=2 and interleaved int16_t samples), then call load_wav_file and
assert the returned WavData is mono and samples equal the per-frame average of
left and right channels (matching the mix-down logic in wav_loader.cpp around
the mix-down loop at lines ~86-95); include variants: (1)
TEST(WavLoader_Stereo_MixedToMono) with distinct constant left/right values to
verify averaging, (2) TEST(WavLoader_Stereo_Truncation_AfterResample) that
writes a stereo file at a different sample_rate and asserts resampling +
truncation behaves like the mono tests (check sample_rate, size limit, and
sample values), and (3) TEST(WavLoader_Stereo_Truncation_PrefixContentPreserved)
with a stereo sinusoid to ensure prefix content and truncation semantics match
mono behavior.
tests/test_effects.cpp (2)

328-339: ⚡ Quick win

Load an IR to test convolution path silence propagation.

The test doesn't call load_ir_from_file(), so conv_engine_.has_kernel() returns false and CabinetSim::process() skips convolution entirely (see context snippet cabinet_sim.cpp:123-145). This means the partitioned overlap-add DSP path—the primary source of potential numerical instability—is not exercised.

Given the PR objectives emphasize "cabinet IR and DSP stability coverage," consider loading a test IR fixture to verify that the convolution engine correctly propagates silence (i.e., that overlap_ buffers remain zero and no denormals/noise appear).

💡 Suggested enhancement to test convolution path
 TEST(cabinet_sim_silence_remains_silent) {
     CabinetSim cab;
     cab.set_sample_rate(48000);
+    // Load a test IR to exercise convolution path
+    cab.load_ir_from_file("tests/fixtures/impulse_512.wav");
     cab.reset();
 
     float buf[512] = {0.0f};
 
     cab.process(buf, 512);
 
     ASSERT_TRUE(buffer_is_finite(buf, 512));
-    ASSERT_LT(rms(buf, 512), 0.000001f);
+    ASSERT_LT(rms(buf, 512), 1e-6f);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_effects.cpp` around lines 328 - 339, The test never exercises the
convolution path because conv_engine_.has_kernel() is false; fix by loading a
small test IR before processing: call CabinetSim::load_ir_from_file(...) (or the
appropriate loader used in tests) after cab.reset() and
cab.set_sample_rate(48000) so the partitioned overlap-add path runs, then call
cab.process(buf, 512) and keep the same assertions; ensure the IR fixture is
silent or extremely short (and matches 48k sample rate) so the test still
verifies that overlap_ remains zero/finite and rms(buf,512) is below the
threshold.

340-354: ⚡ Quick win

Load an IR to test convolution engine long-run stability.

The test doesn't load an IR, so the convolution path (partitioned overlap-add FFT) is bypassed. The core stability concern—whether overlap_ buffers, fdl_ circular indexing, and FFT normalization remain numerically stable across 1000 blocks—is not verified.

Additionally, the RMS threshold > 1e-4 is very permissive (a 440 Hz sine with peak amplitude 1.0 has RMS ≈ 0.707). This might miss bugs where convolution heavily attenuates the signal or introduces slow drift.

💡 Suggested enhancement
 TEST(cabinet_sim_long_run_stability) {
     CabinetSim cab;
     cab.set_sample_rate(48000);
+    cab.load_ir_from_file("tests/fixtures/impulse_512.wav");
     cab.reset();
 
     float buf[512];
 
     for (int i = 0; i < 1000; ++i) {
         fill_sine(buf, 512, 440.0f, 48000);
         cab.process(buf, 512);
 
         ASSERT_TRUE(buffer_is_finite(buf, 512));
-        ASSERT_GT(rms(buf, 512), 0.0001f);
+        // For a unit-impulse IR, output RMS should be close to input RMS
+        ASSERT_GT(rms(buf, 512), 0.1f);
     }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_effects.cpp` around lines 340 - 354, The test currently never
exercises the convolution path; update the test to load an IR into the
CabinetSim so the partitioned overlap-add FFT path runs (use the project’s IR
API on CabinetSim — e.g., the IR-loading method such as load_ir /
setImpulseResponse / similar on the cab instance or create a short impulse
buffer and call the CabinetSim IR setter) before the loop, then run the same
1000 iterations calling cab.process(buf, 512); also tighten the sanity check on
level by replacing the permissive ASSERT_GT(rms(...), 1e-4f) with a stronger
check (for example assert rms is close to the expected sine RMS ~0.7071 using
ASSERT_NEAR(rms(buf,512), 0.7071f, 0.01f) or at least ASSERT_GT(rms(...), 0.5f))
and keep the buffer_is_finite assertions to catch numerical instability.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_wav_loader.cpp`:
- Around line 133-146: In the TEST WavLoader_Truncation_PrefixContentPreserved
replace the non-portable M_PI usage in the sine expression with the project
constant (e.g., Amplitron::TWO_PI or 2*Amplitron::PI) so the expression becomes
0.7f * std::sin(Amplitron::TWO_PI * i / 64.f) * 32767.f; also ensure the test
file includes the header that declares Amplitron::PI/TWO_PI (add the appropriate
common header include if it's not already present).

---

Nitpick comments:
In `@tests/test_effects.cpp`:
- Around line 328-339: The test never exercises the convolution path because
conv_engine_.has_kernel() is false; fix by loading a small test IR before
processing: call CabinetSim::load_ir_from_file(...) (or the appropriate loader
used in tests) after cab.reset() and cab.set_sample_rate(48000) so the
partitioned overlap-add path runs, then call cab.process(buf, 512) and keep the
same assertions; ensure the IR fixture is silent or extremely short (and matches
48k sample rate) so the test still verifies that overlap_ remains zero/finite
and rms(buf,512) is below the threshold.
- Around line 340-354: The test currently never exercises the convolution path;
update the test to load an IR into the CabinetSim so the partitioned overlap-add
FFT path runs (use the project’s IR API on CabinetSim — e.g., the IR-loading
method such as load_ir / setImpulseResponse / similar on the cab instance or
create a short impulse buffer and call the CabinetSim IR setter) before the
loop, then run the same 1000 iterations calling cab.process(buf, 512); also
tighten the sanity check on level by replacing the permissive
ASSERT_GT(rms(...), 1e-4f) with a stronger check (for example assert rms is
close to the expected sine RMS ~0.7071 using ASSERT_NEAR(rms(buf,512), 0.7071f,
0.01f) or at least ASSERT_GT(rms(...), 0.5f)) and keep the buffer_is_finite
assertions to catch numerical instability.

In `@tests/test_wav_loader.cpp`:
- Around line 1-173: Add stereo test coverage by writing tests that create
2-channel PCM16 WAVs (use write_pcm16_wav with num_channels=2 and interleaved
int16_t samples), then call load_wav_file and assert the returned WavData is
mono and samples equal the per-frame average of left and right channels
(matching the mix-down logic in wav_loader.cpp around the mix-down loop at lines
~86-95); include variants: (1) TEST(WavLoader_Stereo_MixedToMono) with distinct
constant left/right values to verify averaging, (2)
TEST(WavLoader_Stereo_Truncation_AfterResample) that writes a stereo file at a
different sample_rate and asserts resampling + truncation behaves like the mono
tests (check sample_rate, size limit, and sample values), and (3)
TEST(WavLoader_Stereo_Truncation_PrefixContentPreserved) with a stereo sinusoid
to ensure prefix content and truncation semantics match mono behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c38a6af0-a34a-4361-9873-898fc880a28c

📥 Commits

Reviewing files that changed from the base of the PR and between 89ff940 and 10c0f30.

📒 Files selected for processing (2)
  • tests/test_effects.cpp
  • tests/test_wav_loader.cpp

Comment thread tests/test_wav_loader.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/test_wav_loader.cpp (1)

28-28: 💤 Low value

Optional: Extract repeated directory creation to a shared helper or test fixture setup.

The std::filesystem::create_directories("tests/assets") call is repeated in three helper functions. While idempotent and safe, extracting this to a test fixture SetUp() or a single initialization function would reduce duplication.

Also applies to: 51-51, 90-90

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_wav_loader.cpp` at line 28, Extract the repeated
std::filesystem::create_directories("tests/assets") calls into a shared setup
helper used by the three helpers/tests; add a function (e.g.,
EnsureTestAssetsDirExists or a test fixture SetUp method) and replace the direct
calls in the helper functions referenced around the creates (the locations
showing std::filesystem::create_directories in tests/test_wav_loader.cpp) to
call that single initializer to remove duplication and centralize directory
creation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/test_wav_loader.cpp`:
- Line 28: Extract the repeated
std::filesystem::create_directories("tests/assets") calls into a shared setup
helper used by the three helpers/tests; add a function (e.g.,
EnsureTestAssetsDirExists or a test fixture SetUp method) and replace the direct
calls in the helper functions referenced around the creates (the locations
showing std::filesystem::create_directories in tests/test_wav_loader.cpp) to
call that single initializer to remove duplication and centralize directory
creation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8d7b677-cda8-49ca-bdbc-ba177792b693

📥 Commits

Reviewing files that changed from the base of the PR and between 10c0f30 and 78112db.

📒 Files selected for processing (2)
  • tests/assets/.gitkeep
  • tests/test_wav_loader.cpp

@YASHcode-IIITV YASHcode-IIITV force-pushed the test/cabinet-ir-coverage branch from 78112db to 8ebc0fd Compare May 24, 2026 13:03

@sudip-mondal-2002 sudip-mondal-2002 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but the coverage still looks low on convo eng
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Audio Processing Related to DSP, effects, or signal processing gssoc:approved GSSoC 2026 contribution level:advanced Advanced task · 45 GSSoC points mentor:sudip-mondal-2002 quality:exceptional type:testing Unit tests, integration tests, or test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: Cover Cabinet Sim IR loading (84%), convolution_engine.cpp (74%), and wav_loader.cpp (36%)

3 participants