通过Python在Midi中的特定时间编写注释

2024-06-24 12:23:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想将一系列音符(由时间、持续时间、音高定义)转换为音频文件。为此,我认为首先创建一个midi,然后将其编译为wav是一种方法

我对音频处理和MIDI文件非常陌生,所以即使我读了几本教程,也可能没有抓住要点

编辑:我发现了问题,请参阅下面的解决方案

有什么问题

通过python的MIDIUtil在特定的时间和特定的持续时间编写注释并不像预期的那样有效。事实上,在将音符时间转换为MIDI的四分之一音符时间度量值时,音符放置的时间(以秒为单位)在很大程度上取决于曲目的bpm,尽管我认为我考虑了bpm

我尝试过的

我正在使用给定的bpm创建MIDI曲目。 然后我将通过 t_{quarter} = t_{seconds} * bpm/60

示例

我用下面的代码写了两个注释,最后一个在t=5秒,持续时间为1s;i、 我期待一个持续6秒的midi文件。但当bpm=600时,文件长度为14秒。当bpm=100时,几乎是预期的6秒

这是我的密码


from midiutil import MIDIFile

def convert_seconds_to_quarter(time_in_sec, bpm):
    quarter_per_second = (bpm/60)
    time_in_quarter = time_in_sec * quarter_per_second
    return time_in_quarter

def write_test_midi():
    bpm = 600

    MyMIDI = MIDIFile(1)
    MyMIDI.addTrackName(track=0, time=0, trackName="Sample Track")
    MyMIDI.addTempo(track=0, time=0, tempo=bpm)

    MyMIDI.addNote(track=0, channel=0, pitch=60,
                   time=convert_seconds_to_quarter(1, bpm),
                   duration=convert_seconds_to_quarter(1, bpm), volume=100)
    MyMIDI.addNote(track=0, channel=0, pitch=60,
                   time=convert_seconds_to_quarter(5, bpm),
                   duration=convert_seconds_to_quarter(1, bpm), volume=100)

    with open("/tmp/output.mid", 'wb') as binfile:
        MyMIDI.writeFile(binfile)

附加信息

带有bpm=100的文件的十六进制内容:

ADDRESS        00 01 02 03   04 05 06 07   08 09 0a 0b   0c 0d 0e 0f       ASCII
00000010       4d 54 68 64   00 00 00 06   00 01 00 02   03 c0 4d 54       MThd..........MT
00000020       72 6b 00 00   00 0b 00 ff   51 03 09 27   c0 00 ff 2f       rk......Q..'.../
00000030       00 4d 54 72   6b 00 00 00   28 00 ff 03   0c 53 61 6d       .MTrk...(....Sam
00000040       70 6c 65 20   54 72 61 63   6b 8c 40 90   3c 64 8c 40       ple.Track.@.<d.@
00000050       80 3c 64 a5   40 90 3c 64   8c 40 80 3c   64 00 ff 2f       .<d.@.<d.@.<d../
00000060       00 00 00 00                                                 .

带有bpm=600的文件的内容:

ADDRESS        00 01 02 03   04 05 06 07   08 09 0a 0b   0c 0d 0e 0f       ASCII
00000010       4d 54 68 64   00 00 00 06   00 01 00 02   03 c0 4d 54       MThd..........MT
00000020       72 6b 00 00   00 0b 00 ff   51 03 01 86   a0 00 ff 2f       rk......Q....../
00000030       00 4d 54 72   6b 00 00 00   29 00 ff 03   0c 53 61 6d       .MTrk...)....Sam
00000040       70 6c 65 20   54 72 61 63   6b cb 00 90   3c 64 cb 00       ple.Track...<d..
00000050       80 3c 64 81   e1 00 90 3c   64 cb 00 80   3c 64 00 ff       .<d....<d...<d..
00000060       2f 00 00 00                                                 /.

解决方案

我发布的代码、转换函数和文件都是正确的。问题是我以前听midi的VLC播放器


Tags: 文件toinconverttime时间trackmidi
1条回答
网友
1楼 · 发布于 2024-06-24 12:23:52

第一个文件:

delta     message            absolute time
time                         ticks  seconds

      ... 03 c0 ...                        960 ticks per quarter note
      ... ff 51 03 09 27 c0      0   0     tempo: 600000 microseconds per quarter note
8c 40     90 3c 64            1600   1     note on
8c 40     80 3c 64            3200   2     note off
a5 40     90 3c 64            8000   5     note on
8c 40     80 3c 64            9600   6     note off
00        ff 2f 00            9600   6     end of track

第二个文件:

      ... 03 c0 ...                        960 ticks per quarter note
      ... ff 51 03 01 86 a0      0   0     tempo: 100000 microseconds per quarter note
cb 00     90 3c 64            9600   1     note on
cb 00     80 3c 64           19200   2     note off
81 e1 00  90 3c 64           48000   5     note on
cb 00     80 3c 64           57600   6     note off
00        ff 2f 00           57600   6     end of track

两个文件的长度都是6秒。您的代码和文件是正确的

问题在于您使用什么工具来处理文件

相关问题 更多 >