can a vst plugin output midi data?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

hi,
is it possible to build a vst plugin that can directly output midi messages to the midi output?
And if this is so, where can it be done with?
many thanx
kriz

Post

i do this with synthedit all the time. seems to work with fl, orion, tracktion, cubase, energy xt.

free to :p
www.synthedit.com
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.

Post

If you want to do it with real coding:

Here it is:
At first you have to define the cando flag for it:

Code: Select all

long YourPlugin::canDo (char* text)
{
    if (!strcmp (text, "receiveVstEvents"))
    return 1;
    if (!strcmp (text, "receiveVstMidiEvent"))
    return 1;
    if (!strcmp(text, "receiveVstTimeInfo"))
    return 1;

    if (!strcmp(text, "sendVstEvents"))
    return 1;
    if (!strcmp(text, "sendVstMidiEvent"))
    return 1;

    return -1;	
}
Second, you should know how the structures for sending looks alike:

Code: Select all

struct VstEvents			// a block of events for the current audio block
{
	long numEvents;
	long reserved;			// zero
	VstEvent* events[2];	// variable
};

//---Defined Events--------------------------------
struct VstMidiEvent		// to be casted from a VstEvent
{
    long type;			// kVstMidiType
    long byteSize;		// 24
    long deltaFrames;	// sample frames related to the current block start sample position
    long flags;			// none defined yet

    long noteLength;	// (in sample frames) of entire note, if available, else 0
    long noteOffset;	// offset into note from note start if available, else 0

    char midiData[4];	// 1 thru 3 midi bytes; midiData[3] is reserved (zero)
    char detune;		// -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
    char noteOffVelocity;
    char reserved1;		// zero
    char reserved2;		// zero
};
Last but not least, you have to prepare the code for sending your MIDI data.

Code: Select all

// prepare the data ...
sendVstEventsToHost(/* VstEvents* */ events);
It is all in the header files of the SDK.

Post

hi,
i read about the codes i need to implement the midi output of a plugin, but after reading through all the functions of the vst sdk, i could not find any reference to setting a midi channel or a midi output directly in the plugin, so the data goes directly to that midi output on tha channel.
Do i need the vst module architecture for this, or can it be done in the standard vst sdk?

Post

It can be done in the standard VST SDK.

I assume you would need to read the above block of code for VstMidiEvent and char midiData[4]. Then look at the following link for information on how to set the MIDI channel for each MIDI datum
http://www.harmony-central.com/MIDI/Doc/table1.html
and set the midiData[] values accordingly.

Post

jackle&hyde wrote:

Code: Select all

long YourPlugin::canDo (char* text)
{
    if (!strcmp (text, "receiveVstEvents"))
    return 1;
    if (!strcmp (text, "receiveVstMidiEvent"))
    return 1;
    if (!strcmp(text, "receiveVstTimeInfo"))
    return 1;

    if (!strcmp(text, "sendVstEvents"))
    return 1;
    if (!strcmp(text, "sendVstMidiEvent"))
    return 1;

    return -1;	
}
please don't take this as a criticism of your style j&h, but I think it is easier & cleaner to write that as:

Code: Select all

long YourPlugin::canDo (char* text)
{
    if ((0 == strcmp(text, "receiveVstEvents")) 
     || (0 == strcmp(text, "receiveVstMidiEvent"))
     || (0 == strcmp(text, "receiveVstTimeInfo"))
     || (0 == strcmp(text, "sendVstEvents"))
     || (0 == strcmp(text, "sendVstMidiEvent"))
    ) {
        return 1;
    }
    return -1;
}
Works the same, but is easier to read.

Post

texture wrote:
jackle&hyde wrote:

Code: Select all

long YourPlugin::canDo (char* text)
{
    if (!strcmp (text, "receiveVstEvents"))
    return 1;
    if (!strcmp (text, "receiveVstMidiEvent"))
    return 1;
    if (!strcmp(text, "receiveVstTimeInfo"))
    return 1;

    if (!strcmp(text, "sendVstEvents"))
    return 1;
    if (!strcmp(text, "sendVstMidiEvent"))
    return 1;

    return -1;	
}
please don't take this as a criticism of your style j&h, but I think it is easier & cleaner to write that as:

Code: Select all

long YourPlugin::canDo (char* text)
{
    if ((0 == strcmp(text, "receiveVstEvents")) 
     || (0 == strcmp(text, "receiveVstMidiEvent"))
     || (0 == strcmp(text, "receiveVstTimeInfo"))
     || (0 == strcmp(text, "sendVstEvents"))
     || (0 == strcmp(text, "sendVstMidiEvent"))
    ) {
        return 1;
    }
    return -1;
}
Works the same, but is easier to read.
Hi, you super developer!

The only thing I did, was to copy from the original VST SDK EXAMPLES!!!
:x

It's not my code. :D
Glad to see some of your real work!
Or are you merely a theoretican? :roll:

Be careful to teach experienced developers with a brunch of releases out there...
(I mean, the crators of those examples have also allot of those experiences!)

Post

degrotebozewolf wrote:hi,
i read about the codes i need to implement the midi output of a plugin, but after reading through all the functions of the vst sdk, i could not find any reference to setting a midi channel or a midi output directly in the plugin, so the data goes directly to that midi output on tha channel.
Do i need the vst module architecture for this, or can it be done in the standard vst sdk?
Of course, You can much do with VST (MIDI enabled) effects and VSTIs.

But still much more possibilities are with the Module Architecture. The only disadvantage is, that the Module Architecture is at the moment merely supported by some few host applications...

Post

jackle&hyde wrote: It's not my code. :D
good.
Glad to see some of your real work!
My real development work is none of your business. A lot of it is confidential.
VST stuff is just a hobby for me.
Be careful to teach experienced developers with a brunch of releases out there...
(I mean, the crators of those examples have also allot of those experiences!) :lol:
I was merely pointing out a nicer way of writing it. I did say not to take it as a personal attack - it wasn't intended to be one.

If experienced developers have lost thier enthusiasm for finding better ways to do things, then thats just fine. I personally quite like finding out little ways to do things better.
There are other people on here who might feel the same, and might have found it useful.

Post

both versions suck :lol:

a method should only have a single return statement, so I'd prefer to use a automatic variable, set that to a value depending on the conditions and return it at the end of the method :wink:

canDo is not really time critical code, but in theory the version with the multiple ifs is faster 'cause it doesn`t have to evaluate 5 string comparisons every time...

Niko

p.s. don't take this serious, I couldn't resist and in the end I think these things have a lot to do with personal preferences, coding habits etc. As long as it works and you understand what you're doing it is perfectly ok, imho.

Post

_niko_ wrote: a method should only have a single return statement, so I'd prefer to use a automatic variable, set that to a value depending on the conditions and return it at the end of the method
Generally I'd agree - I think it often makes the code more readable and maintainable to do this. I usually only bother when it would be confusing to someone reading the code if it hadn't been done.
_niko_ wrote: canDo is not really time critical code, but in theory the version with the multiple ifs is faster 'cause it doesn`t have to evaluate 5 string comparisons every time...
Neither does the second one.

Post

thanks for just posting anything. maybe one day, it will sink in :p
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.

Post

what about something like this?

Code: Select all

member variable:
std::set< std::string > m_canDo;

in constructor:
m_canDo.insert("receiveVstEvents"):
m_canDo.insert("receiveVstMidiEvent");
m_canDo.insert("receiveVstTimeInfo");
m_canDo.insert("sendVstEvents");
m_canDo.insert("sendVstMidiEvent");

the method:
long YourPlugin::canDo (char* text) 
{ 
  if( m_canDo.find(text) != m_canDo.end() )
    return 1;
  else
    return -1;
}

Post

stefancrs wrote:what about something like this?

Code: Select all

member variable:
std::set< std::string > m_canDo;

in constructor:
m_canDo.insert("receiveVstEvents"):
m_canDo.insert("receiveVstMidiEvent");
m_canDo.insert("receiveVstTimeInfo");
m_canDo.insert("sendVstEvents");
m_canDo.insert("sendVstMidiEvent");

the method:
long YourPlugin::canDo (char* text) 
{ 
  if( m_canDo.find(text) != m_canDo.end() )
    return 1;
  else
    return -1;
}
I like that way :)

Post

this is like some kind of nerd playground!!

Post Reply

Return to “DSP and Plugin Development”