Hi,
One year ago I wrote the Zoabis ZS001 for a Masters Thesis. I used the jVSTwRapper and Java. Below is the code that kills all MIDI notes.
The Following Code is Java!
[code]if (kill == true) {
for (int k = 0; k < 128; k++) {
byte midiNoteMessage[] = new byte[4];
// Set the type of the MIDI EVENT
vme.setType(VSTEvent.VST_EVENT_MIDI_TYPE);
vme.setByteSize(24); // 4 * 8 bytes
vme.setDeltaFrames(event.getDeltaFrames()); // set this to
// 0.
midiNoteMessage[0] = (byte) (NOTE_ON); // sets midi status
// to
// note on
midiNoteMessage[1] = (byte) (k); // sets midi note number
// (changes the note by
// 1)
midiNoteMessage[2] = (byte) (0); // sets velocity
midiNoteMessage[3] = (byte) (0); // Always zero.
vme.setData(midiNoteMessage); // Copy the NOTE message into
// VstMidiEventStruct
VSTEvent[] ve = new VSTEvent[1]; // create a VSTEVENT
ve[0] = vme; // insert the MIDIEVENT to the VSTEVENT
ves.setNumEvents(1); // set the number of the VSTEVENTS to 1
ves.setEvents(ve); // insert the VSTEVENT to VSTEVENTS
sendVstEventsToHost(ves);
}
kill = false;
}[/code]
For the relevance of this read onâŠ
One year on and I have just began learning C++ and using Juce. I would like, for now, to [color=#FF0000]simply transpose a MIDI in real-time, adding 5 semitones.[/color] This is just a proof of concept. So far I have no luck. I am using the Audio Plugin Demo as a starting point, though obviously ticking âPlugin wants MIDI input/ Output/ Is a Synthâ.
I assumed the place to do the transposition would be in processBlock and here is my code for that method:
[code]void ZS1AudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
const int numSamples = buffer.getNumSamples();
int channel, dp = 0;
// Go through the incoming data, and apply our gain to it...
for (channel = 0; channel < getNumInputChannels(); ++channel)
buffer.applyGain (channel, 0, buffer.getNumSamples(), gain);
// Now pass any incoming midi messages to our keyboard state object, and let it
// add messages to the buffer if the user is clicking on the on-screen keys
keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true);
//midi input part
if (!midiMessages.isEmpty())
{
MidiMessage midi_message(0xf0);
MidiBuffer output;
int sample_number;
MidiBuffer::Iterator midi_buffer_iter(midiMessages);
while(midi_buffer_iter.getNextEvent(midi_message,sample_number))
{
//I sent some messages to my GUI to make sure I was editing the right numbers...
if( this->_currentMidi) { delete this->_currentMidi; this->_currentMidi = NULL; }
this->_currentMidi = new MidiMessage(midi_message);
_sampleNumber = sample_number;
_lastNoteNumber = midi_message.getNoteNumber();
_lastNoteVelocity = midi_message.getVelocity();
//Preparing the transpose message:
const int notenum = midi_message.getNoteNumber();
const uint8 velocity = midi_message.getVelocity();
const int channel = midi_message.getChannel();
//Transposing by 5 semitones:
int newNote = notenum+5;
//Thought this would work but it didn't:
output.addEvent(MidiMessage::noteOn(channel,newNote,velocity),sample_number);
}
}
// and now get the synth to process these midi events and generate its output.
synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
// Apply our delay effect to the new output..
for (channel = 0; channel < getNumInputChannels(); ++channel)
{
float* channelData = buffer.getSampleData (channel);
float* delayData = delayBuffer.getSampleData (jmin (channel, delayBuffer.getNumChannels() - 1));
dp = delayPosition;
for (int i = 0; i < numSamples; ++i)
{
const float in = channelData[i];
channelData[i] += delayData[dp];
delayData[dp] = (delayData[dp] + in) * delay;
if (++dp > delayBuffer.getNumSamples())
dp = 0;
}
}
delayPosition = dp;
// In case we have more outputs than inputs, we'll clear any output
// channels that didn't contain input data, (because these aren't
// guaranteed to be empty - they may contain garbage).
for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
buffer.clear (i, 0, buffer.getNumSamples());
// ask the host for the current time so we can display it...
AudioPlayHead::CurrentPositionInfo newTime;
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (newTime))
{
// Successfully got the current time from the host..
lastPosInfo = newTime;
}
else
{
// If the host fails to fill-in the current time, we'll just clear it to a default..
lastPosInfo.resetToDefault();
}
}
[/code]
Can anybody please tell me why
doesnât do it for me?
I included the Java code as there is a process like so:
[list]*Copy the NOTE message into a VstMidiEventStruct[/list]
[list]*Create a VSTEVENT[/list]
[list]*Insert the MIDIEVENT to the VSTEVENT[/list]
[list]*Set the number of the VSTEVENTS to 1[/list]
[list]*Insert the VSTEVENT to VSTEVENTS[/list]
and finally:
[list]*sendVstEventsToHost(ves);[/list]
So, it seems like
is quite simple in comparison. I must be missing some steps?
[color=#FF0000]How can I edit the code so my plugin adds 5 semitones to the note number?[/color]
Thanks in advance for any help