Old 01-12-2018, 03:59 AM   #1
sai'ke
Human being with feelings
 
Join Date: Aug 2009
Posts: 26
Default Tracking interface for MIDI blocks.

Hello everyone,
apologies for repeating a question I've seen asked before on the forums. I'm a tracker. I migrated from Jeskola Buzz to REAPER for its superior audio quality and dealing with live input. I want to love Reaper and certainly love many aspects of it, but while I have used it for quite some time now, I just can't get around the frustration that I have to enter MIDI notes by mouse or be forced to use the keyboard step sequencer mode.

I'd love to have the ability to view MIDI blocks in both a tracked representation and the current piano roll format, being able to enter notes as I would in a tracker but without losing the option to make notes slightly longer or shorter in MIDI representation later. I've looked at ReViSiT, but it is cumbersome to add this extra layer to the workflow.

Renoise looks great, but other than the tracking interface, it doesn't seem to suit my workflow very well. I'd also like to shuffle the MIDI blocks around, like I already can in REAPER.

The idea would be to have a tracked representation as an alternative for looking at MIDI blocks. The tracked representation would simply round the MIDI notes to which row they belong as good as possible given a chosen row length. Manipulations would be done by row size, so a delete would trigger a shift by the row size (preserving any offset w.r.t. the row that is in the MIDI block).

Now the question, I am wondering whether the reaper extension system is flexible enough that this could somehow be achieved. Is the MIDI data exposed to the extension API somehow? Can you commit data to a MIDI block? Would it be possible to attach extra information to the individual data that goes into a note that would allow such an interface to keep track of which column the note used to be part of in the tracked representation (I would have no issue with randomly assigning a column the first time a MIDI object is opened if it wasn't created in the tracked representation)?

Just to make it clear, I am not looking for a plugin that can render tracked info to MIDI, or one that can give MIDI output. These exist and add cumbersome steps to the workflow. I would really want to build a transparent interface to the MIDI block directly (if this is possible).

Is there a good reference manual for the extension system? Where would I get started?

I am reasonably proficient in coding C/C++ and I wouldn't mind a challenging project but I am unsure whether this is even remotely possible at all, or where to find more info on the API involved.

Any help would be greatly appreciated!

Last edited by sai'ke; 01-12-2018 at 05:36 AM.
sai'ke is offline   Reply With Quote
Old 01-12-2018, 08:21 AM   #2
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,005
Default

It might be relatively easy if you didn't need that "data per individual note" thing. I think you would only need to implement a custom GUI for editing the MIDI data in that case. Doing GUIs with C++ is a royal hassle of its own but techniques to do it for Reaper extension plugins are more or less available.

But since you need the extra per-note data, I can't really say if that is straightforward or a complete mess to implement.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 01-13-2018, 05:58 AM   #3
sai'ke
Human being with feelings
 
Join Date: Aug 2009
Posts: 26
Default

Thanks!

I've started work on it. Prototyping it with the LUA API first. If that turns out to be fast enough, I might stick to LUA for this altogether, but we'll see.

I think the issue with the additional note data is that I need to keep track of what's in which tracker column somehow. One reason tracking is often so easy is because when you enter the next note, the previous one is automatically stopped at that location. This makes quickly jotting down melodies and beats very easy and fast. It would be pretty frustrating if every time the tracker view is opened, the column assignment would be randomized.

I wish notes had an exposed GUID or something assigned to them, so that I could keep a table with this information myself on the LUA side, but alas, there doesn't seem to be a way to uniquely identify a note. At least, not from what I can see in the API.

As a first approach, I've chosen to store the tracker channel by using the MIDI channel information of a note. This is of course not ideal, since it would mean that for many VSTs, I would have to remap that entire track to a specific channel at the end to get it to play nice with certain VST plugins.
Attached Images
File Type: png hackeytrackey.png (45.4 KB, 28 views)
sai'ke is offline   Reply With Quote
Old 01-15-2018, 03:00 AM   #4
sai'ke
Human being with feelings
 
Join Date: Aug 2009
Posts: 26
Default

So far, progress has been surprisingly good. I've decided to use the channel as column info. I treat MIDI data in channel 0 as 'untracked' and this will get assigned into the tracker channels automatically. When interpreting the MIDI data as tracked format, the channels with channel > 0 will be interpreted and placed in the columns first. The stuff on channel zero will then be assigned a new channel where there is a free block large enough to support the note. Every note gives rise to a note and optionally an OFF marker in the column (if it isn't cut off by another note, in which case there is no OFF marker). OFF markers which are not associated with a note are stored as text "OFF+channel index" in the midi take. This seems to work pretty decently so far.

I've hit a minor snag though. I have two questions that maybe someone with more experience with the API could help me with.

1. Is there any way to write/read MIDI notes and/or events into the MIDI clipboard from the scripting side without having a MIDI editor open? If not, can I open and close one within a frame so that the user does not see it? Otherwise I'll have to code my own clipboard, which isn't difficult, but it would have been nice if notes copied in the tracker would also be available in the rest of the DAW.

2. What is the best way to keep track of undo information?
I've tried both:
reaper.Undo_BeginBlock()
reaper.MarkProjectDirty(0)
do my (multiple) changes here
reaper.Undo_EndBlock("Tracker: Delete note", -1)

and
reaper.Undo_OnStateChange("Tracker: Delete note")
reaper.MarkProjectDirty(0)
do my (multiple) changes here

Both of them seem to group certain undo information in a way that is not obvious to me? I may be interpreting the API wrong.
sai'ke is offline   Reply With Quote
Old 03-18-2018, 01:20 PM   #5
magwa101
Human being with feelings
 
Join Date: Feb 2018
Posts: 15
Default Reaper tracker

I very much agree with your comment about limitations of cursor and keyboard (either) input. Tracker is one example of a more programmatic interface. There could be other generative interfaces (ex. Axon2) that could benefit from a "direct access to Midi blocks" API so that changes are bidirectionally shared from VST<>Reaper. Back and forth editing is a PITA that def leads to lost work and is hard live. Technically a memory mapped file would be awesome. No locking on bus sized writes (int, float, etc.) just "last write wins" but perhaps need some locking on strings, maybe...

I've been trying Hackey-Trackey and I can't tell if this is the same project you're working on. I've been doing many other Reaper work flow setup, but am going to get deeper into the "Tracker" interface over the next couple of months.

Also, at some point, I'd like to throw in some code contributions, but, music first.

I could write some docs for this as Trackers are new to me in general and I'll be going through it nuts to bolts anyway, may as well document it.

One project that seems to take the "I'm a real VST but use Reaper APIs" is Play: http://www.helgoboss.org/projects/playtime/ They may have some answers about the API limitations.
magwa101 is online now   Reply With Quote
Old 03-19-2018, 02:55 AM   #6
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,005
Default

Quote:
Originally Posted by sai'ke View Post
reaper.Undo_OnStateChange("Tracker: Delete note")
reaper.MarkProjectDirty(0)
do my (multiple) changes here
Undo_OnStateChange should be called after you have made your changes. Also I am not sure if calling MarkProjectDirty is strictly necessary.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:03 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.