MidiInput Callback?

How can I setup the MidiInput Callback? Do I first have to inherit from MidiInputCallback? Then I have the following but getting errors

[code]MidiInput* MidiIn;

MidiIn = MidiInput::openDevice(0,handleIncomingMidiMessage);

//And the callback function
void handleIncomingMidiMessage(MidiIn,MidiMessage& m){

}[/code]

Whats the correct way to set it up so I can listen to the incoming midi messages?

Ok, changed it now to

[code]MidiInput* MidiIn;
MidiIn = MidiInput::openDevice(1,this);//Opens Midi Yoke 1 Device

//And the callback function
void handleIncomingMidiMessage(MidiInput* source,const MidiMessage& m){
//do something with the incoming midi message
}[/code]

Im fairly sure this is correct, however Im unable to receive any MidiMessages Im using MidiYoke as the virtual midi loopback driver with cubase, its working for midisend messages and cubase is able to pick them up, but the callback function is not triggered at all no matter what channel or device I send messages from within cubase. Is there something else I have to implement for this to work? I have tested the juce demo audio section with Midi Yoke and that can receive messages from cubase which triggers the juce midi keyboard from cubase, but the above code is not responding to any incoming midimessages?

since MidiInput worker is a simple thread, you should start/stop it for it to begun collecting midi messages.

MidiInput only has about 3 methods you can call, and one of those is called start(). In openDevice it tells you to call start() and stop() to start and stop it… Please let me know how I could have made this any more obvious!

Hello everyone,

can someone type an example of how the midimessage input stream would look like and what each part represents. Im writing an app that will get piano midi input and then the recieved midi messages will be compared to a file

thanks

[quote=“Kilmer”]
can someone type an example of how the midimessage input stream would look like and what each part represents. Im writing an app that will get piano midi input and then the recieved midi messages will be compared to a file[/quote]

Your best approach here is just to try it. The MidiMessage objects are just wrappers for the raw MIDI data with convenience functions; a tutorial on MIDI is, I think, beyond the scope of this forum. Instead, I suggest you just hook up your code to receive MIDI data and then look at what you get in the debugger.

will the handleIncomingMidiMessage function be called automatically when a midi message is recieved, or will we have to create a while loop to keep checking it to see if a midi message arrived or not?

thanks a lot guys

It’s a callback, so will get called by a high-priority thread when messages arrive. Obviously you mustn’t do anything time-consuming or UI-related during the callback.

Hello everyone,

concerning midiInput, the start function should be called once a user starts playing a musical device. The stop function should be called once a user stops playing. How can our program detect when it should stop the midiinput and call the stop function, for eample is there a way we can allow our program to detect that the user stoppped playing?

thanks

eh? Don’t understand what you’re getting at there…

You can leave the input running for as long as you want to - it won’t do any harm.

well, i think they are rules that you’ve just made up.

  • ‘start’ when the user starts playing
  • ‘stop’ when the user stops

I suppose that’s one way of looking at it.

Actually, ‘start’ starts the input, and ‘stop’ stops recieving messages. So you’ll need to start BEFORE they start playing, and stop AFTER they’ve stopped playing something they want to record. Ah - there’s the word - this sort of behaviour is usually mapped to a ‘RECORD’ button, yes? So you just have a way of starting and stopping the input which the user will invoke.

You COULD start a timer in your callback which - if no messages are recieved until it ends - will automatically stop the midi input. That’s how you’d detect if they’d stopped if you really wanted to. But to detect when they start? Well, you’ll need to be listenning to the input to know that, so you’d need to have started already anyway.

Thanks so much guys.

Sorry Jules i didnt make my point clear. My bad

kindest regards,

When ever i call the stop function for my midiinput, i get the following warning which halts my program:

Unhandled exception at 0x0048ca30 in Testing.exe: 0xC0000005: Access violation reading location 0x00000004.

Testing is the name of my class

thanks

I basically want to test my program to see if it is recieving midi messages but this exception is haulting my program and thus not allowing me to test.

Sounds like a basic c++ mistake. You’re probably calling stop() on a null or dangling pointer.

im a bit confused for this part. heres my code so far:

J have this function to sart listening to input

void ModeOne::startListening()
{
//Declare for recieving midi messages from the midi input
MidiInputCallback* pianoMessages;

//Open device
  1. piano = MidiInput::openDevice(1, pianoMessages);

    //Start listening for midi messages from the piano
    piano ->start();

}

i have a seperate function handleIncomingMidiMessages to be called when events r recieved

for the line numbered 1) should it b the way it is or shoud it be:
piano = MidiInput::openDevice(1, this);

whenever i put “this” i get an error saying

1>.\ModeOne.cpp(31) : error C2664: ‘juce::MidiInput::openDevice’ : cannot convert parameter 2 from 'ModeOne *const ’ to ‘juce::MidiInputCallback *’

any help would be appreciated

thanks

Just to clarify:
According to the below code, will the handleIncomingMidiMessage be called. I dont see any relation between pianoMessages and the handleIncomingMidiMessage function.

int main()
{
MidiInput* piano;
MidiInputCallback* pianoMessages;
piano = MidiInput::openDevice(1, pianoMessages);
piano ->start;
}
void handleIncomingMidiMessage(MidiInput* source,const MidiMessage& m){
cout << “Key Pressed”;
}

you’re right, there is absolutely no relationship between pianoMessages and the function. look at it - you’re creating pianoMessages there - a pointer. what do you expect to happen?

MidiInputCallback is a base class. You need to provide a pointer to an instance of your own MidiInputCallback subclass. In your subclass, you will have defined the body of the virtual function ‘handleIncomingMidiMessage(MidiInput*, const MidiMessage&)’.

Not knowing a lot about your class, i can’t tell you what the solution for you would be - but I imagine it would be to inherit MidiInputCallback into ModeOne. Then, you would indeed use piano = MidiInput::openDevice (1,this); - you couldn’t before because you didn’t have MidiInputCallback as one of the base classes.

here’s my code, due to my inexperience with c++ i didnt exactly understand what to do. i changed the name of my callback function to the function name but nothing changed. I’d really appreciate it if you would tell me where to change and modify my code.

Thanks a lot

#include
#include “juce.h”

//Include timer functions
#include <time.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

using namespace std;

class ModeOne {
//Declare midi input device
MidiInput* piano;

public:

void startListening();

void handleIncomingMidiMessages(MidiMessage);

};

void ModeOne::startListening()
{
//Get the indexes of the midiInput devices
StringArray deviceIndex = StringArray::StringArray();
deviceIndex = MidiInput::getDevices();
cout << deviceIndex[0] +"\n";
cout << deviceIndex[1] +"\n";
cout << deviceIndex[2] +"\n";
cout << deviceIndex[3] +"\n";
//Declare for recieving midi messages from the midi input
MidiInputCallback* handleIncomingMidiMessage = 0;

//Open device
piano = MidiInput::openDevice(2, handleIncomingMidiMessage);

//Start listening for midi messages from the piano
piano ->start();

cout << "reached";

}

//And the callback function and do something with the incoming midi message
void handleIncomingMidiMessage(MidiInput* source,const MidiMessage& m){

//Declare midi message attributes
int byte1, byte2, byte3;
const double timeStamp = 0;

//Initialize variables
	byte1 = 0;
	byte2 = 0;
	byte3 = 0;

	MidiMessage keyPlayed = MidiMessage::MidiMessage (byte1, byte2, byte3, timeStamp);
	keyPlayed = m;

cout << “Key Pressed”;

}

int main()
{
ModeOne ModeOneListener;
ModeOneListener.startListening();

}