[1]:
from automuse.midi import Player, play, change_instrument, voice, percuss
from automuse.midi import Instrument, Percussion
from time import sleep
import automuse.chord as chord
import automuse.modes as modes
Playing Notes
AutoMuse comes with a parallelised MIDI player, implemented in omusic.midi. The module exports very few components:
change_instrumentchanges the current instrument to one ofomusic.midi.Instrument. Default is the Acoustic Grand Piano..Playercreates a player. This player controls a MIDI port and acts as a context manager..playplays notes with a player..portreturns the default MIDI port.
Playing Notes
Let’s begin with a quick example: play the \(\text{C}_5\). To make the note last, set its duration to 3 seconds.
[2]:
with Player() as player:
play(player, "C5", duration=2)
closing
Moving on to another example, let’s try the \(\text{I}\rightarrow\text{IV}\rightarrow\text{V}\rightarrow\text{I}\) progression:
[3]:
with Player() as player:
for _ in range(1):
play(player, notes=chord.chord("C5", modes.MAJOR, order=0))
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=3))
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=4))
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=0))
sleep(0.2)
closing
The play function has several parameters that “humanise” the output. These are:
arpeggio: Order of notes to play, can beNone(no change),ascending, ordescending.spacing: Melodic intervals between notes, if a list is given innotes.touch: Variation in note velocity (touch pressure).
The exact values, same as many things in music, are up to your creative choices. As a quick example, let’s hear what different combinations sound like:
[4]:
plan_1 = {"arpeggio": "ascending",
"spacing": 0,
"touch": 0,
"duration": 1}
plan_2 = {"arpeggio": "descending",
"spacing": (0, 2),
"touch": (-30, 30),
"duration": 1}
with Player() as player:
for _ in range(1):
play(player, notes=chord.chord("C5", modes.MAJOR, order=0), **plan_1)
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=3), **plan_1)
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=4), **plan_2)
sleep(0.2)
play(player, notes=chord.chord("C5", modes.MAJOR, order=0), **plan_2)
sleep(0.2)
closing
Simple Voicing
The voice function plays a collection of notes without needing a Player. It can accept two additional arguments:
schememoves notes up and down octaves.play_argscontains arguments to pass to the underlyingplayer, which does all the heavy lifting.
[5]:
voice(["C5", "D5", "E5"],
scheme=[-1, 1, 2],
play_args={"spacing": (0.1, 0.2)})
closing
Change Instrument
The change_instrument function sends a program_change message; this message the instrument of a channel. Instrument is an Enum that contains all standard instruments.
[6]:
with Player() as player:
change_instrument(player, 0, Instrument.Banjo)
play(player, notes=chord.chord("C5", modes.MAJOR))
closing
Percussion
The MIDI standard reserves channel 10 for percussion, where the note specifies a percussion instrument instead of a actual pitch. The percuss function sends notes to this channel. See Percussion for available instruments.
[9]:
with Player() as player:
percuss(player, notes=Percussion.AcousticBassDrum)
closing