bool WriteMidiFile(const MIDIMultiTrack &src, const char *file, bool use_running_status)
{
    MIDIFileWriteStreamFileName out_stream( file );
    if ( !out_stream.IsValid() )
        return false;

    MIDIFileWriteMultiTrack writer( &src, &out_stream );

    // write midifile with or without running status usage
    writer.UseRunningStatus( use_running_status );

    int tracks_number = src.GetNumTracksWithEvents();
    return writer.Write( tracks_number );
}
// delete all text events from multitrack object
bool DeleteAllTracksText( MIDIMultiTrack &tracks )
{
    bool text_deleted = false;
    int num_tracks = tracks.GetNumTracksWithEvents();

    for ( int nt = 0; nt < num_tracks; ++nt )
    {
        MIDITrack &trk = *tracks.GetTrack( nt );
        int num_events = trk.GetNumEvents();

        for ( int ne = 0; ne < num_events; ++ne )
        {
            MIDITimedBigMessage *msg = trk.GetEvent( ne );
            // convert any text midi event to NoOp event
            if ( msg->IsTextEvent() )
            {
                trk.MakeEventNoOp( ne );
                text_deleted = true;
            }
        }
    }

    return text_deleted;
}
int main ( int argc, char **argv )
{
    int retcode = -1;

    if ( argc <= 2 )
    {
        args_err();
        return retcode;
    }

    const char *infile = argv[1];
    const char *outfile = argv[2];

    int mode = 0;
    if ( argc > 3 )
        mode = abs ( atol( argv[3] ) );

    MIDIMultiTrack tracks, tracks2;

    if ( !ReadMidiFile( infile, tracks ) )
    {
        cerr << "\nError reading file " << infile << endl;
        return retcode;
    }

    if ( mode%2 == 1 ) // need to reduce outfile size
    {
        // delete all text events from all tracks
        if ( DeleteAllTracksText( tracks ) )
        {
          cout << "\nAll midi text events deleted." << endl;
        }

        if ( tracks.GetNumTracksWithEvents() == 1 )
        {
            // remake multitrack object and optimize new tracks content:
            // move all channal events to tracks 1-16, and all other types of events to track 0
            // and reduce midifile size because of increase number of events with running status
            tracks.AssignEventsToTracks( 0 );
            cout << "\nAll midi channal events moved to tracks 1-16." << endl;
        }
    }

    MIDIMultiTrack *outtracks = &tracks;
    if ( mode >= 2 ) // need to delete start pause
    {
        CompressStartPause( tracks, tracks2 );
        outtracks = &tracks2;
        cout << "\nStart pause deleted (decreased)." << endl;
    }

    if ( WriteMidiFile( *outtracks, outfile) )
    {
        int num_tracks = outtracks->GetNumTracksWithEvents();
        cout << "\nAll OK. Number of tracks with events " << num_tracks << endl;
        retcode = 0;
    }
    else
    {
        cerr << "\nError writing file " << outfile << endl;
    }

    return retcode;
}