Here is the fixed version. I found a Perl script at http://sourceforge.net/projects/midi2fluxama/files/ called midi120.pl that uses this Perl module, and I have merged the logic into my script.

#!/usr/bin/perl -w
   use Tk;
   use Tk::Optionmenu;
   use Tk::FBox;
   use Tk::MsgBox;
   use MIDI;
   use strict;

   my $mw = MainWindow->new;

   $mw->Label(-text => 'Convert to type 0')->pack;
   $mw->Button(
       -text    => 'Convert',
       -command => sub {doConvert() }
   )->pack;
   $mw->Button(
       -text    => 'Quit',
       -command => sub { exit }
   )->pack;
   MainLoop;
sub doConvert {
   my $ffile = $mw->FBox(
       -type => 'open',
       -filetypes => [[ 'midi files', '.mid' ]],
       -title => 'Select MIDI file to convert...'
   )->Show;
   if ($ffile ne "") {
       my $tfile = $mw->FBox(
           -type => 'save',
           -filetypes => [[ 'midi files', '.mid' ]],
           -title => 'Save converted file as...'
       )->Show;
       if ($tfile ne "") {
           my $opus = MIDI::Opus->new({ 'from_file' => $ffile });
           my $nt = MIDI::Track->new;
           if ($opus->format!=1) {
$mw->MsgBox(-title => "Cancelling", -detail => "$ffile is already in format 0", -type => 'ok')->Show;
           } else {
$mw->MsgBox(-title => "converting...", -detail => "converting to type: 0", -type => 'ok')->Show;
             my @events;
             my @event_counter;
             my @dtime;
             my $i;
             for ($i=0;$i<scalar($opus->tracks);$i++) {
$events[$i]=$event_counter[$i]=scalar(($opus->tracks)[$i]->events);
             }
             while(1) {
               for ($i=0;$i<scalar($opus->tracks);$i++) {
                 if ($event_counter[$i]>0) {
$dtime[$i]=(($opus->tracks)[$i]->events)[scalar(@events)-$event_counter[$i]][1];
                 } else {
                   $dtime[$i]=undef;
                 }
               }
               my $lowest_dtime = undef;
               my $use_track=undef;
               for ($i=0;$i<scalar($opus->tracks);$i++) {
                 next if(!defined($dtime[$i]));
                 if($dtime[$i]==0) {
                   $use_track=$i;
                   last;
                 } else {
                   if (!defined($lowest_dtime)||$dtime[$i]<$lowest_dtime) {
                     $use_track=$i;
                     $lowest_dtime=$dtime[$i];
                   }
                 }
               }
               if (!defined($use_track)) {
                 last;
               }
               for ($i=0;$i<scalar($opus->tracks);$i++) {
                 next if(!defined($dtime[$i]));
                 if($event_counter[$i]>0 && $i!=$use_track) {
(($opus->tracks)[$i]->events)[scalar(@events)-$event_counter[$i]][1]-=$dtime[$use_track];
                 }
               }
my $ev=(($opus->tracks)[$use_track]->events)[scalar(@events)-$event_counter[$use_track]];
               $nt->new_event(@$ev);
               $event_counter[$use_track]--;
             }
           }
           my $newsng = MIDI::Opus->new({
                'format'=>0,
                'ticks'=>$opus->ticks,
                'tracks'=>[$nt]
           });
           #$opus->format($lbsel);
           $newsng->write_to_file($tfile);
       }
   }
}


Darcy Kahle wrote:
This apparently will not work, and I will have to re-work it. This Perl module does not change the midi format, just a field specifying the type. I put a $opus->dump(); after reading the file and saw what was happening. In reality, Midi 1 has the tempo changes, etc on track 0 and the notes on track 1. Midi 0 has everything on track 0. That is not what was happening. It kept the two tracks as they were. An example difference from a file I created before my computer went south:

Midi Type 1:
MIDI::Opus->new({
  'format' => 1,
  'ticks'  => 480,
  'tracks' => [   # 2 tracks...

    # Track #0 ...
    MIDI::Track->new({
      'type' => 'MTrk',
      'events' => [  # 7 events.
        ['copyright_text_event', 0, 'Unknown'],
        ['cue_point', 0, 'Created by Rosegarden'],
        ['cue_point', 0, 'http://www.rosegardenmusic.com/'],
        ['set_tempo', 0, 750000],
        ['set_tempo', 5760, 789473],
        ['set_tempo', 86460, 789473],
        ['set_tempo', 900, 789473],
      ]
    }),
# Track #1 ...
    MIDI::Track->new({
      'type' => 'MTrk',
      'events' => [  # 1718 events.
        ['track_name', 0, ''],
        ['patch_change', 0, 0, 1],
        ['control_change', 0, 0, 7, 100],
        ['control_change', 0, 0, 10, 64],
        ['note_on', 960, 0, 81, 100],
        ['note_on', 0, 0, 65, 100],
        ['note_on', 0, 0, 71, 100],
....
Midi Type 0:
MIDI::Opus->new({
  'format' => 0,
  'ticks'  => 480,
  'tracks' => [   # 1 tracks...

    # Track #0 ...
    MIDI::Track->new({
      'type' => 'MTrk',
      'events' => [  # 1724 events.
        ['copyright_text_event', 0, 'Unknown'],
        ['cue_point', 0, 'Created by Rosegarden'],
        ['cue_point', 0, 'http://www.rosegardenmusic.com/'],
        ['set_tempo', 0, 750000],
        ['patch_change', 0, 0, 1],
        ['control_change', 0, 0, 7, 100],
        ['control_change', 0, 0, 10, 64],
        ['note_on', 960, 0, 81, 100],
        ['note_on', 0, 0, 65, 100],
        ['note_on', 0, 0, 71, 100],
        ['note_on', 0, 0, 74, 100],
        ['note_off', 720, 0, 81, 127],
....

Darcy Kahle wrote:
Thanks for this suggestion. I have decided to do this up in Perl instead of C. For those interested in this, here is my initial code. It works, but does not look nice. You will have to install the Tk and MIDI Perl modules.

#!/usr/bin/perl -w
    use Tk;
    use Tk::Optionmenu;
    use Tk::FBox;
    use Tk::MsgBox;
    use MIDI;
    use strict;

    my $mw = MainWindow->new;
    my $lbsel;

    $mw->Label(-text => 'Convert to type:')->pack;
    my $lb = $mw->Optionmenu(
        -options => ['0', '1'],
        -variable => \$lbsel
    )->pack;
    $mw->Button(
        -text    => 'Convert',
        -command => sub {doConvert() }
    )->pack;
    $mw->Button(
        -text    => 'Quit',
        -command => sub { exit }
    )->pack;
    MainLoop;
sub doConvert {
    my $ffile = $mw->FBox(
        -type => 'open',
        -filetypes => [[ 'midi files', '.mid' ]],
        -title => 'Select MIDI file to convert...'
    )->Show;
    if ($ffile ne "") {
        my $tfile = $mw->FBox(
            -type => 'save',
            -filetypes => [[ 'midi files', '.mid' ]],
            -title => 'Save converted file as...'
        )->Show;
        if ($tfile ne "") {
my $opus = MIDI::Opus->new({ 'from_file' => $ffile, 'no_parse' => 1 }); $mw->MsgBox(-title => "converting...", -detail => "converting to type: $lbsel", -type => 'ok')->Show;
            $opus->format($lbsel);
            $opus->write_to_file($tfile);
        }
    }
}


Michael Gerdau wrote:
Thanks for that link.  It appears that it will do the job (and there are
a few other programs there that might be helpful as well), but I would
prefer a native Linux app, if one exists.

If you have at least basic C coding skills you could try these MIDI
utilities (i.e. the corresponding MIDI file library):
http://www.sreal.com/~div/midi-utilities/

A format conversion to MIDI type 0 program would look something like
this (not tested - meant as primitive sketch).


#include "midifile.h"
int main(int argc, char **argv)
{
  MidiFile_t myMidiFile = MidiFile_load("some_path_to_midifile");
  MidiFile_setFileFormat(myMidiFile, 0);
  return MidiFile_save(myMidiFile, "some_other_path_to_midifile");
}


Look at the other utilities and their Makefiles to see how to add
this to the whole set. Or just create a project on your own.

Of course you could add some cmdline parameter handling to parameterize
filenames, format and you could add other stuff like changing resolution
etc.

HTH,
Michael
------------------------------------------------------------------------

------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
------------------------------------------------------------------------

_______________________________________________
Rosegarden-user mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-user
------------------------------------------------------------------------

------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
------------------------------------------------------------------------

_______________________________________________
Rosegarden-user mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-user
------------------------------------------------------------------------

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent caught up. So what steps can you take to put your SQL databases under version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
------------------------------------------------------------------------

_______________________________________________
Rosegarden-user mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-user
------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Rosegarden-user mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-user

Reply via email to