Does anyone know how to get Juce’s MidiOutput class to work with TiMidity? I am writing a cross-platform “virtual piano” program, but it’s not going to be much use to Linux users unless it will work with a software synth!
Currently I have a ComboBox populated with the devices obtained from MidiOutput::getDevices() which is fine, I can select from “Midi Through”, “OSS Sequencer” and the 4 “TiMidity (x)” virtual devices.
The ComboBoxListener is set up to close any current device and open the new device when it is selected:
class MidiDevicesListener : public ComboBoxListener
{
public:
MidiDevicesListener()
{
}
~MidiDevicesListener()
{
}
void comboBoxChanged(ComboBox* comboBox)
{
delete outputDevice;
outputDevice = MidiOutput::openDevice(comboBox->getSelectedItemIndex());
outputDevice->reset();
outputDevice->setVolume(1.0, 1.0);
}
};
This IS opening the device because I used an AlertWindow to see if it was returning a NULL pointer, which it is not.
I have a MidiKeyboardStateListener set up like this:
class KeyStateListener : public MidiKeyboardStateListener
{
public:
KeyStateListener()
{
}
~KeyStateListener()
{
}
void handleNoteOn(MidiKeyboardState* keyState, int midiChannel, int midiNoteNumber, float velocity)
{
if (outputDevice) {
outputDevice->sendMessageNow(MidiMessage::noteOn(midiChannel, midiNoteNumber, velocity));
}
}
void handleNoteOff(MidiKeyboardState* keyState, int midiChannel, int midiNoteNumber)
{
if (outputDevice) {
outputDevice->sendMessageNow(MidiMessage::noteOff(midiChannel, midiNoteNumber));
}
}
};
Again, I tested this with AlertWindows inside the if statements, and they appeared so the TiMidity device is definately getting opened.
But it makes about as much noise as a… thing that doesn’t make noise!
And the thing is, a program I have called “NoteEdit” shows a virtual MIDI device, and my program can connect to that and it successfully records the notes, and even loops them through to the TiMidity device so I can hear them!
So I am obviously missing some kind of code to do with volume or whatever. Does anyone know the solution to this strange problem?
I am even ensuring the MidiKeyboardComponent is sending “audible” notes by maxing out it’s velocity:
addAndMakeVisible(keyComponent = new PCAnoKeyboard(keyState));
keyComponent->setVelocity(1.0);
(PCAnoKeyboard is just a subclass of MidiKeyboardComponent that “skins” itself in it’s constructor, nothing wrong with that )
As a VB6 programmer moving to C++ after about a year of translating C++ code from MSDN into VB6 code, I’m loving JUCE so far, I doubt I’ll ever be going Back to (Visual) Basic(s) again!
EDIT: I just tried this with my physical keyboard using a USB-MIDI cable, and the “output” light on that is not even blinking as I click notes. So that’s just making things even more confusing - How come the only thing that “sees” what the program is sending is NoteEdit’s virtual device?
Also further confirmation that it is definately opening the device - If it really, really can’t open it (for example beacuse I try to select the USB Midi after unplugging it), as expected from that code it crashes with a null pointer exception - Devices that exist and aren’t busy don’t crash it so they’re being opened just fine.