MIDI Events, len and other crap

I’m wondering what would be the best practices on handling my MIDI Events on my Sequencer project (Wusik SQ200).

I receive the MIDI Events, add to my Array, all good. But the thing is, when drawing and editing events, I need to know the len of each Note On event, and also where its Note Off event is located at. I tried to create my own solution but I don’t think it works correctly, and makes things much more complicated. I can share if you guys want to check, but don’t laugh. :wink:

So I wonder, is there something already there in JUCE that I’m overseeing? Any ideas?

Thanks again.

Cheers, WilliamK
www.Wusik.com

Don’t store Note Off event separately, store the note length instead. Naturally you must create your own Midi event class for that. MIDI is not Juce’s strongest point.

Is there a reason you don’t use MidiMessageSequence?

Can you elaborate on this statement?

Thanks guys! :slight_smile:

I store midi events in XmlElements - but my type of plugins are not your average sequencer. But one of the above answers nails it: you store the length along with the noteOn event data.

I haven’t looked at your classes, but MidiMessageSequence may still work for you. You can store any unit of time in the MidiMessage object. It’s a double, and you interpret it’s meaning for playback. So you can store PPQ time in it.

Right you are, I will try to see if I could use it instead. Thanks again guys.

Ok, replacing my entire code to use MidiMessage and the MidiMessageSequence, much more organized and elegant. :slight_smile: Thanks JULES!!

Now, as for automation, I guess I could use SysEx on MidiMessages? Or something else? I need to know which track the automation is for and parameter index and a float value.

Cheers, WilliamK

The only sane plan is to avoid MIDI as much as you possibly can:

  • convert MIDI into a richer representation of your own as soon as it enters your app
  • throw away the original MIDI
  • do not store any of your state as MIDI
  • don’t do any internal processing using MIDI
  • work entirely with your own data model format, and convert it back to real MIDI only at the very last moment if you absolutely need to send it somewhere external (or into a VST etc)

And also: just don’t write your own engine. That’s a job for crazy people. Just use the tracktion engine. We spent 20-30 man-years figuring out all the hard stuff, and will continue to make it better as tech evolves. If you have a great sequencer idea, just write your own GUI on top of it and don’t re-invent the wheel when it comes to building an engine. I’m biased, but that’d be my advice even if someone else had written it.

Automation is one of the most insanely difficult things to deal with. Took us a decade of huge re-writes to get it right in the tracktion engine, and if you’re asking this level of vague question about how to tackle the whole subject then you clearly also have years of learning ahead of you before you stand much chance of building a decent implementation. Seriously: you’re the target audience for the tracktion engine :slight_smile:

1 Like

Jesus Jules, you always do this to me. For years you have been replying like this. :-\ I really don’t get you. Did you at least check my project? I posted the name on the original thread. Is a simple sequencer, nothing fancy. And its already working, I’m just looking for ways to IMPROVE it…

I guess we programmers always think we know it all… :wink:

  1. Anyway, I’m using now the MidiMessageSequence and it works perfectly, so far.

  2. For automation, is just simple. I have a few values: the track or effect number, the parameter and value. That’s all I need. I even added a type for future proofing. I just add it as SYSEX, and it works great.

  3. My sequencer is like those old hardware MIDI sequencers, so it makes sense to be nostalgic and also use MIDI internally. :-p

    struct WMidiSysexAutomation
    {
    public:
    WMidiSysexAutomation(uint8_t _type, uint8_t _source, int16_t _parameter, float _value) : source(_source), parameter(_parameter), value(_value), type(_type) {};
    uint8_t type, source;
    uint16_t parameter;
    float value;
    };

So, in the end, now its working. I’m 90% finished converting the code to the new format.

Cheers (and sorry for the jokes and rants)

Here’s a MIDI hardware sequencer I (myself alone) created from ZERO. :slight_smile:

Edit: Just search for Beat707 and you will find several projects I created.

Darn @jules :slight_smile:

The only sane plan is to avoid MIDI as much as you possibly can:

  • convert MIDI into a richer representation of your own as soon as it enters your app
  • throw away the original MIDI
  • do not store any of your state as MIDI
  • don’t do any internal processing using MIDI
  • work entirely with your own data model format, and convert it back to real MIDI only at the very last moment if you absolutely need to send it somewhere external (or into a VST etc)

That’s exactly what I did. Started before you open sourced the Tracktion engine of course but all that I need (so far) working. If I’d had Tracktion that would have saved me tons of time (and heaps of nightly live midi msg debugging sessions). FWIW @WilliamkWusik it took me about 4 months to build a working Midi Editor/Sequencer/Generator engine (after hours). I didn’t have Jules’ above advice (but somehow that seemed the logical approach to me) and of course what I have comes nowhere close to what Tracktion offers. So far my little engine does what it says on the tin but god knows how many hidden subtle bugs must be lurking (comparing my 4 months to Jules’ 20 man years… makes me shudder).

Hmmm should I consider a rewrite? Would be great to get a pianoroll editor for free … time to start reading Tracktion documentation I guess!

Anyhow, if anyone is interested here’s 2 projects of mine that use my minimal engine:
https://github.com/tomto66/Topiary-Presetz
https://github.com/tomto66/Topiary-Beatz

And this.

Sorry, my free time for browsing people’s projects is very scarce… your original question was “what would be the best practices on handling my MIDI Events on my Sequencer project”, so that’s what I was answering!

Of course it depends why you’re writing something - if you’re enjoying the journey of working on a simple old-style sequencer then of course, do it with whatever tools are the most fun! But if you’re trying to actually create a working product, then not re-invent any wheels would make more sense.

Hi, I’m revisiting this topic at the moment because I have to add MIDI Clips to a new project. I’m curious to know your approaches for a richer representation of MIDI events for polyphonic and unquantized MIDI clips.

What are your experiences using different data structures for this purpose?

I have been using lists of events sorted by beat position so far. I wonder if this can be improved. tracktion_engine seems to be using a ValueTree which looks convenient to add support for “undo” and to convert from/to binary. However I’m a bit concerned about its performance to continuously retrieve events in a particular beat range in MIDI clips with thousands of notes (long piano recordings).

That’s why we have concrete objects which wrap the ValueTrees and provide quick array and property lookups.

1 Like

Thanks. I had missed that in my quick analysis of your code.