In my plugin I have need to change channel gain, mute on/off, solo on/off (and possible some other things) with midi messages (well, with device(mixer) which has midi interface and can send midi messages to plugin of-course :) ).
I cant test plugin on real device, so I can not experiment.
Are there standard functions inside MidiMessage class which are dealing with this?
I suppose I can use getChannel to retrieve specific channel, but what other functions should I use?
What is use for getChannelPressureValue (what is pressure), getAfterTouchValue...?
MidiMessage::controllerEvent (const int channel, const int controllerType, const int value)
where controllerType should be 7 and value 0 for silent and 127 for full volume.
A list of available midi controller messages can be found at various sites e.g. http://www.sonicspot.com/guide/midifiles.html
getChannelPressureValue() and getAfterTouchValue() is used to retrieve the pressure used when playing a key on the keyboard (not avilable on all keyboards and not to confuse with velocity). getAfterTouchValue() refers to individual keys, wheras getChannelPressureValue() refers to all keys played of a channel. I think.
You can use these value to vary the pitch, modulation or whatever you like of the sound.
So if I need to check if I should add more gain to channel I suppose I can use these methods:
int getChannel () const noexcept (from here I can pick which channel is affected ?)
Returns the midi channel associated with the message.
bool isForChannel (int channelNumber) const noexcept (or I can check is channel of interest directly)
Returns true if the message applies to the given midi channel.
bool isController () const noexcept (is this neccessary to check before anything? I mean if not controller message than I suppose I should not do anything)
bool isControllerOfType (int controllerType) const noexcept (i suppose this maps to controllerType ?)
Returns true if this message is a controller message and if it has the specified controller type.
int getControllerNumber () const noexcept (is this same as controllerType?)
Returns the controller number of a controller message.
int getControllerValue () const noexcept (actual value?)
Returns the controller value from a controller message.
If you know the channel it should suffce to add a volume controller message for that channel. Or you can loop through all 16 channels if you want the same volume for them. Otherwise you can look for a noteOn message and get its channel with message->getChannel().
You should be able to test this with the built in Midiplayer (that's one in Windows, and I reccon there's also one in MacOs). I haven't tried this though.
if (midiMessage.isController()) {
int channel = midiMessage.getChannel() - 1; // [1 - 16], 0 means no channel
int value = midiMessage.getControllerValue(); // [0 - 127]
if (channel < 0) {
return;
}
SignalChannel* signalChannel = this->getSignalChannel(channel);
if (midiMessage.isControllerOfType(Mixer::MAIN_VOLUME_CONTROLLER_TYPE)) { // Mixer::MAIN_VOLUME_CONTROLLER_TYPE = 7
float fvalue = (value / 127.0f) * 26.0f - 20.0f; // map to [-20, 6]
fvalue = Decibels::decibelsToGain(fvalue, -20.0f); // convert db to gain
signalChannel->setGain(fvalue); // set gain for channel
} else if (midiMessage.isControllerOfType(Mixer::BALANCE_CONTROLLER_TYPE) ||
midiMessage.isControllerOfType(Mixer::PAN_CONTROLLER_TYPE)) {
signalChannel->setPanning(0.0078125f * value + 0.5f);
}
}
But I cant figure out what messages I could use for mute and solo. I'm not sure I can use info on this page http://www.cs.cf.ac.uk/Dave/Multimedia/node158.html to achieve this.
Edit:
I think for mute I can use
if (midiMessage.isAllSoundOff()) {
int channel = midiMessage.getChannel();
// IS This ok?
bool isOn = midiMessage.getControllerValue() == 127; // 0 = off; 127 = on
if (channel > 0) {
SignalChannel* signalChannel = this->getSignalChannel(channel);
signalChannel->setActive(isOn);
}
}
but can figure out what can I do to detect solo midi message (or what message mixete will pass to my program so I can detect it and set channel to solo). Also I'm not sure if code above detect (mute on/off) correctly; is isAllSoundOff controller message at all?
I'm not sure what you're trying to do. Perhaps you could be a bit more specific about what are your midi source and destination, i.e. where does the input to the plugin come from and to where goes the output?