Closed Boscop closed 1 year ago
There are ways to do this more directly and I think it would involve functions like AddMediaItemToTrack
, AddTakeToMediaItem
, CreateNewMIDIItemInProj
etc. However, it's not super straightforward and it would probably need more time to turn this into good idiomatic Rust. InsertMedia
on the other hand should be very easy to add to the medium-level API. If that's enough for you, I could give it a go.
Yes, I think having InsertMedia
would be sufficient for now. Thanks :)
It seems the other way (CreateNewMIDIItemInProj
etc.) requires bindings to many more functions, to be able to populate/modify the newly created media item.
I just realized that the VST also needs to clear the track before adding the new media item, so I'd also need these functions (to iterate over all items and delete each): https://www.reaper.fm/sdk/reascript/reascripthelp.html#GetTrackNumMediaItems https://www.reaper.fm/sdk/reascript/reascripthelp.html#GetTrackMediaItem https://www.reaper.fm/sdk/reascript/reascripthelp.html#DeleteTrackMediaItem
(I could add it on a new track but that would not be idempotent behavior. Also the midi track's FX and routings should survive the "midi file reload".)
Btw, can non-VST Reaper plugin DLLs run in the background, or are they only ran on demand like scripts (and need to be compiled as a VST if they should stay running in the background)?
I only used the Reaper extension API from inside a VST or from a LUA script until now, so I'm wondering if I should compile this one as a VST or as a normal DLL (that exposes ReaperPluginEntry
).
@Boscop Please see the draft pull request. There are some things that still need to be figured out concerning insert_media()
.
BTW, if it's urgent, you can always fall back to the low-level API (which brings us down to C level but maybe better than nothing).
Btw, can non-VST Reaper plugin DLLs run in the background, or are they only ran on demand like scripts (and need to be compiled as a VST if they should stay running in the background)? I only used the Reaper extension API from inside a VST or from a LUA script until now, so I'm wondering if I should compile this one as a VST or as a normal DLL (that exposes
ReaperPluginEntry
).
REAPER extension plug-ins are loaded directly at REAPER startup and are unloaded when it quits. So if you want something that's around all the time and doesn't benefit from having multiple instances, an extension plug-in is an even better choice than a VST plug-in. reaper-rs has support for both. No need to write the ReaperPluginEntry
stuff yourself, there's a macro for that, see the README.
Thanks for the quick implementation, I'll try it out asap. Yes, I saw that section in the Readme, which caused me to even consider compiling it as non-VST plugin.
But if I wanted to have a text input field (for entering the path to the (Rust) DLL that will be watched and auto-reloaded, which produces the composition), how can I expose an Editor from a non-VST extension plugin? (And then how to open it inside Reaper?)
Btw, I'm considering using imgui-baseview
(or iced_baseview
) for the GUI, which GUI lib are you using for your Rust-rewrite of ReaLearn? :)
If it's just simple text fields, you could use get_user_inputs()
. If you have a child window handle that doesn't need to be a parent, you could dock it by using DockWindowAdd
and related functions (not yet in reaper-medium
but easy to add). Or how about opening a top-level Boscop webview window 😃, triggered by a REAPER action (which can be assigned to a toolbar button) or a custom entry in the "Extensions" menu?
Btw, I'm considering using
imgui-baseview
(oriced_baseview
) for the GUI, which GUI lib are you using for your Rust-rewrite of ReaLearn? :)
I'm using SWELL (which is a part of WDL and exposed via low-level API), but it's not something I would generally recommend because it's raw Win32 UI programming which feels very clunky, more so in a language like Rust. Also, I didn't find a way to avoid having RefCell
s all over the place because I'm not in control of the event loop (could probably have just ignored reentrancy issues by using UnsafeCell
instead, but then it felt like giving up on some of Rust's safety measures). I just did it because SWELL comes as part of REAPER and standard OS UI components are pretty well suited for a tool like ReaLearn.
I'm interested how things work with imgui-baseview and stuff!
Having a bit of a nightmare with this at the moment.
I also want to use the InserMedia so I'm down in the low API at the moment.
unsafe {
let c_str = CString::new(msg.data).unwrap();
let c_world: *const c_char = c_str.as_ptr() as *const c_char;
Reaper::get().medium_reaper().low().InsertMedia(c_world, 1);
}
I found this solution, which claims to work:
let c_str = CString::new(to).unwrap();
let c_world: *const c_char = c_str.as_ptr() as *const c_char;
I was also sure you would have written utility method somewhere for this but I'm just not good enough at reading rust to spot it.
It saying "use of a moved value" on the msg.data
in this line let c_str = CString::new(msg.data.).unwrap();
But adding Copy and Clone traits falls foul of the fact it's got two "String" fields ... this is making my OO brain hurt.
I guess firstly, did you create a wrapper / utility method?
If not, how on earth do I get this working? LOL. NURSE!!
Can you please add bindings for the
InsertMedia
function, it would be very useful :) My use case is, I'm experimenting with midi livecoding in Rust and I want to integrate it into Reaper as a VST. The only way to edit the arrangement via the API seems to be viaInsertMedia
: Every time the composition changes, writing the midi from memory into a file on disk and then callingInsertMedia
. (Or can you see another way?)There are 2 related functions: https://www.reaper.fm/sdk/reascript/reascripthelp.html#InsertMedia https://www.reaper.fm/sdk/reascript/reascripthelp.html#InsertMediaSection
But for my use case I only need
InsertMedia
, because every call will overwrite the full composition.CC @PrismaPhonic https://github.com/helgoboss/reaper-rs/issues/18