0

Sibelius (v.4?..) によって作成された、「珍しい」楽器を含む MIDI ファイルがいくつかあります。メロディーが聞こえない。インストゥルメントを 0 に「リセット」する必要があると判断しました (アコースティック グランド ピアノだと思います)。

そこで、python-midimingusの両方を使用して Python プログラムを作成しました。これらのプログラムは MIDI 楽器を変更できましたが、どちらもリズムを劇的に変更しました。

Rosegardenはこの仕事を非常にうまく行っていますが、バッチで使用することはできません。

次に、MIDI フォーマット情報 (たとえばherehere ) を読み取った後、単純な Python スクリプト (以下を参照) を作成しました。このスクリプトは、一部の文字列を別の文字列に単純に置き換えます --- 0xC0[byte] を 0xC000 に置き換えます。

これで、これらの MIDI ファイルのサウンドは正常になり、すべてを聞くことができます。

それで、私の質問は---これを行うのは(何らかの意味で)「安全」ですか?どうすればより良い楽器に交換できますか? MIDI ファイルの 0xCx コマンドをより適切に「検出」するにはどうすればよいですか?

ありがとうございました!

#!/usr/bin/env python
#

import sys
import re

patt = re.compile('(\xC0|\xC1|\xC2|\xC3|\xC4|\xC5|\xC6|\xC7).')

try:
    filein = sys.argv[1]
except IndexError:
    print "Specify input file as an argument."
    sys.exit(1)

try:
    fileout = sys.argv[2]
except IndexError:
    fileout = '%s-out2.mid' % filein.replace('.mid', '')

filein_data = open(filein, 'rb').read()

open(fileout, 'wb').write(patt.sub('\1\x00',filein_data))
4

2 に答える 2

2

すべての0xCを単純に交換するのは安全ではありません??? 0xC?00のバイト、主に0xC ??? イベントのデルタ時間を示している可能性があり、実際にはプログラム変更イベントの一部ではない可能性があります。誤ってデルタタイムを変更すると、後続のすべてのイベントがオフタイムにシフトします。これは、マルチトラックコンポジションの一部である場合はかなりひどい音になります。

解決策としては、デルタ時間を取得せずにプログラム変更イベントを検出できる正規表現があるとは思えません。MIDIの変更に関する私の唯一の経験は、私が作成したJavaライブラリを使用したものであり、次のコードを使用してタスクを実行できます。

MidiFile input = new MidiFile(INPUT_FILE);

for(MidiTrack T : input.getTracks()) {
    Iterator<MidiEvent> it = T.getEvents().iterator();
    while(it.hasNext()) {
        MidiEvent E = it.next();
        if(E instanceof ProgramChange) {
            E.setProgramNumber(0);
        }
    }
}

input.writeToFile(OUTPUT_FILE);

私はそれをフリーハンドで書いたので、例外キャッチを使用する必要があるかもしれませんが、それはかなり簡単です。

お役に立てば幸いです。

于 2012-04-09T17:13:02.743 に答える
0

これは私にとってはうまくいきます。以前は何が悪いのかわかりません。python-midiいいです。

#!/usr/bin/env python
#
# Sets all instruments' numbers to zero.
#

import sys
import midi

try:
    infile = sys.argv[1]
except IndexError:
    print "Specify input file as an argument, please."
    sys.exit(1)

try:
    outfile = sys.argv[2]
except IndexError:
    outfile = '%s-out.mid' % infile.replace('.mid', '')

midi_data = midi.read_midifile(infile)

for track_idx in range(len(midi_data)):
    for event in midi_data[track_idx]:
        if isinstance(event, midi.ProgramChangeEvent):
            event.data = map(lambda x: 0, event.data)

midi.write_midifile(outfile, midi_data)
于 2012-04-12T08:33:15.983 に答える