Having issues reading note


#1

Hi everyone!

I wrotte some ligne of code which are supposed to read a midi file get the note of  he track and play it

But I can't figure out why it's not working, any idea?

http://pastebin.com/iPUP6Z0w

Thank you for your support

Best regards!

Goldiman


#2

I see many questionable things in your code, such as putting a juce::File on the heap, and not using smart pointers (e.g.: juce::ScopedPointer)! Did you just jump onto JUCE/C++ from a pure C background?

In any case, the main issue here is that you aren't applying some form of timing between your notes - you're essentially sending all of your notes really REALLY quickly to your device. For the sake of just getting it working, you could sleep between calls (blocking the main thread). I'll leave figuring how long to sleep for up to you.

Also, why are you calling MidiOutput::sendMessageNow as a static method? You should be doing this, OuputMidi->MidiOutput-­­>sendMessageNow, instead of this, OuputMidi->MidiOutput::sendMessageNow.


#3

Hello!

Thank your for answering me,

Yes I come from a C background, I never used smart pointer and don't really know if I use the "C" pointer the right way....

I added the sleep but I after i changed the sendMessageNow method I add some compilation error but I don't understand them.

Here the code I tried to modify : http://pastebin.com/ibY1eCPd

Here the syntax error http://pastebin.com/FUn9vAQ4

Thank you for your support

Best regards!

Goldiman


#4

Hello,

After some research I found the good way ,OuputMidi->sendMessageNow(*MessageMidi); and also changed the 

const File* fileHard;
fileHard = new File("./music.mid") ;

into 

const File* fileHard = new File("C://music.mid");

But I still don't have any sound, other questionable things?

Sorry If my question sounds a little silly but i'm really a begginer with coding.

Thank you

Best regards


 


#5

Do note that you really, really don't ever need to put a File object on the heap; use the stack for that sort of thing.

Also, if you see something that really, really does happen to need the heap, use a ScopedPointer.

Have a look at JUCE's [url=http://www.juce.com/documentation/coding-standards]coding standard[/url] to help you out with programming in C++. It seems a bit counter-intuitive to approach programming this way, but it's rather detailed, and can prove helpful in simplifying and thinking of clearing up code in a different way.


#6
void playMidiFile()
{
    FileInputStream stream (File ("C:\\Users\\goldiman\\Desktop\\Midi0110\\ReadMidi\\music.mid"));
        
    if (! stream.openedOk())
        return;

    MidiFile midiFile;

    if (! midiFile.readFrom (stream))
        return;
 
    const int numTracks = midiFile.getNumTracks();

    if (numTracks <= 0)
        return;
 
    const MidiMessageSequence& sequence = *midiFile.getTrack (0);
 
    const int numEvents = sequence.getNumEvents();

    if (numEvents <= 0)
        return;
  
    ScopedPointer<MidiOutput> midiOutput (MidiOutput::openDevice (MidiOutput::getDefaultDeviceIndex()));

    if (midiOutput == nullptr)
        return;
 
    for (int i = 0; i < numEvents; ++i)
    {
        MidiMessageSequence::MidiEventHolder* eventHolder = sequence.getEventPointer (i);

        if (eventHolder == nullptr)
            continue;

        const MidiMessage& message = eventHolder->message;
 
        if (message.isNoteOnOrOff())
        {
            midiOutput->sendMessageNow (message);
            const int note = message.getNoteNumber();
            const int velocity = message.getVelocity();
            DBG ("Note on/off processed --- Note# " + String (note) + ", Velocity " + String (velocity));
        }
        else
        {
            DBG ("Skipped a message");
        }

        Thread::sleep (1000);
    }
}

Above is a simplified version of what you've linked. Do note that "Sleep()" is not a standard function; you should be in the habit of using juce::Thread::sleep() to be able to conform to various platforms, not just Windows.

Also, you can use juce's multi-platform DBG() macro instead of std::cout and std::endl for outputting to the console. And juce::String handles converting all sorts of data types into String objects.

With that, it was obvious a couple things were leaking memory; your File object that was put on the heap, likewise for your MidiOutput instance. If you "new" something, you must "delete" something. So as to not forget or worry about it, use RAII, a juce::ScopedPointer is good in this case since it will handle that for you.

Edit: Right, I forgot to mention that you initially wrote "OuputMidi->MidiOutput->sendMessageNow". Not sure what the hell that was about, but seemed like a typo.


Have a look and see what I cleared up.


#7

First, thank you ! Your modications works like a charm !

I have understood your advices and will do better next time.

Thank you again for your constructive  advices, have a nice day!

Best regards

Goldiman