Reference

class tinysoundfont.Sequencer(synth)

A Sequencer schedules MIDI events over time.

Parameters:

synth (Synth) – The synthesizer object to send events to.

add(events)

Add a list of MIDI events to queue for sending.

Parameters:

events (List[Event]) – List of MIDI events

See midi.load() for generating the list of events. See midi_load() for directly loading a MIDI file.

get_time()

Get current playing time of sequencer.

Return type:

float

Returns:

current playing time of sequencer in seconds of absolute time since sequencer started

is_empty()

Return True if there are no more events scheduled.

Return type:

bool

Returns:

True if there are no more events scheduled for this sequencer (song is over)

Songs often end on a final NOTEOFF event that may have a decay time. It is often good to wait some amount of time before looping or scheduling a new song.

midi_load(filename, **kwargs)

Load MIDI file and schedule events.

Parameters:

filename (str) – Filename to load MIDI data from, in Standard MIDI format

Any additional keyword arguments are passed to midi.load(). See midi.load() for documentation on additional keyword arguments.

notes_off()

Send NOTE_OFF for all currently playing notes of the Synth object.

pause(pause_value=True)

Pause or unpause playback.

When playback is paused, time does not advance. No new events will be sent to the Synth object connected to the sequencer. If notes are playing, they will continue to play.

To prevent notes from continuing to play during pause, this method calls notes_off(). You may want to call sound_off() to stop all sound playing immediately if needed.

process(delta)

Advance time and send any events that need to be sent to the Synth.

Parameters:

delta (float) – How many seconds to advance time

Return type:

float

Returns:

How far time was actually advanced (may be smaller than delta)

send(event)

Send a single MIDI event to the synth object now, ignoring any time information.

Parameters:

event (Event) – Single event to send

If the event tries to select a preset that does not exist no error is raised.

set_time(time)

Set current playing time of sequencer.

Parameters:

time (float) – New absolute time in seconds

Note that if previously scheduled events did not have persistent set then the events will no longer exist and will not play again.

Note that MIDI expects events to happen in sequence. So if there is a program change as an event and you set the time to before that event, you might get the new instrument at a position where the previous instrument should have played. In general seeking back to the start of the MIDI events should work. Other random seeking may have unintended effects.

To avoid stuck notes, this method turns off all keypresses using notes_off(). It does not stop all sounds so playing notes may still have time to decay. If needed you can call sounds_off() to stop all playing sounds immediately.

sounds_off()

Turn off all sounds of the Synth object.

exception tinysoundfont.SoundFontException

An exception raised from tinysoundfont

class tinysoundfont.Synth(gain=0, samplerate=44100)

Create new synthesizer object to control sound generation.

Parameters:
  • gain (float) – scale factor for audio output, in relative dB (default 0.0)

  • samplerate (int) – output samplerate in Hz (default 44100)

If you need to mix many simultaneous voices you may need to turn down the gain to avoid clipping. Some SoundFonts also require gain adjustment to avoid being too loud or too quiet.

control_change(chan, controller, control_value)

Change control value for a specific channel.

Parameters:
  • chan (int) – Channel to use (0-15)

  • controller (int) – Controller to update, (0-127), meaning defined by MIDI 1.0 standard

  • control_value (int) – Value to use for update, (0-127)

The interpretation of controller number is from the MIDI 1.0 standard. Supported controller values that have an effect are:

  • 7 VOLUME_MSB

  • 39 VOLUME_LSB

  • 11 EXPRESSION_MSB

  • 43 EXPRESSION_LSB

  • 10 PAN_MSB

  • 42 PAN_LSB

  • 6 DATA_ENTRY_MSB

  • 38 DATA_ENTRY_LSB

  • 0 BANK_SELECT_MSB

  • 32 BANK_SELECT_LSB

  • 100 RPN_LSB

  • 101 RPN_MSB

  • 98 NRPN_LSB

  • 99 NRPN_MSB

  • 120 ALL_SOUND_OFF

  • 123 ALL_NOTES_OFF

  • 121 ALL_CTRL_OFF

The supported Registered Parameter Names (RPN) are:

  • 0 - Pitch bend amount (measured in semitones MSB and cents LSB)

  • 1 - Fine tuning (measured in fractions of one semitone up/down using MSB and LSB)

  • 2 - Coarse tuning (measured in integral semitones up/down using MSB)

Note

To change Registered Parameters Name (RPN) values do the following.

First choose a supported RPN using Controller RPN_LSB (100). Controller RPN_MSB (101) should always be kept at 0. Next put the MSB value in Controller DATA_ENTRY_MSB (6). If needed, also put a LSB value in Controller DATA_ENTRY_LSB.

generate(samples, buffer=None)

Generate fixed number of output samples.

Parameters:
  • samples (int) – Number of samples to generate

  • buffer (Optional[memoryview]) – Existing buffer to fill, or None to allocate new buffer

Return type:

memoryview

Returns:

View into buffer with samples filled in stereo float32 format.

This method fills in a fixed number of output samples in the output buffer given (or creates a new buffer if none is given). The sequencer callback is called as needed to trigger MIDI events at the correct sample location.

generate_simple(samples, buffer=None)

Generate fixed number of output samples, ignoring sequenced events.

Parameters:
  • samples (int) – Number of samples to generate

  • buffer (Optional[memoryview]) – Existing buffer to fill, or None to allocate new buffer

Return type:

memoryview

Returns:

View into buffer with samples filled in stereo float32 format.

This method fills in a fixed number of output samples in the output buffer given (or creates a new buffer if none is given). The sequencer is not called from this method so no new events are ever triggered by this method.

See also: generate()

noteoff(chan, key)

Stop a note.

Parameters:
  • chan (int) – Channel to use (0-15)

  • key (int) – MIDI key to release (0-127), 60 is middle C

Returns:

True if note was valid, False if note was outside of legal range or channel did not have instrument loaded

It is valid to call noteoff on a note that never had noteon.

noteon(chan, key, velocity)

Play a note.

Parameters:
  • chan (int) – Channel to use (0-15)

  • key (int) – MIDI key to press (0-127), 60 is middle C

  • velocity (int) – Velocity of keypress (0-127), 0 means to turn off, 127 is maximum

Return type:

bool

Returns:

True if note was valid, False if note was outside of legal range or channel did not have instrument loaded

notes_off(chan=None)

Turn off all playing notes in all channels or one specific channel.

Parameters:

chan (Optional[int]) – Channel to use (0-15) or None to indicate all channels

Some instruments have long decays or may continue to produce sound after a NOTE_OFF event. If you need all sounds to stop playing use sounds_off().

pitchbend(chan, value)

Set pitch wheel position for a channel.

Parameters:
  • chan (int) – Channel to affect (0-15)

  • value (int) – Value from 0 to 16383 indicating pitch bend down to pitch bend up (default 8192, no pitch change)

See also: pitchbend_range()

pitchbend_range(chan, semitones)

Set pitch bend range up and down for a channel.

Parameters:
  • chan (int) – Channel to affect (0-15)

  • semitones (float) – Pitch bend range up and down in semitones (default 2.0)

See also: pitchbend()

program_change(chan, preset, is_drums=False)

Select a program for a specific channel.

Parameters:
  • chan (int) – Channel to affect (0-15)

  • preset (int) – Which preset to use (0-127)

  • is_drums (bool) – Whether to set channel to MIDI drum mode (default False)

Raises:

SoundFontException if channel is out of range or does not have a SoundFont loaded

Raises:

RuntimeError if bank/preset are out of range or do not match any instrument for the SoundFont in the channel

Note that presets are numbered with 0-based indexing. MIDI user interfaces typically number presets 1-128.

program_info(chan)

Get SoundFont id, bank, program number, and preset number of channel.

Parameters:

chan (int) – Channel to use (0-15)

Raises:

SoundFontException if channel is out of range or has no SoundFont loaded

Return type:

(int, int, int)

Returns:

Tuple containing (sfid, bank, preset) indicating SoundFont ID, bank number, and preset number

program_select(chan, sfid, bank, preset, is_drums=False)

Select a program from a SoundFont for specific channel

Parameters:
  • chan (int) – Channel to affect (0-15)

  • sfid (int) – ID of SoundFont to use

  • bank (int) – Bank to set (0-127)

  • preset (int) – Which preset to use (0-127)

  • is_drums (bool) – Whether to set channel to MIDI drum mode (default False)

Raises:

SoundFontException if the SoundFont does not exist

Raises:

RuntimeError if channel, bank, or preset is out of range

Raises:

RuntimeError if bank/preset does not match any instrument for the SoundFont

Note that presets are numbered with 0-based indexing. MIDI user interfaces typically number presets 1-128.

program_unset(chan)

Set the preset of a MIDI channel to an unassigned state.

Parameters:

chan (int) – Channel to affect (0-15)

Raises:

SoundFontException if channel is out of range

set_tuning(chan, tuning)

Set tuning for a channel.

Parameters:
  • chan (int) – Channel to affect (0-15)

  • tuning (float) – Tuning adjustment in semitones (default 0.0)

sfload(filename_or_bytes, gain=0.0, max_voices=256)

Load SoundFont and return its ID

Parameters:
  • filename_or_bytes (str | bytes) – either a filename containing sf2/sf3/sfo SoundFont data or bytes object

  • gain (float) – gain adjustment for this SoundFont, in relative dB (default 0.0)

  • max_voices (int) – maximum number of simultaneous voices (default 256)

Return type:

int

Returns:

ID of SoundFont to be used by other methods such as program_select()

When deciding on the value for max_voices, one note in a SoundFont may use more than one voice. Playing multiple notes also uses more voices. If more voices are required than are available, older voices will be cut off.

See also: program_select(), sfpreset_name(), sfunload()

sfpreset_name(sfid, bank, preset)

Return name of a SoundFont preset.

Parameters:
  • sfid (int) – ID of SoundFont to use

  • bank (int) – Bank to use (0-127)

  • preset (int) – Which preset to retrieve (0-127)

Raises:

SoundFontException if channel is out of range or has no SoundFont loaded

Raises:

RuntimeError if bank/preset are out of range

Return type:

Optional[str]

Returns:

Name of preset in SoundFont, or None if preset does not exist in SoundFont

Note that presets are numbered with 0-based indexing. MIDI user interfaces typically number presets 1-128.

sfunload(sfid)

Unload a SoundFont and free memory it used.

Parameters:

sfid (int) – ID of SoundFont to unload, as returned by sfload()

Raises:

SoundFontException if the SoundFont does not exist

See also: sfload()

sounds_off(chan=None)

Turn off all playing sounds in all channels or one specific channel.

Parameters:

chan (Optional[int]) – Channel to use (0-15) or None to indicate all channels

Some instruments have long decays or may continue to produce sound after a NOTE_OFF event. If you need all notes to stop playing and continue producing the decay, use notes_off().

start(buffer_size=1024, **kwargs)

Start audio playback in a separate thread.

Parameters:

buffer_size (int) – Number of samples to buffer or 0 for automatic sizing for low latency (default 1024)

Extra keyword arguments will be passed to the pyaudio stream constructor. Useful arguments might include:

  • output_device_index – index of output device to use, or None for default output device

Note that depending on your platform pyaudio may recognize a large number of devices not all of which are suitable for audio playback. You may need to use pyaudio method get_host_api_info_by_index() to find details about the pyaudio devices and choose a suitable index.

The separate audio playback thread will continue generating and playing samples until stopped with stop().

The audio thread will not prevent the main thread from exiting. If you turn on notes and call start(), your main thread will need to call time.sleep() to let time pass to be able to hear the notes playing. To schedule note events through time see Sequencer.

See also: stop()

stop()

Stop audio playback thread.

See also: start()

class tinysoundfont.midi.ControlChange(control, control_value)

Action that changes a MIDI control value

Parameters:
  • control (int) – MIDI controller number (0-127)

  • control_value (int) – Value to change to (0-127)

class tinysoundfont.midi.Event(action, t=0, channel=0, persistent=True)

A single event that can be sent to a Synth object.

Parameters:
class tinysoundfont.midi.NoteOff(key)

Action that turns off a single note

Parameters:

key (int) – MIDI note number of note (0-127)

class tinysoundfont.midi.NoteOn(key, velocity=0)

Action that turns on a single note

Parameters:
  • key (int) – MIDI note number of note (0-127)

  • velocity (int) – Velocity of note, 0 means turn off (0-127)

class tinysoundfont.midi.PitchBend(pitch_bend=8192)

Action that bends pitch of current channel

Parameters:

pitch_bend (int) – How much to bend pitch (0-16383, 8192 means no bend)

Range of pitch bend is set using RPN

class tinysoundfont.midi.ProgramChange(program)

Action that changes current preset program

Parameters:

program (int) – Preset number to use (0-127)

tinysoundfont.midi.load(filename, delta_time=0, filter=None, persistent=True)

Load MIDI file and turn into list of events.

Parameters:
  • filename (str) – Filename to load MIDI data from, in Standard MIDI format

  • delta_time (float) – Time offset to add to all events (default 0)

  • filter (Optional[Callable[[List[Event]], Optional[bool]]]) – Optional function that takes in individual events and can modify them or filter them out (default None)

  • persistent (bool) – Whether to keep events in queue after playing, allowing for seeking back to start or arbitrary positions after playback has started (default True)

Return type:

List[Event]

Returns:

List of events from MIDI data, possibly filtered

Filter function should take one input argument, the event, and modify it in place as needed. The function should return None or False to indicate to keep the modified event, or True to indicate that the event should be deleted.

See also: load_memory()

tinysoundfont.midi.load_memory(data, delta_time=0, filter=None, persistent=True)

Load MIDI data and turn into list of events.

Parameters:
  • data (bytes) – MIDI data, in Standard MIDI format

  • delta_time (float) – Time offset to add to all events (default 0)

  • filter (Optional[Callable[[List[Event]], Optional[bool]]]) – Optional function that takes in individual events and can modify them or filter them out (default None)

  • persistent (bool) – Whether to keep events in queue after playing, allowing for seeking back to start or arbitrary positions after playback has started (default True)

Return type:

List[Event]

Returns:

List of events from MIDI data, possibly filtered

Filter function should take one input argument, the event, and modify it in place as needed. The function should return None or False to indicate to keep the modified event, or True to indicate that the event should be deleted.

See also: load()