Install and connect
By the end of this chapter, Subsequence is installed on your computer, it has written a note to a MIDI file, and you have heard that note on an instrument of your own.
Subsequence makes MIDI and nothing else. The sound comes from whatever it plays: a hardware synth or drum machine, or a software instrument in a DAW.
What you need
- A computer with Python on it. Python is the language Subsequence is written in, and the language you write music for it in.
- An instrument that takes MIDI, and a way to reach it. Both kinds are covered below.
- A terminal, the window where you type commands: Terminal on macOS, Windows Terminal or PowerShell on Windows, and whichever your Linux desktop gives you.
Python
Open a terminal and ask Python for its version:
Not checked: the build does not run this.
python3 --version
On Windows, type python --version instead. If it prints a version number, Python is installed. If it says the command was not found, install Python first. Python's own documentation says how for each system: Windows, macOS, and Linux and other Unix systems.
A virtual environment
A virtual environment is a folder that holds one project's Python packages, so what you install for Subsequence never disturbs anything else on your computer. Make a folder for your music, move into it in the terminal, and create one there:
Not checked: the build does not run this.
python3 -m venv .venv
source .venv/bin/activate
On Windows, the two lines are python -m venv .venv and .venv\Scripts\activate. The second line switches the environment on, and it lasts until you close the terminal, so run it again each time you open a new one. While it is on, python and pip mean the environment's own, on every system. Python's tutorial explains virtual environments in full.
Subsequence
With the environment switched on, install Subsequence:
Not checked: the build does not run this.
pip install "subsequence @ git+https://github.com/simonholliday/subsequence@a5e0a09447dc8c49592753412f69abd2606ef380"
That line installs the version of Subsequence this guide is checked against. If your Python is too old for it, pip says so and installs nothing.
A first note, in a file
Create a file called first_note.py in your music folder, in any text editor, and put this in it:
import subsequence
composition = subsequence.Composition(bpm=120)
@composition.pattern(channel=1, beats=4)
def first_note (p):
p.note(60, beat=0, velocity=100, duration=1)
composition.render(bars=1, filename="first-note.mid")
Then run it from the terminal:
Not checked: the build does not run this.
python first_note.py
It writes first-note.mid beside the script. Line by line, this is what it says:
import subsequencemakes Subsequence available to the script.composition = subsequence.Composition(bpm=120)makes aComposition, the piece you are writing, at 120 BPM, and calls itcomposition.@composition.pattern(channel=1, beats=4)is a decorator: a line starting with@that hands the function below it to something else. Here it makes the function a pattern of the composition, a part four beats long that plays on MIDI channel 1.def first_note (p):starts the function, namedfirst_note. Subsequence calls it each time the pattern comes round, and gives itp, which places notes. The indented line under it is the function's body.p.note(60, beat=0, velocity=100, duration=1)places MIDI note 60, middle C, on the first beat, at velocity 100, one beat long.p.notecounts beats from 0, sobeat=0is the first beat of the pattern, while MIDI channels are counted from 1, as instruments label them.composition.render(bars=1, filename="first-note.mid")plays the composition for one bar, as fast as your computer can rather than in time, and writes what it played to the file.renderneeds no instrument.
Under an example, a few lines like these say what it made, bar and beat first:
tempo 120 bpm from 1 1.000
MIDI channel 1
1 1.000 note C4 (60) velocity 100 length 1.000
Your file holds the same: at 120 BPM, one note on MIDI channel 1, in bar 1 on beat 1, named C4 and numbered 60, at velocity 100, lasting one beat. Some instruments and DAWs name MIDI note 60 C3, and it is the same note. Open first-note.mid in a DAW to see it.
Hearing it
play sends the notes to an instrument as they happen, in time. Change the last line of first_note.py to call it instead of render:
Not checked: the build does not run this.
composition.play()
Run the script again. Subsequence looks for a MIDI port to play through. If there is one, it uses it. If there are several, it lists them and asks which you mean. If there are none, it says it found no MIDI output devices. Then it plays middle C at the start of every bar until you press Ctrl+C.
Set your instrument to listen on MIDI channel 1, or on every MIDI channel.
A hardware instrument
A synth or drum machine with a USB port appears as a MIDI port of its own once it is connected and switched on. One with only round five-pin MIDI sockets connects through a USB MIDI interface, and the interface is the port: plug its MIDI out into the instrument's MIDI in.
A software instrument
A software instrument or a DAW is another program on the same computer, so the notes travel through a virtual MIDI port that both programs can see. Subsequence plays into it, and the DAW takes its MIDI from it.
- macOS: turn on the IAC Driver in Audio MIDI Setup and give it a bus, as Apple describes in transferring MIDI information between apps.
- Windows: create a loopback MIDI port. On Windows 11 with Windows MIDI Services, its tools create one, and on earlier versions of Windows, loopMIDI does.
- Linux: a software instrument or DAW that takes MIDI from other programs through ALSA appears as a MIDI port of its own.
Then, in the DAW, give a track that virtual port as its MIDI input, put an instrument on the track, and arm or monitor it so it plays what arrives.
Naming the port
Rather than choosing from a list every time, tell Subsequence which port to use when you make the composition:
Not checked: the build does not run this.
composition = subsequence.Composition(bpm=120, output_device="*IAC*")
The name is matched as a pattern, so you do not have to type all of it. * stands for any run of characters, matching ignores capital letters, and a name with no * in it matches any port whose name contains it. Subsequence's README says more on naming your MIDI device, including how to keep a name working on Linux, where part of it changes between restarts.
On Linux, if opening the port fails with Permission denied, add yourself to the audio group, then log out and back in:
Not checked: the build does not run this.
sudo usermod -a -G audio $USER