Create MIDI messages programatically

Hello,

I’m currently doing my master’s thesis, and I’m developing (or rather attempting to) an audio plug-in that will work with Lindenmayer-Systems (L-Systems) to generate music.

Since I’m new to audio plugin development and C++, I’m struggling sometimes to get a grasp of things. I’ve already looked at the docs of iPlug2 and the current project I have is essentially a duplicate of the IPlugInstrument example. What I’m looking for help is how to play notes programatically. This is because L-Systems basically generate strings which I will parse to a set of notes according to a set of rules, so I need to know how to control MIDI messages in code.

Thanks for any help provided and sorry if the question is too newbie.

In general terms what you want to do is to process the massages that arrive at the ProcessMidiMsg function. Some of these messages will have a NoteOn or NoteOff status, corresponding to the press and release of a key on a MIDI keyboard. If you identify one such message you can keep interrogating it in order to create a code that will let the ProcessBlock function to reproduce the corresponding sound, which you can do by use of member variables, or some other method.

Here is a very brief example:

void Keyboard::ProcessMidiMsg(const IMidiMsg& msg)
{
    int status = msg.StatusMsg();
    if (status == IMidiMsg::kNoteOn)
    {
        int n = msg.NoteNumber();
        // create code to let the programme know that note n should be played
    }
    else if (status == IMidiMsg::kNoteOff)
    {
        int n = msg.NoteNumber();
        // create code to let the programme know that note n should stop
    }
}

void Keyboard::ProcessBlock( **sample** ** inputs, **sample** ** outputs, int nFrames)
{
    // print data on the output channels according to the notes that should be playing
}

I hope this is in the direction of what you’re looking for. Sometimes when you start working with a new library a good idea is to type something like msg. and take a look at what the autocomplete shows… a lot of the functions will be very intuitive and others will require more research.

Good luck with your project!

1 Like

Thank you so much for the reply!

What I specifically need is not to process MIDI messages from a keyboard but rather create the MIDI messages myself and send them to ProcessBlock (the ultimate goal of my plugin would be that it would generate the sounds for you based on other inputs rather than you playing them). Although your example didn’t showcase this, it certainly helped me better understand the flow of things. In summary, I have to implement a “CreateMidiMsg”. Once I achieve this I will post it here to potentially help others in the future.

Oh, I see. Nice. But then maybe what you want to do is to create a duplicate of the IPlugMidiEffect example instead.

I will take a look at it, thanks! Right now I’m struggling with controlling the duration of my MIDI notes, but it’s more of a C++ challenge than an iPlug2 one :sweat_smile:

In plug-ins MIDI events have sample-offsets so that notes can be triggered sample-accurately. Timers, Callables and especially Sleep() are not the correct way to deal with timing. MIDI is mainly handled on the real time audio thread, and the way that you do it is to count the samples between events.

Here is an example

void IPlugEffect::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
{
  static int count = 0; // these variables should really be member variables
  static bool noteOn = true; // by making them static, their state is persisted across calls to this method
  
  for (int s = 0; s < nFrames; s++) {
    if (count == 0) {
      IMidiMsg msg;
      if (noteOn) {
        msg.MakeNoteOnMsg(60, 127, s);
      }
      else {
        msg.MakeNoteOffMsg(60, s);
      }
      noteOn = !noteOn;
      SendMidiMsg(msg);
    }
    
    count++;
    
    count %= 44100;
  }
}
1 Like

Thanks for the help @olilarkin and @Ric . I realized I am trying to run before I can walk with C++ and audio plug-in development in general, so I will have to come back to iPlug2 in the future.

I was wondering if you know a framework or tool where I wouldn’t need to develop or handle the DSP part of an audio plug-in but rather the higher level stuff only (e.g. just adding or removing parameters, changing the types of instrument, play a sequence of notes directly), almost sort of a low code approach. Sadly time is short on my thesis delivery and I have to get something done in about a month.

Many thanks again.

everything you mention screams MIDI messages… I don’t really know of any such tool but I understand that some DAWs (e.g. Cubase) are very MIDI friendly and perhaps there’s a way of creating macros or scripts for it, but, as I said above, I don’t know for sure.

On the other hand you could probably get someone else’s help with programming some sort of kernel that you could fiddle with later. It’s difficult to say without knowing too much about your project.