void ofxThreadedMidiPlayer::init(){
    if(!bIsInited){
        isReady = false;
        string filePath = ofToDataPath(midiFileName, true);
        
        MIDIFileReadStreamFile rs ( filePath.c_str() );
        
        if ( !rs.IsValid() )
        {
            ofLogError( "ERROR OPENING FILE AT: ",  filePath);
            
        }
        
        tracks = new MIDIMultiTrack();
        MIDIFileReadMultiTrack track_loader ( tracks );
        MIDIFileRead reader ( &rs, &track_loader );
        
        int numMidiTracks = reader.ReadNumTracks();
        int midiFormat = reader.GetFormat();
        
        tracks->ClearAndResize( numMidiTracks );
        cout << "numMidiTracks: " << numMidiTracks << endl;
        cout << "midiFormat: " << midiFormat << endl;
        
        if ( reader.Parse() ){
            cout << "reader parsed!: " << endl;
        }
        
        
        //MIDISequencer seq( &tracks );
        sequencer = new MIDISequencer ( tracks );//&seq;
        musicDurationInSeconds = sequencer->GetMusicDurationInSeconds();
        
        ofLogVerbose( "musicDurationInSeconds is ", ofToString(musicDurationInSeconds));
        
        midiout=new RtMidiOut();
        if (midiout->getPortCount()){
            midiout->openPort(midiPort);
            ofLogVerbose("Using Port name: " ,   ofToString(midiout->getPortName(0)) );
            //std::cout << "Using Port name: \"" << midiout->getPortName(0)<< "\"" << std::endl;
        }
        
        currentTime = 0.0;
        nextEventTime = 0.0;
        if (!sequencer->GoToTimeMs ( currentTime )){
            ofLogError("Couldn't go to time in sequence: " ,   ofToString(currentTime) );
        }
        if ( !sequencer->GetNextEventTimeMs ( &nextEventTime ) ){
            ofLogVerbose("No next events for sequence", ofToString(nextEventTime));
        }
        max_time = (musicDurationInSeconds *1000.);
        bIsInited = true;
    }
}