COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 11-19-2009, 10:36 PM   #1
asiohead
Human being with feelings
 
Join Date: Oct 2009
Posts: 8
Default construct midi messages and sync them to the tempo

I’m working on a step sequencer, and I need to create some midi events. But I can’t exactly figure out how. (The notes come from an array, NotesArray.)

I initialise a IMidiMsg once like this

IMidiMsg* seqMsg = new IMidiMsg(0,128,0,100);


Then I generated a message like this in a method that gets called in ProcessDoubleReplacing


seqMsg->MakeNoteOnMsg(NotesArray[x],100,0);
mMidiQueue.push_back(*seqMsg);
seqMsg->MakeNoteOffMsg(NotesArray[x],0);
mMidiQueue.push_back(*seqMsg);
SendMidiMsg(seqMsg);

But this doesn’t work at all because I have no control over how fast the queue is being read. The note events are being fired so close, nothin really happens.
Also, why do you have to give an offset in the MakeNote … methods, and what does this Offset mean exactly ?



Could someone explain how to construct and work with midi messages, where to send/handle them (ProcessMidiMsg or ProcessDoubleReplacing)

How do I sync the sending of messages to the tempo, because now they just fire at sample rate. I have no control over it.

And how do I set the other parameters on the seqMsg object , like decay, note length, AttackTime, etc …



Thanx
asiohead is offline   Reply With Quote
Old 11-21-2009, 05:55 AM   #2
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
Default

When your host software receives a MIDI message, your plug is probably busy generating audio in ProcessDoubleReplacing. So the host temporarily stores the MIDI message, recording it's sample offset. When your plug returns from ProcessDoubleReplacing (i.e. when it has finished processing a sample block), the host will send the temporarilly stored MIDI messages to your plug using ProcessMidiMsg. Along with the MIDI message it gives you the sample offset at which the MIDI message should occur. This offset is relatoive to the next ProcessDoubleReplacing call, so an offset of 0 means before the 1st sample, an offset of 1 means after the 1st sample etc.

When you send MIDI back out and you want it to be sample accurate, you will need to specify the offset again. I don't think it's safe to specify an offset larger than the current sample block frame count, so your plug will have to know when exactly to send the MIDI messages. Here is a fragment of code that sends a Note On and a Note Off every 0.5 seconds (assuming a sample rate of 44100 Hz):

Code:
void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
	for (int offset = 0; offset < nFrames; ++offset)
	{
		// Note On
		if (mTimer == 0)
			SendMidiMsg(&IMidiMsg(offset, 0x90, mNoteNumber, 127));
		// Note Off
		else if (mTimer == 22050)
			SendMidiMsg(&IMidiMsg(offset, 0x80, mNoteNumber, 0));

		if (++mTimer >= 44100)
			mTimer = 0;
	}
}
I hope this clarifies things a bit for you.
Tale is online now   Reply With Quote
Old 11-21-2009, 03:21 PM   #3
asiohead
Human being with feelings
 
Join Date: Oct 2009
Posts: 8
Default

It does indeed, thanx mate, I really appreciate it !
asiohead is offline   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 11:43 PM.


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