I would like to have a crescendo (rise in volume) through each note using MIDIUtil. Is there a way to do this? I have the simple MIDIUtil demo code and have modified it so each note lasts 5 beats. I have a basic code like this:
from midiutil.MidiFile import *
degrees = [60, 62, 64, 65, 67, 69, 71, 72]
track = 0
channel = 0
time = 0
duration = 5
tempo = 120
volume = 100
MyMIDI = MIDIFile(1)
MyMIDI.addTempo(track,time, tempo)
for pitch in degrees:
MyMIDI.addNote(track, channel, pitch, time, duration, volume)
time = time + 1
with open("major-scale.mid", "wb") as output_file:
MyMIDI.writeFile(output_file)
You can increase the velocity of each note by increasing the value of the volume
parameter. Something like this:
from midiutil.MidiFile import *
degrees = [60, 62, 64, 65, 67, 69, 71, 72]
track = 0
channel = 0
time = 0
duration = 4
tempo = 120
volume = 15
MyMIDI = MIDIFile(1)
MyMIDI.addTempo(track,time, tempo)
for pitch in degrees:
MyMIDI.addNote(track, channel, pitch, time, duration, volume)
time = time + 4
volume = volume + 15
with open("major-scale.mid", "wb") as output_file:
MyMIDI.writeFile(output_file)
This will make each note have a higher velocity than the previous, but the volume will not increase while the note is sounding. (Also note that I changed duration to 4 and increase time
by 4 for each note. This makes each note a whole note with no overlap. With your example, each note is five beats long and starts one beat after the previous note, causing a lot of overlap.)
Calling this parameter volume
is a mistake on the part of the implementor of MIDIUtil. It should be called "velocity". Volume is a completely different thing in MIDI. Volume is continuous controller #7 and affects the volume of everything sounding on that MIDI channel. Velocity is the strength at which an individual note is struck. There's not even any guarantee that velocity will affect the volume of a note. It's common, but a sound can be programmed so that velocity affects any aspect of the sound, not just loudness.
Here's a similar program that uses the volume continuous controller to increase the volume while each note (all with velocity 80) is sounding. (It's not elegant code. I'm not much of a Python programmer and it's past my bedtime.)
from midiutil.MidiFile import *
degrees = [60, 62, 64, 65, 67, 69, 71, 72]
track = 0
channel = 0
time = 0
duration = 4
tempo = 120
volume = 8
MyMIDI = MIDIFile(1)
MyMIDI.addTempo(track, time, tempo)
for pitch in degrees:
MyMIDI.addNote(track, channel, pitch, time, duration, 80)
for i in range (0, 15):
MyMIDI.addControllerEvent(track, channel, time + i * 4 / 15, 7, volume)
volume = volume + 1
time = time + 4
with open("major-scale-with-volume.mid", "wb") as output_file:
MyMIDI.writeFile(output_file)
Here's what the first few measures look like: