Music Processing and Transformation in Chirp

Most music transformation and processing capabilities in ChiptuneSAK are performed in the Chirp representation. The Chirp classes together implement a rich set of transformations to allow straightforward programmatic control over many song details.

To perform these operations, music is imported and converted to the Chirp representation. The ChirpSong and ChirpTrack classes have a large number of pre-defined music transformation methods, and are designed to make addition of new methods straightforward.

For transformations involving changing notes, if a method is defined for a ChirpSong class, the same method is defined for the ChirpTrack class; the track method is called by the song method for all tracks.

Metadata transformations either apply to the complete song or to an individual track.

Simple Transformations

ChirpSong.transpose(semitones, minimize_accidentals=True)[source]

Transposes the song by semitones

Parameters:
  • semitones (int) – number of semitones to transpose by. Positive transposes to higher pitch.
  • minimize_accidentals (bool) – True to choose key signature to minimize number of accidentals
ChirpSong.scale_ticks(scale_factor)[source]

Scales the ticks for all events in the song. Multiplies the time for each event by scale_factor. This method also changes the ppq by the scale factor.

Parameters:scale_factor (float) – Floating-point scale factor to multiply all events.
ChirpSong.move_ticks(offset_ticks)[source]

Moves all notes in the song a given number of ticks. Adds the offset to the current tick for every event. If the resulting event has a negative starting time in ticks, it is set to 0.

Parameters:offset_ticks (int) – Offset in ticks
ChirpSong.truncate(max_tick)[source]

Truncate the song to max_tick

Parameters:max_tick (int) – maximum tick number for events to start (song will play to end of any notes started)

Quantization Transformations

ChirpSong.estimate_quantization()[source]

This method estimates the optimal quantization for note starts and durations from the note data itself. This version all note data in the tracks. Many pieces have no discernable duration quantization, so in that case the default is half the note start quantization. These values are easily overridden.

ChirpSong.quantize(qticks_notes=None, qticks_durations=None)[source]

This method applies quantization to both note start times and note durations. If you want either to remain unquantized, simply specify a qticks parameter to be 1 (quantization of 1 tick).

Parameters:
  • qticks_notes (int) – Quantization for note starts, in MIDI ticks
  • qticks_durations (int) – Quantization for note durations, in MIDI ticks
ChirpSong.quantize_from_note_name(min_note_duration_string, dotted_allowed=False, triplets_allowed=False)[source]

Quantize song with more user-friendly input than ticks. Allowed quantizations are the keys for the constants.DURATION_STR dictionary. If an input contains a ‘.’ or a ‘-3’ the corresponding values for dotted_allowed and triplets_allowed will be overridden.

Parameters:
  • min_note_duration_string (str) – Quantization note value
  • dotted_allowed (bool) – If true, dotted notes are allowed
  • triplets_allowed (bool) – If true, triplets (of the specified quantization) are allowed

All the above methods make use of this quantization function:

chirp.quantize_fn(qticks)

This function quantizes a time or duration to a certain number of ticks. It snaps to the nearest quantized value.

Parameters:
  • t (int) – a start time or duration, in ticks
  • qticks (int) – quantization in ticks
Returns:

quantized start time or duration

Return type:

int

Polyphony Transformations

ChirpSong.remove_polyphony()[source]

Eliminate polyphony from all tracks.

ChirpSong.explode_polyphony(i_track)[source]

‘Explodes’ a single track into multi-track polyphony. The new tracks replace the old track in the song’s list of tracks, so later tracks will be pushed to higher indexes. The new tracks are named using the name of the original track with ‘_sx’ appended, where x is a number for the split notes. The polyphony is split using a first-available-track algorithm, which works well for splitting chords.

Parameters:i_track (int) – zero-based index of the track for the song (ignore the meta track - first track is 0)

Metadata Transformations

ChirpSong.set_time_signature(num, denom)[source]

Sets the time signature for the entire song. Any existing time signature changes will be removed.

Parameters:
  • num
  • denom
ChirpSong.set_key_signature(new_key)[source]

Sets the key signature for the entire song. Any existing key signatures and changes will be removed.

Parameters:new_key (str) – Key signature. String such as ‘A#’ or ‘Abm’
ChirpSong.set_qpm(qpm)[source]

Sets the tempo in QPM for the entire song. Any existing tempo events will be removed.

Parameters:qpm (int) – quarter-notes per minute tempo

Advanced Transformations

ChirpSong.remove_keyswitches(ks_max=8)[source]

Some MIDI programs use extremely low notes as a signaling mechanism. This method removes notes with pitch <= ks_max from all tracks.

Parameters:ks_max (int) – Maximum note number for the control notes
ChirpSong.modulate(num, denom)[source]

This method performs metric modulation. It does so by multiplying the length of all notes by num/denom, and also automatically adjusts the time signatures and tempos such that the resulting music will sound identical to the original.

Parameters:
  • num (int) – Numerator of metric modulation
  • denom (int) – Denominator of metric modulation

The following are meant to be applied to individual tracks and have no corresponding methods in the ChirpSong class:

ChirpTrack.merge_notes(max_merge_length_ticks)[source]

Merges immediately adjacent notes if they are short and have the same note number.

Parameters:max_merge_length_ticks (int) – Length of the longest note to merge, in ticks
ChirpTrack.remove_short_notes(max_duration_ticks)[source]
Removes notes shorter than max_duration_ticks from the track.
Parameters:max_duration_ticks (int) – maximum duration of notes to remove, in ticks
ChirpTrack.set_min_note_len(min_len_ticks)[source]

Sets the minimum note length for the track. Notes shorter than min_len_ticks will be lengthened and any notes that overlap will have their start times adjusted to allow the new longer note.

Parameters:min_len_ticks (int) – Minimum note length