Playing a MIDI file

I need some help for playing MIDI files. I have problems with the MidiFile Class, and I would like someone post some simple code to play a MIDI file, with the opening of each ports etc.

Someone can helps me ? I have finished the GUI after nearly 1 weew and now I’m blocking again on something else, with pointers etc. It’s boring :frowning:

For now, I’m here :

[code]portMIDI = MidiOutput::openDevice(0);

File* fileHard;
FileInputStream* fileInputStream;
MidiFile fileMIDI;

fileHard = new File (T(“C:\Projets\Devcpp\file.mid”)); // (1)
fileInputStream = fileHard->createInputStream();
fileMIDI->readFrom(fileHard->createInputStream()); // (2)[/code]

The line with the (1) gives me a warning :

[quote][Warning] unknown escape sequence ‘\P’
[Warning] unknown escape sequence ‘\D’
[Warning] unknown escape sequence ‘\G’
[Warning] unknown escape sequence ‘\M’[/quote]

And I have problems with the (2) about pointers, i need a InputStream& in parameter, and I only have InputStream*…

There is a thing I don’t understand, the function for reading audio data from an InputStream is :

And for MIDI data that’s :

Why a “&” here and a “*” on the other ?

For the first warning, I have understood, the path must be written with some “/” and not “” :lol:

But I haven’t found a solution for the MidiFile class…

Nobody can help me ?

You should just be able to pass in the contents of your InputStream pointer to the MidiFile::readFrom() method. i.e.

[code]portMIDI = MidiOutput::openDevice(0);

File* fileHard;
FileInputStream* fileInputStream;
MidiFile fileMIDI;

fileHard = new File (T(“C:\Projets\Devcpp\file.mid”));
fileInputStream = fileHard->createInputStream();
fileMIDI->readFrom(*fileInputStream); // note the *[/code]

An & for a function parameter means you’re passing the variable in by reference. Basically when you pass a variable in to a function (e.g. function(int variable); ), a copy of the variable is made for the function to operate on. Passing in a variable by reference (e.g. function(int& variable); ) means a copy is not made - instead the function acts on the actual variable you passed in. Essentially it’s like passing in a pointer to a variable, but you don’t use pointer notation (e.g. you’d have stream.readByte() inside the function instead of stream->readByte()).

  • Niall.

Yeah that works ! And thanks for the explanation :wink:

No Problem :slight_smile:

  • Niall.

I have another question, I just need some explanation…

Apparently, to play a MIDI file, I must use the method createControllerUpdatesForTime() to get the MidiMessage objects and the sendMessageNow of my MIDI output.

So, I must use a loop which will get the time corresponding to each Event (from 0 to getNumEvents() ), use a Timer to know if I am at the right Time to send all the messages one by one… and maybe I need the Thread class because I don’t want the program to be freezed while the file is played…

Am I right ? Someone can enlight me on this ?

So ? Someone has an idea ? And apparently, I can’t use the Timer class to do this, I must use the Thread class to perform the time tests…

Nobody uses MIDI commands here ? I haven’t found any example in the libraries, and I really need an answer, I’m on it for nearly 1 week and I don’t how to do… I’m working on a Drum Loop manager project, and I just need some minor MIDI capabilities, after I will be able to show you my work…

Okay, I haven’t done any MIDI stuff with JUCE, but I’ll give it a shot…

With your midiMessageSequence, do you not just loop through it, dispatching/operating on the messages however you want? e.g.

[code]int i;
MidiMessage *tempMessage;
MidiMessageSequence *seq;
MidiFile phil();

seq = phil->getTrack(0); //or whatever track you want…
for(i=0;igetNumEvents();i++)
tempMessage = &(seq->getEventPointer()->message);
[/code]
Then use tempMessage to do whatever it is you’re wanting to do.

  • Niall.

Thanks for the tip, I had a problem to get the MidiMessage one by one… I will have a try :wink: Then, the problem will be to send them to the midi port at the right time…

With your help, now I have got some sound ! ! ! Yeah ! :lol:

But the synchronization is the problem now… I have created a thread, and used the wait instruction to… wait for the next event, at the right time, and with a maximum priority, the play of midi file is, you can imagine, not slow at all, but the drummer has lost 20 years of practice :lol: Now I’m looking for a way to do the synchronization faster…

That works perfectly ! Yeaaaaaaaaaaah ! Thanks for your help NialM :wink: I will post the source code if somebody is interested… Because it’s not so easy to make the file be played well… I had to do a sort of each event before the loop in my Thread to accelerate the process…

Yeah- would be great to see your concotion. Thanks!

OK, I have posted a part of my code, the files cannot be compiled alone, but you will find all of the code I have done to play a MIDI file, and a class to use a SimpleListBox that allows to choose the MIDI output you want :wink:

It’s here : PlayingMidiFile.zip

The code is not optimizated at maximum, I have some bugs when I try to play with the port MidiYoke to use Kontakt and NSKIT7 in Tracktion, with more than 30% of CPU used, so I have still some work… (for example, the uint64 method of the Time class is useless, I don’t need too much precision…)

Hello.
Link to MididFile.zip isn’t valid.
I don’t know format of midi file.
And trying to play MIDI by the touch.
So could someone help me with MIDI file playing.

Is there an alternative link to an example that plays a MIDI file?