Skip to content

10223 port filter curve eq#10892

Merged
saintmatthieu merged 24 commits into
audacity:masterfrom
saintmatthieu:10223-port-filter-curve-eq
May 15, 2026
Merged

10223 port filter curve eq#10892
saintmatthieu merged 24 commits into
audacity:masterfrom
saintmatthieu:10223-port-filter-curve-eq

Conversation

@saintmatthieu
Copy link
Copy Markdown
Contributor

@saintmatthieu saintmatthieu commented May 7, 2026

Resolves: #10223

  • I signed CLA
  • The title of the pull request describes an issue it addresses
  • If changes are extensive, then there is a sequence of easily reviewable commits
  • Each commit's message describes its purpose and effects
  • There are no behavior changes unnecessary for the stated purpose of the PR

Recommended:

  • Each commit compiles and runs on my machine without known undesirable changes of behavior

QA:

  • Testflow test cases have been run

@saintmatthieu saintmatthieu self-assigned this May 7, 2026
@saintmatthieu
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 9c92efff-d96f-4a47-90f8-48abea5814f0

📥 Commits

Reviewing files that changed from the base of the PR and between a5fb65c and 6ed28ad.

📒 Files selected for processing (48)
  • .gitignore
  • .vscode/launch.json
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/GraphicEqView.qml
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir

📝 Walkthrough

Walkthrough

Adds a new shared axis utility module (types, scale, ticks, labels, NumberScale), introduces a reusable GridPlot QML component, implements a new Filter Curve EQ effect (C++ class, view-model, editable curve model), and QML views including a tooltip. Spectrogram code is migrated to use shared axis types/NumberScale and prior spectrogram ruler-tick utilities are removed. CMake build files are updated to include the shared module and a new AU_BUILD_SHARED_TESTS option; resources and integration wiring are added for the new QML/UI components.

sequenceDiagram
  participant User as User
  participant UI as FilterCurveEqView (QML)
  participant VM as FilterCurveEqViewModel
  participant Model as FilterCurveModel
  participant Effect as FilterCurveEq
  participant Shared as shared::axis
  User->>UI: drag/edit curve point / toggle scale / zoom
  UI->>VM: invoke zoomIn/zoomOut / setLinFreqScale / setLabelWidth
  UI->>Model: setPoint/addPoint/removePoint (via VM)
  VM->>Model: reload / commit edits
  Model->>Effect: syncToEnvelope / EnvelopeUpdated
  VM->>Shared: xTicks() -> axisTicks + labelsForTicks
  Shared-->>VM: AxisTick list + labels
  UI->>UI: show FilterCurveEqTooltip(freq,gain)
Loading

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'port filter curve eq' is partially related to the changeset. It highlights a main aspect of the PR, but uses abbreviated and informal language ('port', 'eq') that could be more descriptive.
Description check ✅ Passed The PR description follows the template structure, includes issue links (#10223 and #10560), and has all checkboxes filled appropriately. The author confirms CLA signature, proper commits, and no unnecessary changes.
Linked Issues check ✅ Passed The changeset implements the Filter Curve EQ effect per #10223 requirements: adds the effect implementation, UI view with GridPlot integration, curve model with linear interpolation, log/linear frequency scale toggle, and extracts shared axis utilities. Partially addresses #10560 by extracting spectrogram ruler logic into shared axis tick/label utilities.
Out of Scope Changes check ✅ Passed Minor out-of-scope changes detected: GraphicEqView button rename (Flatten→Reset), .gitignore addition (.claude/settings.local.json), and VS Code launch config update. These are peripheral and non-critical to the main objectives.

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
src/shared/axis/axisticks.h (1)

28-29: ⚡ Quick win

Consider widening majorStep to double.

Typing majorStep as std::optional<int> rules out fractional steps (e.g., 0.5, 0.1) for ranges below ~10, and also pairs poorly with the auto-computed step in the implementation (see comment in axisticks.cpp). A double would be both safer and more general for a shared axis library.

src/shared/axis/axisticks.cpp (1)

71-76: 💤 Low value

Dead-parameter nit: getTicks ignores min/max.

min and max are received but the only values forwarded to getTicksValues are max (twice via the local) and min. Actually min isn't forwarded at all — getTicksValues(max, min, ...) is called inline. The scale parameter is also redundant once numberScale is passed. Consider tightening the signature, or inlining this one-line helper at the single call site (Line 111).

src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp (1)

78-87: 💤 Low value

Consider calling EnvelopeUpdated() in cancelDrag() for consistency with flatten() and invert().

While cancelDrag() successfully restores the point list and syncs the envelope back via syncToEnvelope(), it does not notify downstream listeners via EnvelopeUpdated(). This differs from flatten() and invert(), which both call EnvelopeUpdated() immediately after syncToEnvelope().

The current code appears safe because:

  • mCurves cache in mCurvesList is only read after EnvelopeUpdated() is called
  • The UI binds to m_points through the pointsChanged() signal, which cancelDrag() does emit
  • The legacy au3 code follows the same pattern (no EnvelopeUpdated() on capture loss)

However, adding the call would improve consistency and provide defensive coverage if future code introduces listeners expecting EnvelopeUpdated() notifications on state reversions.

src/shared/axis/numberscale.h (1)

16-17: 💤 Low value

AxisScale::Undefined treated as Linear — consider making the default constructor explicit about the invariant.

The default constructor sets mType = AxisScale::Undefined and stores raw value0/value1 (same path as Linear), but the Iterator dereference at lines 178–181 returns mValue for both Undefined and Logarithmic without any Hz-back-conversion. For Logarithmic this is intentional (the value stored is already in Hz after begin() initialises it via exp(...)), but for Undefined the dereference silently returns the stored raw value, which may not be what callers expect if they ever construct via the default constructor and then iterate.

This is not a defect given current usage, but worth a short comment near the default constructor to document the Undefined == Linear contract.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 82c409f0-e231-4d4d-869f-06a6de0956cd

📥 Commits

Reviewing files that changed from the base of the PR and between 9e20cd8 and f9638e6.

📒 Files selected for processing (45)
  • CMakeLists.txt
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqGridLines.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.cpp

Comment thread src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
Comment thread src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
Comment thread src/shared/axis/axisticks.cpp Outdated
@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from f9638e6 to 7c42595 Compare May 8, 2026 07:54
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp (1)

181-183: ⚡ Quick win

Use adaptive major-step selection instead of fixed 1000 in xTicks().

Line 181 hardcodes majorStep=1000, which can make tick density inconsistent across zoom/range and lin/log modes. Let axisTicks() auto-pick by passing std::nullopt for better axis readability.

Suggested fix
-    auto allTicks = au::shared::axisTicks(loFreq(), hiFreq(), scale, m_labelWidth, m_axisWidth, 1000);
+    auto allTicks = au::shared::axisTicks(loFreq(), hiFreq(), scale, m_labelWidth, m_axisWidth, std::nullopt);

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: a9bcbabf-6491-4bc4-8fc2-c8e81bfc59d9

📥 Commits

Reviewing files that changed from the base of the PR and between f9638e6 and 7c42595.

📒 Files selected for processing (31)
  • CMakeLists.txt
  • src/CMakeLists.txt
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/spectrogramutils.cpp
✅ Files skipped from review due to trivial changes (13)
  • src/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/shared/axis/axisscale.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/shared/tests/CMakeLists.txt
  • src/shared/axis/axistypes.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/shared/CMakeLists.txt
  • src/spectrogram/view/spectrogramchannelrulermodel.h
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/spectrogram/CMakeLists.txt
  • CMakeLists.txt
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/spectrogram/spectrogramtypes.h
  • src/shared/axis/axislabel.h
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/numberscale.h
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml

Comment thread src/shared/axis/axisticks.cpp
Comment thread src/shared/axis/axisticks.cpp Outdated
@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from f9c2aac to c3fb86e Compare May 12, 2026 21:59
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 (3)
src/shared/tests/axisticks_tests.cpp (1)

72-80: ⚡ Quick win

Add a regression case for the clamped-log boundary (safeMin == max).

Current tests don’t cover the boundary that can produce 1–2 major ticks and stress edge-pruning logic.

Suggested test addition
 TEST(axisTicks, normalized_scales_are_supported) {
@@
     EXPECT_GE(ticks.major.size(), kMinMajorTicks);
 }
+
+TEST(axisTicks, logarithmic_clamp_boundary_is_safe)
+{
+    constexpr auto min = 0.0;
+    constexpr auto max = 1e-6; // safeMin clamps to max
+    constexpr auto scale = AxisScale::Logarithmic;
+    constexpr auto labelExtent = 20.0;
+    constexpr auto axisLength = 10.0; // forces aggressive edge-overlap pruning
+
+    const AxisTicks ticks = axisTicks(min, max, scale, labelExtent, axisLength);
+    EXPECT_FALSE(ticks.major.empty());
+}
src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp (1)

22-22: 💤 Low value

Consider using explicit namespace qualification instead of file-scope using namespace.

The namespace directive using namespace au::effects; is only used for eq_common::envLogToLin and eq_common::envLinToLog (lines 96, 101). Explicit qualification (e.g., au::effects::eq_common::envLogToLin) would make the origin of these functions clearer and avoid potential name collisions if this file grows.

♻️ Proposed refactor to use explicit qualification
-using namespace au::effects;
-
 `#include` "log.h"

Then update the call sites:

-    eq_common::envLogToLin(m_curvesList.mParameters);
+    au::effects::eq_common::envLogToLin(m_curvesList.mParameters);
-    if (eq_common::envLinToLog(m_curvesList.mParameters)) {
+    if (au::effects::eq_common::envLinToLog(m_curvesList.mParameters)) {
src/effects/builtin_collection/filtercurveeq/FilterCurveEqGridLines.qml (1)

75-79: 💤 Low value

Consider using Qt.font(Object.assign(...)) pattern for consistency.

While the current approach (binding font.family and font.pixelSize separately) is valid, the codebase uses Qt.font(Object.assign({}, ui.theme.bodyFont, { ... })) in other files for consistency and clarity. This avoids potential future issues if additional font properties need to be inherited.

♻️ Proposed refactor
     FontMetrics {
         id: fontMetrics
-        font.family: ui.theme.bodyFont.family
-        font.pixelSize: ui.theme.bodyFont.pixelSize
+        font: Qt.font(Object.assign({}, ui.theme.bodyFont))
     }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: d915c8c7-e8c5-4fe6-82c9-8ae753aac1f5

📥 Commits

Reviewing files that changed from the base of the PR and between f9c2aac and c3fb86e.

📒 Files selected for processing (46)
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqGridLines.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.cpp
✅ Files skipped from review due to trivial changes (8)
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/spectrogramtypes.cpp
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/effects/builtin_collection/CMakeLists.txt
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
🚧 Files skipped from review as they are similar to previous changes (27)
  • src/shared/axis/axisscale.h
  • src/shared/axis/axistypes.h
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • CMakeLists.txt
  • src/shared/tests/CMakeLists.txt
  • src/uicomponents/au_uicomponents.qrc
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • muse
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/shared/axis/axislabel.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/shared/axis/numberscale.h

Comment thread src/effects/builtin_collection/filtercurveeq/FilterCurveEqGridLines.qml Outdated
Comment thread src/effects/builtin_collection/filtercurveeq/FilterCurveEqGridLines.qml Outdated
Comment thread src/shared/axis/axisticks.cpp Outdated
@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch 2 times, most recently from d4da778 to c19aa70 Compare May 13, 2026 08:01
@kryksyh
Copy link
Copy Markdown
Member

kryksyh commented May 13, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/shared/axis/axisticks.cpp (1)

100-104: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve bookend ticks when only min/max are present.

Lines 100-104 currently run with majorTicks.size() == 2, which can delete one edge tick even though there is no interior tick to prune. Gate both checks on size() > 2 so only interior ticks are removed.

Suggested fix
-    if (majorTicks.size() > 1u && std::abs(majorTicks.front().position - (majorTicks.begin() + 1)->position) < extentFraction * 1.5) {
+    if (majorTicks.size() > 2u
+        && std::abs(majorTicks.front().position - majorTicks[1].position) < extentFraction * 1.5) {
         majorTicks.erase(majorTicks.begin() + 1);
     }
-    if (majorTicks.size() > 1u && std::abs(majorTicks.back().position - (majorTicks.end() - 2)->position) < extentFraction * 1.5) {
+    if (majorTicks.size() > 2u
+        && std::abs(majorTicks.back().position - majorTicks[majorTicks.size() - 2].position) < extentFraction * 1.5) {
         majorTicks.erase(majorTicks.end() - 2);
     }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 6931e3f0-2076-4c6a-bbd1-a39a8f7f3641

📥 Commits

Reviewing files that changed from the base of the PR and between f9c2aac and c19aa70.

📒 Files selected for processing (47)
  • .gitignore
  • .vscode/launch.json
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/spectrogramutils.cpp
✅ Files skipped from review due to trivial changes (11)
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • .gitignore
  • src/uicomponents/au_uicomponents.qrc
  • src/spectrogram/internal/spectrogramservice.cpp
  • .vscode/launch.json
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/effects/builtin_collection/CMakeLists.txt
  • src/shared/axis/axistypes.h
🚧 Files skipped from review as they are similar to previous changes (25)
  • CMakeLists.txt
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
  • src/shared/tests/CMakeLists.txt
  • src/CMakeLists.txt
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/spectrogram/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/shared/CMakeLists.txt
  • src/spectrogram/spectrogramtypes.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • muse
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/shared/axis/axisticks.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/shared/axis/numberscale.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp

@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from c19aa70 to be6d90c Compare May 13, 2026 13:12
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 81afebb1-f95a-4831-a558-18f715585ec6

📥 Commits

Reviewing files that changed from the base of the PR and between c19aa70 and be6d90c.

📒 Files selected for processing (47)
  • .gitignore
  • .vscode/launch.json
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/spectrogramutils.cpp
✅ Files skipped from review due to trivial changes (8)
  • .gitignore
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/shared/axis/axistypes.h
  • src/CMakeLists.txt
  • src/spectrogram/spectrogramtypes.cpp
🚧 Files skipped from review as they are similar to previous changes (33)
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/uicomponents/au_uicomponents.qrc
  • muse
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/effects/builtin_collection/CMakeLists.txt
  • src/shared/tests/CMakeLists.txt
  • CMakeLists.txt
  • .vscode/launch.json
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/shared/CMakeLists.txt
  • src/spectrogram/spectrogramtypes.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/axis/axisscale.h
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/shared/axis/axislabel.cpp
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/shared/axis/axisticks.h
  • src/shared/tests/axisticks_tests.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/shared/axis/axislabel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/CMakeLists.txt
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/shared/axis/axisticks.cpp
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp

@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from be6d90c to 3f646ea Compare May 13, 2026 13:21
navigation.panel: root.buttonsNavigationPanel
navigation.order: invertButton.navigation.order + 1

icon: IconCode.ZOOM_IN
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

zoom in and zoom out buttons need toolTipTitle for the voiceover

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Adding them.
Why would that not regard the other FlatButtons, though?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Most buttons have text which is used for the voice over, but in this case there is only an icon so we have to help the accessibility system, an excerp from FlatButton.qml:

    NavigationControl {
        id: navCtrl
        name: root.objectName !== "" ? root.objectName : "FlatButton"
        enabled: root.enabled && root.visible

        accessible.role: MUAccessible.Button
        accessible.name: Boolean(root.text) ? root.text : root.toolTipTitle
        accessible.description: root.toolTipDescription
        accessible.visualItem: root
        accessible.enabled: navCtrl.enabled

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see - thanks.

Comment thread src/shared/axis/axisticks.cpp Outdated
if (!muse::is_equal(majorValues.back(), safeMin)) {
majorValues.push_back(safeMin);
}
std::vector<AxisTick> majorTicks = toTicks(majorValues, numberScale, extentFraction);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

now this allows ticks to be too close to each other in spectrogram view

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

Comment thread src/shared/axis/axisticks.cpp Outdated
return values;
}

std::vector<shared::AxisTick> toTicks(const std::vector<double>& values, const shared::NumberScale& numberScale, double labelExtentFraction)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

labelExtentFraction - unused

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

Comment thread src/shared/axis/axisticks.cpp Outdated
}
}

shared::AxisTicks shared::axisTicks(double min, double max, AxisScale scale, double labelExtent, double axisLength)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this function looks similar to FilterCurveEqViewModel::xTicksLog can we merge them? The logic is quite complex (and I don't think I fully understand all corner cases here), maybe it will be worthwhile to have a single implementation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The FilterCurveEqViewModel::xTicksLog implementation is a special case: on a log scale, the graphic distance from e.g. 10 to 20 is the same as 100 to 200 and the same as 1k to 2k, etc. So there the major ticks are 10, 100, 1000, etc, which gives the opportunity to implement major and minor ticks decade by decade, in a for loop.
Here, I have to support all scale types. For instance, I can't have major ticks at 10, 100, 1000, etc, for a linear scale, and probably this applies to other non-log scales (like the mel scale) too. So I found a mechanism that works ok-ish for everything. When we talked about the design of the spectrogram rulers a while ago, there was a consensus that an ok-ish result was acceptable, because we'd give the user other means of knowing exactly what frequency she was pointing at.

The fact that the labels are now on top of one another like you showed in your comment below isn't acceptable, though, and shouldn't be too hard to fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that the implementation is tricky. The unit tests help, though.

filterCurveEq.curveModel.removePoint(index, completed)
}

onDragCancelled: {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How can a user cancel a drag? For Automation you can press Esc, but effect window closes on Esc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch!
Adding a fix to this.
There will remain a less severe bug until another small fix is made for this in the framework's PolylinePlot.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

const double loLog = std::log10(kLoFreqRef);
const double hiLog = std::log10(hiFreq);
const double denom = hiLog - loLog;
bool changed = false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is it "changed" or "clamped"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's changed by clamping?
That's code that was migrated from AU3 almost as-is. It turns out that the return value isn't used by any alive path (the other place being in the graphic EQ if the scale is linear there but in practice it never is, maybe it's some historical leftover).


for (size_t i = 0; i < numPoints; ++i) {
if (when[i] * hiFreq >= kLoFreqRef) {
// Caution: on Linux, when (when * hiFreq) == 20, the log
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it is not specifically a linux thing, most likely it will depend on libm and codegen. Most likely with clang/mingw on windows it will be the same.

Copy link
Copy Markdown
Member

@kryksyh kryksyh left a comment

Choose a reason for hiding this comment

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

moving to QA, but at least VO should be addressed

@kryksyh kryksyh force-pushed the 10223-port-filter-curve-eq branch from 3f646ea to 9cf2829 Compare May 14, 2026 12:40
@kryksyh
Copy link
Copy Markdown
Member

kryksyh commented May 14, 2026

rebased to fix export dialog

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp (1)

236-253: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize multiplier when it starts at 10 to keep decade iteration correct.

std::ceil(loFreq() / increment) can yield 10, which desynchronizes the ++multiplier % 10 rollover logic and produces wrong/duplicated log ticks in the first decade.

Suggested fix
     auto exponent = std::floor(left);
     auto increment = std::pow(10, exponent);
     int multiplier = std::ceil(loFreq() / increment);
+    if (multiplier >= 10) {
+        multiplier = 1;
+        ++exponent;
+    }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 1960ba76-2af1-4d1b-b56b-041002dd084a

📥 Commits

Reviewing files that changed from the base of the PR and between be6d90c and 9cf2829.

📒 Files selected for processing (47)
  • .gitignore
  • .vscode/launch.json
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/spectrogramutils.cpp
✅ Files skipped from review due to trivial changes (10)
  • src/uicomponents/au_uicomponents.qrc
  • muse
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • .gitignore
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/CMakeLists.txt
🚧 Files skipped from review as they are similar to previous changes (30)
  • .vscode/launch.json
  • src/spectrogram/internal/spectrogramservice.cpp
  • CMakeLists.txt
  • src/shared/tests/CMakeLists.txt
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/shared/axis/axisscale.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/spectrogram/CMakeLists.txt
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/axis/axistypes.h
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.h
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/CMakeLists.txt
  • src/spectrogram/spectrogramtypes.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/shared/axis/axisticks.h
  • src/shared/axis/numberscale.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/shared/axis/axislabel.cpp

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp (1)

236-255: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

xTicksLog: starting multiplier can be 10, causing first-decade corruption.

At line 238, std::ceil(loFreq() / increment) can return 10 when loFreq() lies in (9·10^e, 10^(e+1)) (e.g., 95, 99.99, 950). The wrap check at lines 251-254 only triggers when ++multiplier % 10 == 0. Starting at 10, the sequence goes 10 → 11 → … → 19 → 20, emitting ticks at incorrect decade boundaries (10·10^e, 11·10^e, ... instead of 1·10^(e+1), 2·10^(e+1), ...).

While the default 20 Hz loFreq avoids this, mParameters.mLoFreq is user/preset configurable.

🛠️ Suggested fix

Normalize the initial multiplier/exponent pair immediately after ceil:

     auto exponent = std::floor(left);
     auto increment = std::pow(10, exponent);
     int multiplier = std::ceil(loFreq() / increment);
+    if (multiplier >= 10) {
+        multiplier = 1;
+        ++exponent;
+        increment = std::pow(10, exponent);
+    }
🧹 Nitpick comments (2)
src/effects/builtin_collection/graphiceq/GraphicEqView.qml (1)

74-84: 💤 Low value

Button labeled "Reset" still calls flatten() method.

The button ID and text were changed from "Flatten" to "Reset" (lines 74, 82), but the onClicked handler at line 84 still calls graphicEq.bandsModel.flatten(). If "Reset" is the preferred user-facing term, consider renaming the underlying method for consistency, or document why different terminology is used in the UI vs. the model API.

src/shared/axis/axislabel.cpp (1)

17-17: 💤 Low value

Redundant parentheses in the while condition.

Line 17 has double parentheses in the while condition: while (((label.contains('.') && (label.endsWith('0'))) || label.endsWith('.'))). The outer parentheses are unnecessary.

♻️ Simplification
-        while (((label.contains('.') && (label.endsWith('0'))) || label.endsWith('.'))) {
+        while ((label.contains('.') && label.endsWith('0')) || label.endsWith('.')) {

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 5b595752-5627-4551-ba7d-b535c972634d

📥 Commits

Reviewing files that changed from the base of the PR and between 9cf2829 and 6b3be62.

📒 Files selected for processing (10)
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/graphiceq/GraphicEqView.qml
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/shared/axis/axislabel.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml

Comment thread src/shared/axis/axislabel.cpp
Comment thread src/shared/axis/axisticks.h Outdated
@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from 6b3be62 to a5fb65c Compare May 15, 2026 13:37
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp (1)

236-255: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

multiplier can start at 10, corrupting the first decade's tick pattern.

When loFreq() falls in the range (9×10^e, 10^(e+1)), std::ceil(loFreq() / increment) returns 10. The subsequent loop increments from 10 → 11 → ... → 19 → 20, wrapping only when ++multiplier reaches a multiple of 10. This produces ticks at 10×10^e, 11×10^e, ..., 19×10^e (values from the next decade) before wrapping, and causes the major-tick check multiplier == 1 || multiplier == 5 to select the wrong frequencies.

With the default 20 Hz loFreq this doesn't trigger, but mParameters.mLoFreq is user-configurable (e.g., 95 Hz would exhibit the issue).

🔧 Proposed fix

Normalize the initial multiplier/exponent pair immediately after the ceil:

     auto exponent = std::floor(left);
     auto increment = std::pow(10, exponent);
     int multiplier = std::ceil(loFreq() / increment);
+    if (multiplier >= 10) {
+        // ceil() can yield 10 when loFreq is just below a power of 10.
+        // Normalize into [1, 9] so the wrap logic stays in sync.
+        multiplier = 1;
+        ++exponent;
+    }
src/shared/axis/axislabel.cpp (1)

82-88: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: labels.clear() empties the vector before indexed access.

Line 82 resizes labels to ticks.size(), but line 85 calls labels.clear(), which empties the vector (size becomes 0). The subsequent labels[tick.index] access at line 87 is out-of-bounds and triggers undefined behavior. The static analyzer correctly flagged this as containerOutOfBounds.

🛠️ Proposed fix

Remove the clear() call and reuse the resized vector by overwriting each element:

     std::vector<std::string> labels;
     labels.resize(ticks.size());
     int numDecimalDigits = 0;
     while (numDecimalDigits <= maxDecimalDigits) {
-        labels.clear();
+        // Reuse the resized vector; overwrite each relevant element
         for (const auto& tick : ticksWithIndex) {
             labels[tick.index] = valueToLabel(tick.tick.val, numDecimalDigits);
         }

This preserves the allocated size and correctly updates each label slot.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 108778a1-8c6c-442e-8515-7ab8f7e15515

📥 Commits

Reviewing files that changed from the base of the PR and between 6b3be62 and a5fb65c.

📒 Files selected for processing (48)
  • .gitignore
  • .vscode/launch.json
  • CMakeLists.txt
  • muse
  • src/CMakeLists.txt
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/builtin_effects_collection.qrc
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/effects/builtin_collection/dynamics/compressor/CompressorView.qml
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/effects/builtin_collection/graphiceq/GraphicEqView.qml
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/CMakeLists.txt
  • src/shared/axis/axislabel.cpp
  • src/shared/axis/axislabel.h
  • src/shared/axis/axisscale.h
  • src/shared/axis/axisticks.cpp
  • src/shared/axis/axisticks.h
  • src/shared/axis/axistypes.h
  • src/shared/axis/numberscale.h
  • src/shared/tests/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/spectrogram/CMakeLists.txt
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/spectrogramtypes.cpp
  • src/spectrogram/spectrogramtypes.h
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.h
  • src/uicomponents/au_uicomponents.qrc
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
💤 Files with no reviewable changes (3)
  • src/spectrogram/internal/spectrogramutils.h
  • src/spectrogram/internal/spectrogramutils.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.h
✅ Files skipped from review due to trivial changes (7)
  • src/spectrogram/internal/au3/au3spectrogramclipchannelpainter.cpp
  • src/spectrogram/internal/au3/au3spectrogramsettings.cpp
  • src/spectrogram/spectrogramtypes.cpp
  • muse
  • src/spectrogram/view/channelspectralselectionmodel.cpp
  • src/spectrogram/internal/frequencyselectioncontroller.cpp
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (30)
  • src/uicomponents/au_uicomponents.qrc
  • src/spectrogram/internal/spectrogramservice.cpp
  • src/effects/builtin_collection/internal/builtincollectionloader.cpp
  • src/shared/axis/axisscale.h
  • src/uicomponents/qml/Audacity/UiComponents/qmldir
  • CMakeLists.txt
  • src/shared/axis/axistypes.h
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.cpp
  • src/shared/CMakeLists.txt
  • src/shared/tests/axisticks_tests.cpp
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.h
  • src/shared/tests/CMakeLists.txt
  • .vscode/launch.json
  • src/effects/builtin_collection/filtercurveeq/filtercurveeq.h
  • src/spectrogram/CMakeLists.txt
  • src/shared/axis/axislabel.h
  • src/effects/builtin_collection/equalization_common/equalizationenvelopeutils.h
  • src/effects/builtin_collection/dynamics/compressor/CompressionCurve.qml
  • src/shared/axis/axisticks.h
  • src/effects/builtin_collection/CMakeLists.txt
  • src/effects/builtin_collection/filtercurveeq/filtercurvemodel.cpp
  • src/effects/builtin_collection/graphiceq/equalizationbandsliders.cpp
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqTooltip.qml
  • src/uicomponents/qml/Audacity/UiComponents/components/GridPlot.qml
  • src/effects/builtin_collection/filtercurveeq/FilterCurveEqView.qml
  • src/shared/axis/axisticks.cpp
  • src/spectrogram/view/spectrogramchannelrulermodel.cpp
  • src/effects/builtin_collection/filtercurveeq/filtercurveeqviewmodel.h
  • src/shared/axis/numberscale.h

Comment thread src/shared/axis/axislabel.cpp Outdated
while (((label.contains('.') && (label.endsWith('0'))) || label.endsWith('.'))) {
label.chop(1);
}
return label.toStdString() + "k";
Copy link
Copy Markdown
Member

@kryksyh kryksyh May 15, 2026

Choose a reason for hiding this comment

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

most likely this unit should be translated, for russian it should be к instead of k as in кГц vs kHz

@saintmatthieu saintmatthieu force-pushed the 10223-port-filter-curve-eq branch from a5fb65c to 6ed28ad Compare May 15, 2026 16:56
@saintmatthieu saintmatthieu merged commit f57a8a3 into audacity:master May 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port Filter Curve EQ effect

2 participants