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??? 可能指示事件的增量时间,但实际上并不是程序更改事件的一部分。不小心修改了一个 delta 时间会改变所有后续事件的关闭时间,如果它是多轨组合的一部分,这听起来会很糟糕。

至于解决方案,我怀疑是否有一个正则表达式可以检测程序更改事件,而不会同时获取增量时间。我修改 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

这对我有用。不知道什么是错的prevoiusly。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 回答