python - 我如何将 pitch_bend 更改添加到函数piano_roll_to_pretty_midi 以制作音乐?
问题描述
我想使用函数piano_roll_to_pretty_midi 转换属性音乐,但我不知道如何将pitch_bend 更改添加到此函数,这是鳕鱼piano_roll:
def piano_roll_to_pretty_midi(piano_roll, fs=100, program=0):
'''Convert a Piano Roll array into a PrettyMidi object
with a single instrument.
Parameters
----------
piano_roll : np.ndarray, shape=(128,frames), dtype=int
Piano roll of one instrument
fs : int
Sampling frequency of the columns, i.e. each column is spaced apart
by ``1./fs`` seconds.
program : int
The program number of the instrument.
Returns
-------
midi_object : pretty_midi.PrettyMIDI
A pretty_midi.PrettyMIDI class instance describing
the piano roll.
'''
notes, frames = piano_roll.shape
pm = pretty_midi.PrettyMIDI()
instrument = pretty_midi.Instrument(program=program)
# pad 1 column of zeros so we can acknowledge inital and ending events
piano_roll = np.pad(piano_roll, [(0, 0), (1, 1)], 'constant')
# use changes in velocities to find note on / note off events
velocity_changes = np.nonzero(np.diff(piano_roll).T)
# keep track on velocities and note on times
prev_velocities = np.zeros(notes, dtype=int)
note_on_time = np.zeros(notes)
for time, note in zip(*velocity_changes):
# use time + 1 because of padding above
velocity = piano_roll[note, time + 1]
time = time / fs
if velocity > 0:
if prev_velocities[note] == 0:
note_on_time[note] = time
prev_velocities[note] = velocity
else:
pm_note = pretty_midi.Note(
velocity=prev_velocities[note],
pitch=note,
start=note_on_time[note],
end=time)
instrument.notes.append(pm_note)
prev_velocities[note] = 0
pm.instruments.append(instrument)
return pm
解决方案
您将PitchBend
对象添加到仪器的pitch_bends
列表中。这是一个 MWE,它从钢琴卷中添加音符并弯曲它们:
from pretty_midi import *
from numpy import *
roll = [[1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1]]
roll = array(roll).T
notes, frames = roll.shape
pm = PrettyMIDI()
instr = Instrument(program = 80)
roll = pad(roll, [(0, 0), (1, 1)], 'constant')
velocity_changes = nonzero(np.diff(roll).T)
prev_velocities = zeros(notes, dtype=int)
note_on_time = zeros(notes)
for time, note in zip(*velocity_changes):
velocity = roll[note, time + 1]
if velocity > 0:
if prev_velocities[note] == 0:
note_on_time[note] = time
prev_velocities[note] = velocity
else:
start_time = note_on_time[note]
pm_note = Note(
velocity = 120,
pitch = note + 40,
start = start_time,
end=time)
instr.notes.append(pm_note)
for i in range(20):
time = start_time + i / 20
bend = PitchBend(400 * i, time)
instr.pitch_bends.append(bend)
prev_velocities[note] = 0
pm.instruments.append(instr)
pm.write('test.mid')
推荐阅读
- td-engine - 填TDengine数据库不能用join?
- sql - 使用 sql 为具有最新可用信息的日期范围创建附加行
- api - 如何从 billsby 禁用 3d 安全
- vue.js - 如何在 Vue 和 Pug 中从字符串日期类型转换日期?
- kentico - 页面类型字段可见性条件不起作用
- sql - sqlite3中的“with”和“with recursive”有什么区别?
- reactjs - Highchart 的极坐标图:在相交区域系列上应用渐变颜色
- python - 在geojson边界外遮罩叶图
- html - 如何解决这个关于 div 元素的验证错误?
- java - 线程“主”java.util.regex.PatternSyntaxException 中的异常:在索引 0 附近悬空元字符 '*' *