https://bugs.kde.org/show_bug.cgi?id=528027

            Bug ID: 528027
           Summary: Mixer filters reverse order on track effect add
    Classification: Applications
           Product: kdenlive
      Version First 26.04.3
       Reported In:
          Platform: Flatpak
                OS: Linux
            Status: REPORTED
          Severity: minor
          Priority: NOR
         Component: Audio Effects & Transitions
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

DESCRIPTION

Summary: Adding a track effect reverses the order of the audio mixer's filters,
so the track meter ignores the fader after every other effect edit

How this was found: the bug was found with AI while implementing a custom audio
effect. It was then reproduced and tested manually with the Flatpak version
26.08.2, using the saved project files and script below. A fix is proposed
below and was tested on a clean upstream build.

STEPS TO REPRODUCE

1. Start Kdenlive and create a new project with the default tracks. Save it as
before.kdenlive (Ctrl+S).
2. Add an audio effect, for example Gain, to the track A1 itself, not to a
clip. Select the A1 track header so the effect stack shows the track, then
double-click the effect in the Effects panel, or drag it onto the A1 track
header.
3. Save the project again as after1.kdenlive.
4. Run the script below on each file: python3 check-mixer-order.py
before.kdenlive and python3 check-mixer-order.py after1.kdenlive.
5. Optional: add a second track effect, save as after2.kdenlive and run the
script again. The order is correct again.

OBSERVED RESULT

The mixer creates its hidden track filters in the order volume (fader), panner,
audiolevel (meter). Each time an effect is planted on the track, they are moved
after the new effect in reverse order: audiolevel, panner, volume. So the meter
switches between post-fader and pre-fader with each edit. Master effects go
through the same code, but I did not test them.

EXPECTED RESULT

The mixer's filters keep their order after the track effects: volume, panner,
audiolevel, so the meter always shows the post-fader level.

SOFTWARE/OS VERSIONS

Kdenlive version: 26.08.2
MLT version: 7.43.0
Operating system: Debian GNU/Linux 13 (trixie), Linux 6.12
Installation method: Flatpak (org.kde.kdenlive from Flathub) (also tested on a
clean local build of 26.04.3)

ADDITIONAL INFORMATION

Python checker script:

```
#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as ET

def props(el):
    return {p.get("name"): (p.text or "") for p in el.findall("property")}

root = ET.parse(sys.argv[1]).getroot()
bad = 0
for tr in root.iter("tractor"):
    filters = [props(f) for f in tr.findall("filter")]
    names = [f.get("mlt_service", "?") for f in filters]
    if "volume" not in names or "audiolevel" not in names:
        continue
    label = props(tr).get("kdenlive:track_name") or tr.get("id")
    ok = names.index("volume") < names.index("audiolevel")
    bad += not ok
    print(f"{label:12} {' '.join(names)}  ->  {'OK, meter after fader' if ok
else 'BUG, meter before fader'}")
sys.exit(1 if bad else 0)
```

CAUSE AND PROPOSED FIX

In EffectStackModel::registerItem
(src/effects/effectstack/model/effectstackmodel.cpp), the filters with
internal_added are moved to the end one at a time, from the highest index down.
Each move to the end puts that filter after the ones moved before it, which
reverses them. Moving them in ascending order, with an offset for those already
moved, keeps their order:

```
-                std::sort(ixToMove.rbegin(), ixToMove.rend());
-                for (auto &ix : ixToMove) {
-                    if (ix < ct - 1) {
-                        ms->move_filter(ix, ct - 1);
-                    }
-                }
+                // Move them to the end in their current order: each move
shifts the following filters down by one
+                int moved = 0;
+                for (auto &ix : ixToMove) {
+                    ms->move_filter(ix - moved, ct - 1);
+                    moved++;
+                }
```
mlt_service_move_filter does nothing when from and to are equal, so the old ix
< ct - 1 check is no longer needed.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to