How to read a midi file, change its tool and write it back?

I want to analyze an existing .mid file, change its instrument, for example, from an “acoustic piano” to a “violin”, and save it back or as another .mid file.

From what I saw in the documentation, the instrument is modified using the directive program_changeor patch_change, but I cannot find any library that does this in existing MIDI files. All of them seem to support this only MIDI files created from scratch.

+5
source share
2 answers

Use music21 library (connecting my own system, I hope that everything is in order). If patches are indicated in the parts, follow these steps:

from music21 import converter,instrument # or import *
s = converter.parse('/Users/cuthbert/Desktop/oldfilename.mid")

for el in s.recurse():
    if 'Instrument' in el.classes: # or 'Piano'
        el.activeSite.replace(el, instrument.Violin())

s.write('midi', '/Users/cuthbert/Desktop/newfilename.mid')

or if patch changes are not currently defined:

from music21 import converter,instrument # or import *
s = converter.parse('/Users/cuthbert/Desktop/oldfilename.mid")

for p in s.parts:
    p.insert(0, instrument.Violin())

s.write('midi', '/Users/cuthbert/Desktop/newfilename.mid')
+4
source

The package MIDIwill do this for you, but the exact approach depends on the original contents of the midi file.

A midi file consists of one or more tracks, and each track is a sequence of events on any of sixteen channels, such as Note Off, Note On, Program Change, etc. The last one will change the tool assigned to the channel, and this is what you need to change or add.

- , ( ) , . , , , Program Change .

, Program Change, , . , , .

, Program Change , , . , , , .

, midi , - . MIDI::Opus , ( ) . Program Change ( patch_change) 0 . 40 - - .

, Program Change , - , , .

use strict;
use warnings;

use MIDI;

my $opus = MIDI::Opus->new( { from_file => 'song.mid' } );

my $tracks = $opus->tracks_r;
my $track0_events = $tracks->[0]->events_r;

unshift @$track0_events, ['patch_change', 0, 0, 40];
$opus->write_to_file('newsong.mid');
+5

All Articles