Usage

Installation

To use the package, clone the repository

git clone https://github.com/amerotz/loeric

Then create a virtual environment with

python -m venv <environment name>

Activate the environment you created with

source <environment name>/bin/activate

Then install the required packages with

pip install -r requirements.txt

Performing a tune

To perform a tune, invoke:

python loeric <tune MIDI file> [command line arguments]

where the possible arguments are

  • source: the midi file to play;

  • -h, --help: show the help message and exit;

  • --list_ports: list available input and output MIDI ports and exit;

  • -c CONTROL, --control CONTROL: the MIDI control signal number to use as human control;

  • -hi HUMAN_IMPACT, --human_impact HUMAN_IMPACT: the percentage of human impact over the performance (0: only generated, 1:only human);

  • -i INPUT, --input INPUT: the input MIDI port for the control signal;

  • -o OUTPUT, --output OUTPUT: the output MIDI port for the performance;

  • -mc MIDI_CHANNEL, --midi-channel MIDI_CHANNEL: the output MIDI channel for the performance;

  • -t TRANSPOSE, --transpose TRANSPOSE: the number of semitones to transpose the tune of;

  • -d, --diatonic: whether or not error generation should be quantized to the tune’s mode;

  • -r REPEAT, --repeat REPEAT: how many times the tune should be repeated;

  • -bpm BPM: the tempo of the performance. If None, defaults to the original file’s tempo;

  • --save: whether or not to export the performance. Playback will be disabled;

  • --seed: the random seed for the performance;

  • --no-prompt: whether or not to wait for user input before starting;

  • --config CONFIG: the path to a configuration file. Every option included in the configuration file will override command line arguments.

For example, to play the tune butterfly.mid on output port 0 on MIDI channel 2, while reading control input on control signal 42 on input port 0, with a human impact of 0.5, transposing by 10 semitones, repeating 3 times, at 200 BPM:

python loeric butterfly.mid -o 0 -mc 2 -c 42 -i 0 -hi 0.5 -t 10 -r 3 -bpm 200

All of these parameters and many internal ones can be changed with a configuration file:

python loeric butterfly.mid --config conf.json

The configuration file has precedence over command line arguments. That means that if there is a field corresponding to performance BPM in the configuration file, the bpm flag in the command invocation will be ignored.

Some parameters are not specified in the configuration file and need to be given always as arguments; these are:

  • the input port;

  • the output port;

  • repeats;

  • saving;

  • prompting.

To know which ports are available for input and output, invoke:

python loeric --list_ports

Alternatively, if the input port or the output port is not specified, the program will automatically list the available ones and ask the user which one to use.

Live Interaction

The system allows for live human interaction by reading a MIDI control signal with a given event number (0 to 127) on a specified input port. This can be a MIDI controller’s output (a knob on a keyboard, an expression pedal, etc…) or it can be generated by another script.

The flag -c or --control allows to specify the event number to monitor. If set up correctly, the program should print the value of the control signal as a number between 0 and 1 at each update.

Available Control Scripts

There are a few scripts that compute an intensity value based on some user activity and output it as a control signal on a given port.

MIDI Velocity Listener

This script continuously reads MIDI input on the given port and sends a control signal with a given event number on a given port corresponding to “intensity” computed from the MIDI velocity of played notes.

The intensity of each note is simply its velocity mapped from [0, 127] to the interval [0, 1]. The new intensity value is then computed as:

value = old_value * (1 - responsiveness) + note_value - responsiveness

where responsiveness is the weight of the newly computed note intensity. A value of 0 newver updates the intensity, a value of 1 always returns the newest value. Note off events (and thus also note on events with velocity 0) are excluded from this computation.

Invoke using:

python midi_velocity_listener.py [command line arguments]

where possible arguments are:

  • -h, --help: show this help message and exit

  • --list_ports: list available input and output MIDI ports and exit.

  • -i INPUT, --input INPUT: the input MIDI port.

  • -o OUTPUT, --output OUTPUT: the output MIDI port.

  • -c CONTROL, --control CONTROL: the control channel on which intensity is sent.

  • -r RESPONSIVE, --responsive RESPONSIVE: the weight of incoming values when computing intensity, in range 0 to 1.

When using loeric, use the --list_ports option to identify the port you just opened and use it as input port. Make sure to monitor the same event number with the --c option.

Other Listeners

Coming soon.