Basically, I am trying record the midi performance data of two people on one machine. The midi is sampled at 100hrz, and each performer is using two separate MIDI busses. I am still unsure what format I am going to to save the data as, but I know I will want two files, with time stamps, and that after each sample all midi data for a single performer will be collated into a vector (so two devices would end up as 256 elements in the array).
I pulled apart the MidiInputSelectorComponent to start with, and got it to enable/disable midi ports. Now I’m trying to create a separate thread for each performer (although I guess I could sample both performers from a single thread), that holds dynamically created MidiMessageCollectors. The idea being that I call
and hard link the MidiMessageCollector to a single device input. Then in my thread, I was iterating over the MidiMessageCollectors and calling their “removeNextBlockOfMessages()” to pack them into the data struct (which is just a text file right now).
the problem is that I am getting an error: “JUCE Assertion failure in /Developer/juce/amalgamation/…/src/audio/midi/juce_MidiMessageCollector.cpp, line 83”
Which I think is related to setting the sampling rate, but you can see below that I do call the reset() function?
//midiHandlers is my collection of MidiMessageCollectors
midiHandlers[pos]->reset(44100.00);
I think it might be due to the thread trying to access the MidiMessageCollector before I have a chance to reset it? I’m not sure what it is really?
Sorry if I sound off the wall, I am pretty new to JUCE. If there is a better way to approach this, I would be all ears
Here is the code to add the MidiMessageCollectors. I just add them from a listbox of available midi devices.
#include "MidiDataPackagingThread.h"
MidiDataPackagingThread::MidiDataPackagingThread(AudioDeviceManager& deviceManager_)
: Thread ("Midi Packaging Thread"),
deviceManager (deviceManager_)
{
//hard set for now = to 10ms
bufferSize = 44100/100;
_pMIDIlog = new File("../MIDIlog.txt");
_pMIDIlog->replaceWithText("");
startThread (10);
}
MidiDataPackagingThread::~MidiDataPackagingThread()
{
// allow the thread 2 seconds to stop cleanly - should be plenty of time.
stopThread (2000);
}
void MidiDataPackagingThread::run()
{
// threadShouldExit() returns true when the stopThread() method has been
// called, so we should check it often, and exit as soon as it gets flagged.
while (! threadShouldExit())
{
// sleep a bit so the threads don't all grind the CPU to a halt..
wait (10);
// fill a midi buffer with incoming messages from the midi input.
MidiBuffer incomingMidi;
for(int i = 0; i < midiHandlers.size(); i++)
{
if(midiHandlers[i] != NULL)
{
midiHandlers[i]->removeNextBlockOfMessages (incomingMidi, bufferSize);
if(!incomingMidi.isEmpty())
{
_pMIDIlog->appendText("Device " + String::String(i));
_pMIDIlog->appendText("\n");
MidiBuffer::Iterator midiIterator(incomingMidi);
MidiMessage msg(0x80,0,0,0);
int pos;
while(midiIterator.getNextEvent(msg, pos))
{
if(msg.isController())
{
_pMIDIlog->appendText("Velocity: " + String::String(msg.getControllerValue())
+ " ControllerNumber: "
+ String::String(msg.getControllerNumber())
+ " TimeStamp: "
+ String::String(msg.getTimeStamp()) + "\n");
}
else
{
_pMIDIlog->appendText("Velocity: " + String::String(msg.getFloatVelocity())
+ " NoteNumber: "
+ String::String(msg.getNoteNumber())
+ " TimeStamp: "
+ String::String(msg.getTimeStamp()) + "\n");
}
}
_pMIDIlog->appendText("******************************************************");
_pMIDIlog->appendText("\n");
}
}
}
}
}
void MidiDataPackagingThread::addMidiHandler(int pos, const String& midiDevice_)
{
midiHandlers.insert(pos, new MidiMessageCollector());
//This needs to be set by the global sr note by a constant OV 2011
deviceManager.addMidiInputCallback (midiDevice_, midiHandlers[pos]);
midiHandlers[pos]->reset(44100.00);
}
void MidiDataPackagingThread::removeMidiHandler(int pos, const String& midiDevice_)
{
deviceManager.removeMidiInputCallback (midiDevice_, midiHandlers[pos]);
midiHandlers.remove(pos);
}
and a picture if that helps at all.