reaper-oss / sws

The SWS extension is a collection of features that seamlessly integrate into REAPER, the Digital Audio Workstation (DAW) software by Cockos, Inc
https://www.sws-extension.org/
MIT License
448 stars 85 forks source link

Bug: 'SWS/BR: Disable "Ignore project tempo" for selected MIDI items preserving time position of MIDI events (use tempo at item's start)' (`BR_MidiItemTimePos::Restore`) handles loop points incorrectly? #1862

Open J-MR-T opened 6 months ago

J-MR-T commented 6 months ago

Hi there, and thanks for all of your amazing work on the extensions, they've really helped me over the years.

I'm trying to create a custom action that basically changes the projects BPM number, without changing any of the actual playback characteristics, a sort of "call this time 90bpm instead of 120bpm, but make everything still sound exactly the same, please". This seems easy for audio, but quite difficult for MIDI, but now, thanks to the BR Enable/Disable "Ignore project tempo" [...] preserving time position [...] actions I'm almost there. The only remainning problem is, that using the Disable action does not seem to respect loop boundaries properly. For example, taking this item: image (at 90 bpm project tempo, and Ignoring project tempo and using 45 bpm instead: image ) If I run SWS/BR: Disable "Ignore project tempo" for selected MIDI items preserving time position of MIDI events (use tempo at item's start) on this item, this is the result: image (this result is independent of the timebase of the midi item/track) As you can see, it does preserve the midi item positions/lengths 'in the real world', as I would like, but only up until the loop point, where it fails, and puts the loop too far back.

I've had a look at the code, and it seems this issue is somewhere in BR_MidiItemTimePos::Restore (judging from these lines)?

Unfortunately, I'm nowhere near familiar enough with the REAPER C++ API or this project to remedy this myself, but I hope this helps in fixing this issue (if it even is one? BR_MidiItemTimePos::Restore does seem to have some handling of loop points, so maybe this is intentional?). But given some pointers as to what to do, I'd also be happy to implement this myself and submit a PR, but that would probably end up being more work for the maintainers, than simply fixing it?

Buy-One commented 6 months ago

Just an idea for a workaround: 1. disable loop source 2. enable ignore tempo 3. re-enable loop source

This may or may not work but worth a try

J-MR-T commented 6 months ago

Just an idea for a workaround: 1. disable loop source 2. enable ignore tempo 3. re-enable loop source

This may or may not work but worth a try

Certainly a valid idea, but unfortunately disabling loop source seems to reset the loop points to the item boundaries, thus re-enabling it does not work. But what would probably work is to do it with a script:

  1. go through all selected midi items
    • save loop point and item boundaries
    • trim item to make the new bounds equal to the loop points
    • disable loop source
  2. use disable ignore tempo action
  3. do 1. in reverse with the saved loop points and item boundaries

But that's so much hassle, that I'd rather try to understand why the current action doesn't do what I want, and try to fix that instead 🙃