ChiptuneSAK Class Reference¶
Contents
Intermediate Representation Classes¶
Chirp¶
Note¶
-
class
chiptunesak.chirp.Note(start, note, duration, velocity=100, tied_from=False, tied_to=False)[source]¶ This class represents a note in human-friendly form: as a note with a start time, a duration, and a velocity.
-
note_num= None¶ MIDI note number
-
start_time= None¶ In ticks since tick 0
-
duration= None¶ In ticks
-
velocity= None¶ MIDI velocity 0-127
-
tied_from= None¶ Is the next note tied from this note?
-
tied_to= None¶ Is this note tied from the previous note?
-
ChirpTrack¶
-
class
chiptunesak.chirp.ChirpTrack(chirp_song, mchirp_track=None)[source]¶ This class represents a track (or a voice) from a song. It is basically a list of Notes with some other context information.
ASSUMPTION: The track contains notes for only ONE instrument (midi channel). Tracks with notes from more than one instrument will produce undefined results.
-
chirp_song= None¶ Parent song
-
name= None¶ Track name
-
channel= None¶ This track’s midi channel. Each track should have notes from only one channel.
-
notes= None¶ The notes in the track
-
program_changes= None¶ Program (patch) changes in the track
-
other= None¶ Other events in the track (includes voice changes and pitchwheel)
-
qticks_notes= None¶ Not start quantization from song
-
qticks_durations= None¶ Note duration quantization
-
import_mchirp_track(mchirp_track)[source]¶ Imports an MChirpTrack
Parameters: mchirp_track (MChirpTrack) – track to import
-
estimate_quantization()[source]¶ This method estimates the optimal quantization for note starts and durations from the note data itself. This version only uses the current track for the optimization. If the track is a part with long notes or not much movement, I recommend using the get_quantization() on the entire song instead. Many pieces have fairly well-defined note start spacing, but no discernable duration quantization, so in that case the default is half the note start quantization. These values are easily overridden.
Returns: tuple of quantization values for (start, duration) Return type: tuple of ints
-
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 either qticks parameter to be 1, so that it will quantize to the nearest tick (i.e. leave everything unchanged)
Parameters: - qticks_notes (int) – Resolution of note starts in ticks
- qticks_durations (int) – Resolution of note durations in ticks. Also length of shortest note.
-
quantize_long(qticks)[source]¶ Quantizes only notes longer than 3/4 qticks; quantizes both start time and duration. This function is useful for quantization that also preserves some ornaments, such as grace notes.
Parameters: qticks (int) – Quantization for notes and durations
-
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
-
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
-
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
-
remove_polyphony()[source]¶ This function eliminates polyphony, so that in each channel there is only one note active at a time. If a chord is struck all at the same time, it will retain the highest note. Otherwise, when a new note is started, the previous note is truncated.
-
is_polyphonic()[source]¶ Returns whether the track is polyphonic; if any notes overlap it is.
Returns: True if track is polyphonic. Return type: bool
-
is_quantized()[source]¶ Returns whether the current track is quantized or not. Since a quantization of 1 is equivalent to no quantization, a track quantized to tick will return False.
Returns: True if the track is quantized. Return type: bool
-
remove_keyswitches(ks_max=8)[source]¶ Removes all MIDI notes with values less than or equal to ks_max. Some MIDI devices and applications use these extremely low notes to convey patch change or other information, so removing them (especially if you do not want polyphony) is a good idea.
Parameters: ks_max (int) – maximum note number for keyswitches in the track (often 8)
-
truncate(max_tick)[source]¶ Truncate the track to max_tick
Parameters: max_tick (int) – maximum tick number for events to start (track will play to end of any notes started)
-
transpose(semitones)[source]¶ Transposes track in-place by semitones, which can be positive (transpose up) or negative (transpose down)
Parameters: semitones – Number of semitones to transpose
-
modulate(num, denom)[source]¶ Modulates this track metrically by a factor of num / denom
Parameters: - num – Numerator of modulation
- denom – Denominator of modulation
-
scale_ticks(scale_factor)[source]¶ Scales the ticks for this track by scale_factor.
Parameters: scale_factor –
-
ChirpSong¶
-
class
chiptunesak.chirp.ChirpSong(mchirp_song=None)[source]¶ Bases:
chiptunesak.base.ChiptuneSAKBaseThis class represents a song. It stores notes in an intermediate representation that approximates traditional music notation (as pitch-duration). It also stores other information, such as time signatures and tempi, in a similar way.
-
qticks_notes= None¶ Quantization for note starts, in ticks
-
qticks_durations= None¶ Quantization for note durations, in ticks
-
tracks= None¶ List of ChirpTrack tracks
-
other= None¶ List of all meta events that apply to the song as a whole
-
midi_meta_tracks= None¶ list of all the midi tracks that only contain metadata
-
midi_note_tracks= None¶ list of all the tracks that contain notes
-
time_signature_changes= None¶ List of time signature changes
-
key_signature_changes= None¶ List of key signature changes
-
tempo_changes= None¶ List of tempo changes
-
to_rchirp(**kwargs)[source]¶ Convert to RChirp. This calls the creation of an RChirp object
Returns: new RChirp object Return type: rchirp.RChirpSong
-
to_mchirp(**kwargs)[source]¶ Convert to MChirp. This calls the creation of an MChirp object
Returns: new MChirp object Return type: MChirpSong
-
import_mchirp_song(mchirp_song)[source]¶ Imports an MChirpSong
Parameters: mchirp_song (MChirpSong) –
-
set_metadata()[source]¶ Sets the song metadata to reflect the current status of the song. This function cleans up any redundant item signature, key signature, or tempo changes (two events that have the same timestamp) and keeps the last one it finds, then sets the metadata values to the first of each respectively.
-
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.
-
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
-
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
-
is_quantized()[source]¶ Has the song been quantized? This requires that all the tracks have been quantized with their current qticks_notes and qticks_durations values.
Returns: Boolean True if all tracks in the song are quantized
-
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)
-
is_polyphonic()[source]¶ Is the song polyphonic? Returns true if ANY of the tracks contains polyphony of any kind.
Returns: Boolean True if any track in the song is polyphonic Return type: bool
-
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
-
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)
-
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
-
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
-
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.
-
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
-
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
-
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 –
-
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’
-
end_time()[source]¶ Finds the end time of the last note in the song.
Returns: Time (in ticks) of the end of the last note in the song. Return type: int
-
measure_starts()[source]¶ Returns the starting time for measures in the song. Calculated using time_signature_changes.
Returns: List of measure starting times in MIDI ticks Return type: list
-
measures_and_beats()[source]¶ Returns the positions of all measures and beats in the song. Calculated using time_signature_changes.
Returns: List of MeasureBeat objects for each beat of the song. Return type: list
-
get_measure_beat(time_in_ticks)[source]¶ This method returns a (measure, beat) tuple for a given time; the time is greater than or equal to the returned measure and beat but less than the next. The result should be interpreted as the time being during the measure and beat returned.
Parameters: time_in_ticks (int) – Time during the song, in MIDI ticks Returns: MeasureBeat object with the current measure and beat Return type: MeasureBeat
-
MChirp¶
Measure¶
-
class
chiptunesak.mchirp.Measure(start_time, duration)[source]¶ -
process_triplets(measure_notes, ppq)[source]¶ Processes and accounts for all triplets in the measure
Parameters: - measure_notes (list of notes/triplets) – list of notes in the measure
- ppq (int) – pulses per quarter from song
Returns: new measure contents
Return type: list of notes/triplet
-
populate_triplet(triplet, measure_notes)[source]¶ Given a triplet, populate it from the ntoes in the measure, splitting them if required
Parameters: - triplet (Triplet) – triplet to be populated
- measure_notes (list of notes) – notes in the measure
Returns: measure notes now including triplet
Return type: list of notes/triplets
-
add_rests(measure_notes)[source]¶ Add rests to a measure content
Parameters: measure_notes (list of notes) – notes in the measure Returns: new list of events including rests Return type: list of events in measure
-
populate(track, carry=None)[source]¶ Populates a single measure with notes, rests, and other events.
Parameters: - track – Track from which events are to be imported
- carry – If last note in previous measure is continued in this measure, the note with remaining time
Returns: Carry note, if last note is to be carried into the next measure.
-
MChirpTrack¶
-
class
chiptunesak.mchirp.MChirpTrack(mchirp_song, chirp_track=None)[source]¶ -
measures= None¶ List of measures in the track
-
name= None¶ Track name
-
channel= None¶ Midi channel number
-
mchirp_song= None¶ parent MChirpSong
-
qticks_notes= None¶ Inherit quantization from song
-
qticks_durations= None¶ Inherit quantization from song
-
import_chirp_track(chirp_track)[source]¶ Converts a track into measures, each of which is a sorted list of notes and other events
Parameters: chirp_track (ChirpTrack) – A ctsSongTrack that has been quantized and had polyphony removed Returns: List of Measure objects corresponding to the measures
-
MChirpSong¶
-
class
chiptunesak.mchirp.MChirpSong(chirp_song=None)[source]¶ Bases:
chiptunesak.base.ChiptuneSAKBase-
metadata= None¶ Metadata
-
qticks_notes= None¶ Quantization for note starts, in ticks
-
qticks_durations= None¶ Quantization for note durations, in ticks
-
other= None¶ Other MIDI events not used in measures
-
import_chirp_song(chirp_song)[source]¶ Gets all the measures from all the tracks in a song, and removes any empty (note-free) measures from the end.
Parameters: chirp_song (ChirpSong) – A chirp.ChirpSong song
-
RChirp¶
RChirpRow¶
-
class
chiptunesak.rchirp.RChirpRow(row_num: int = None, milliframe_num: int = None, note_num: int = None, instr_num: int = None, new_instrument: int = None, gate: bool = None, milliframe_len: int = None, new_milliframe_tempo: int = None)[source]¶ The basic RChirp row
-
row_num= None¶ rchirp row number
-
milliframe_num= None¶ frames / 1000 since time 0
-
note_num= None¶ MIDI note number; None means no note asserted
-
instr_num= None¶ Instrument number
-
new_instrument= None¶ Indicates new instrument number; None means no change
-
gate= None¶ Gate on/off tri-value True/False/None; None means no gate change
-
milliframe_len= None¶ frames * 1000 to process this row (until next row)
-
new_milliframe_tempo= None¶ Indicates new tempo for channel (not global); None means no change
-
RChirpVoice¶
-
class
chiptunesak.rchirp.RChirpVoice(rchirp_song, chirp_track=None)[source]¶ The representation of a single voice; contains rows
-
rchirp_song= None¶ The song this voice belongs to
-
rows= None¶ dictionary: K:row num, V: RChirpRow instance
-
milliframe_indexed_rows¶ Returns dictionary of rows indexed by milliframe number
A voice holds onto a dictionary of rows keyed by row number. This method returns a dictionary of rows keyed by milliframe number.
Returns: A dictionary of rows keyed by milliframe number Return type: defaultdict
-
sorted_rows¶ Returns a list of row-number sorted rows for the voice
Returns: A sorted list of RChirpRow instances Return type: list
-
append_row(rchirp_row)[source]¶ Appends a row to the voice’s collection of rows
This is a helper method for treating rchirp like a list of contiguous rows, instead of a sparse dictionary of rows
Parameters: rchirp_row (RChirpRow) – A row to “append”
-
last_row¶ Returns the row with the largest milliframe number (latest in time)
Returns: row with latest milliframe number Return type: RChirpRow
-
next_row_num¶ Returns one greater than the largest row number held onto by the voice
Returns: largest row number + 1 Return type: int
-
is_contiguous()[source]¶ Determines if the voice’s rows are contiguous. This function requires that row numbers are consecutive and that the corresponding milliframe numbers have no gaps.
Returns: True if rows are contiguous, False if not Return type: bool
-
integrity_check()[source]¶ Finds problems with a voice’s row data
Returns: True if all integrity checks pass Raises: AssertionError – Various integrity failure assertions possible
-
make_filled_rows()[source]¶ Creates a contiguous set of rows from a sparse row representation
Returns: filled rows Return type: list of rows
-
orderlist_to_rows()[source]¶ Convert an orderlist with patterns into rows
Returns: rows Return type: list of rows
-
validate_orderlist()[source]¶ Validate that the orderlist is self-consistent and generates the correct set of rows
Returns: True if consistent Return type: bool
-
import_chirp_track(chirp_track)[source]¶ - Imports a Chirp track into a raw RChirpVoice object. No compression or conversion to patterns
- and orderlists performed. Track must be non-polyphonic and quantized.
Parameters: chirp_track (ChirpTrack) – A chirp track
Raises: - ChiptuneSAKQuantizationError – Thrown if chirp track is not quantized
- ChiptuneSAKPolyphonyError – Thrown if a single voice contains polyphony
-
RChirpSong¶
-
class
chiptunesak.rchirp.RChirpSong(chirp_song=None)[source]¶ Bases:
chiptunesak.base.ChiptuneSAKBaseThe representation of an RChirp song. Contains voices, voice groups, and metadata.
-
arch= None¶ Architecture
-
voices= None¶ List of RChirpVoice instances
-
voice_groups= None¶ Voice groupings for lowering to multiple chips
-
patterns= None¶ Patterns to be shared among the voices
-
other= None¶ Other meta-events in song
-
compressed= None¶ Has song been through compression algorithm?
-
program_map= None¶ Midi-to-RChirp instrument map
-
metadata= None¶ Song metadata (author, copyright, etc.)
-
to_chirp(**kwargs)[source]¶ Converts the RChirpSong into a ChirpSong
Returns: Chirp song Return type: ChirpSong
-
import_chirp_song(chirp_song)[source]¶ Imports a ChirpSong
Parameters: chirp_song (ChirpSong) – A chirp song
Raises: - ChiptuneSAKQuantizationError – Thrown if chirp track is not quantized
- ChiptuneSAKPolyphonyError – Thrown if a single voice contains polyphony
-
remove_tempo_changes()[source]¶ Removes tempo changes and sets milliframes_per_row constant for the entire song. This method is used to eliminate accelerandos and ritarandos throughout the song for better conversion to Chirp.
Returns: True on success Return type: bool
-
has_patterns()[source]¶ Does this RChirp have patterns (and thus, presumably, orderlists)?
Returns: True if there are patterns Return type: bool
-
make_program_map(chirp_song)[source]¶ Creates a program map of Chirp program numbers (patches) to instruments
Parameters: chirp_song (ChirpSong) – chirp song Returns: program_map Return type: dict of {chirp_program:rchirp_instrument}
-
is_contiguous()[source]¶ Determines if the voices’ rows are contiguous, without gaps in time
Returns: True if rows are contiguous, False if not Return type: bool
-
integrity_check()[source]¶ Finds problems with voices’ row data
Returns: True if integrity checks pass for all voices Raises: AssertionError – Various integrity failure assertions possible
-
set_row_delta_values()[source]¶ RChirpRow has some delta fields that are only set when there’s a change from previous rows.
This method goes through the rows, finds those changes and sets the appropriate fields
-
milliframe_indexed_voices()[source]¶ Returns a list of dicts, where many voices hold onto many rows. Rows indexed by milliframe number.
Returns: a list of dicts (voices->rows) Return type: list
-
Input/Output Classes¶
MIDI Class¶
-
class
chiptunesak.midi.MIDI[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIOImport/Export MIDI files to and from Chirp songs.
The Chirp format is most closely tied to the MIDI standard. As a result, conversion between MIDI files and ChirpSong objects is one of the most common ways to import and export music using the ChiptuneSAK framework.
The MIDI class does not implement the standard to_bin() method because it uses the mido library to process low-level midi messages, and mido only deals with MIDI files.
The Chirp framework can import both MIDI type 0 and type 1 files. It will only write MIDI type 1 files.
-
to_chirp(filename, **kwargs)[source]¶ Import a midi file to Chirp format
Parameters: - filename (str) – filename to import
- options –
- keyswitch (bool) Remove keyswitch notes with midi number <=8 (default True)
- polyphony (bool) Allow polyphony (removal occurs after any quantization) (default True)
- quantize (str)
- ’auto’: automatically determines required quantization
- ’8’, ‘16’, ‘32’, etc. : quantize to the named duration
Returns: chirp song
Return type:
-
to_file(song, filename, **kwargs)[source]¶ Exports a ChirpSong to a midi file.
Parameters: - song (chirpSong) – chirp song
- filename (str) – filename for export
Returns: True on success
Return type: bool
-
midi_track_to_chirp_track(chirp_song, midi_track)[source]¶ Parse a MIDI track into notes, track name, and program changes. This method uses the mido library for MIDI messges within the track.
Parameters: midi_track (MIDO midi track) – midi track
-
import_midi_to_chirp(input_filename)[source]¶ Open and import a MIDI file into the ChirpSong representation. THis method can handle MIDI type 0 and 1 files.
param input_filename: MIDI filename.
-
get_meta(chirp_song, meta_track, is_zerotrack=False, is_metatrack=False)[source]¶ Process MIDI meta messages in a track.
param chirp_song: param meta_track: param is_zerotrack: param is_metatrack:
-
GoatTracker Class¶
-
class
chiptunesak.goat_tracker.GoatTracker[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIOThe IO interface for GoatTracker and GoatTracker Stereo
Supports conversions between RChirp and GoatTracker .sng format
-
set_options(**kwargs)[source]¶ Sets options for this module, with validation when required
Parameters: kwargs (keyword arguments) – keyword arguments for options
-
to_bin(rchirp_song, **kwargs)[source]¶ Convert an RChirpSong into a GoatTracker .sng file format
Parameters: - rchirp_song (MChirpSong) – rchirp data
- options –
- end_with_repeat (bool) - True if song should repeat when finished
- max_pattern_len (int) - Maximum pattern length to use. Must be <= 127
- instruments (list of str) - Instrument names that will be extracted from GT instruments directory
- Note: These instruments are in instrument order, not in voice order! Multiple voices may use the same instrument, or multiple instruments may be on a voice. The instrument numbers are assigned in the order instruments are processed on conversion to RChirp.
Returns: sng binary file format
Return type: bytearray
-
to_file(rchirp_song, filename, **kwargs)[source]¶ Convert and save an RChirpSong as a GoatTracker sng file
Parameters: - rchirp_song (RChirpSong) – rchirp data
- filename (str) – output path and file name
- options – see to_bin()
-
to_rchirp(filename, **kwargs)[source]¶ Import a GoatTracker sng file to RChirp
Parameters: - filename (str) – File name of .sng file
- options –
- subtune (int) - The subtune numer to import. Defaults to 0
- arch (str) - architecture string. Must be one defined in constants.py
Returns: rchirp song
Return type:
-
SID Class¶
-
class
chiptunesak.sid.SID[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIOParses and imports SIDs into RChirp using 6502/6510 emulation with a thin C64 layer.
This class is the import interface for ChiptuneSAK for SIDs. It runs the SID in the emulator, using the information in the SID header to configure the driver, and captures information from the interaction of the code with the SID chip(s) following init and play calls.
The resulting data can be converted to an RChirpSong object and/or written as a csv file that has a row for each invocation of the play routine. The csv file is useful for diagnosing how the play routine is modifying the SID chip and helps inform choices about the conversion of the SID music to the rchirp format.
-
set_options(**kwargs)[source]¶ Sets options for this module, with validation when required
Note: set_options gets called on __init__ (setting defaults), and a 2nd time if options are to be set after object instantiation.
Parameters: kwargs (keyword arguments) – keyword arguments for options See to_rchirp() for possible options
-
capture()[source]¶ Captures data by emulating the SID song execution
This method calls internal methods that watch how the machine language program interacts with virtual SID chip(s), and records these interactions on a call-by-call basis (of the play routine).
Returns: captured SID data as a Dump object Return type: Dump
-
to_rchirp(sid_in_filename, **kwargs)[source]¶ Converts a SID subtune into an RChirpSong
Parameters: - sid_in_filename (str) – SID input filename
- options –
- subtune (int = 0) - subtune to extract (zero-indexed)
- vibrato_cents_margin (int = 0) - cents margin to control snapping to previous note
- tuning (int = CONCERT_A) - tuning to use,
- seconds (float = 60) - seconds to capture
- arch (string=’NTSC-C64’) - architecture. Note: overwritten if/when SID headers get parsed
- gcf_row_reduce (bool = True) - reduce rows via GCF of row-activity gaps
- create_gate_off_notes (bool = True) - allow new note starts when gate is off
- assert_gate_on_new_note (bool = True) - True => gate on event in delta rows with new notes
- always_include_freq (bool = False) - False => freq in delta rows only with new note
- verbose (bool = True) - print details to stdout
Returns: SID converted to RChirpSong
Return type:
-
to_csv_file(output_filename, **kwargs)[source]¶ Convert a SID subtune into a CSV file
Each row of the csv file represents one call of the play routine.
Parameters: output_filename (str) – output CSV filename
-
get_val(val, format=None)[source]¶ Used to create CSV string values when not None
Parameters: - val (str or int) – str or int
- format (str, optional) – format descriptor, defaults to None
Returns: empty string, passed in value (with possible formatting)
Return type: str or int
-
get_bool(bool, true_str='on', false_str='off')[source]¶ Used to create CSV string values when not None
Parameters: - bool (bool) – a boolean
- true_str (str, optional) – string if true, defaults to ‘on’
- false_str (str, optional) – string if false, defaults to ‘off’
Returns: string description of boolean
Return type: str
-
reduce_rows(sid_dump, rows_with_activity)[source]¶ The SidImport class samples SID chip state after each call to the play routine. This creates 1 row per play call. For non-multispeed, in most trackers, this would require speed 1 playback (1 frame per row), which cannot be achieved (again, without multispeed). So this method attempts to reduce the number of rows in the representaton. It does so by computing the greatest common divisor for the count of inactive rows between active rows, and then eliminates the unnecessary rows (while preserving rhythm structure).
# TODO: A row in cvs output contains all channels at a point in time. A row # in rchirp contains only one channel. When not making CVS output, better # results could be achieved by computing the GCD for each voice # independently.
Parameters: - sid_dump (sid.Dump) – Capture of SID chip state from the subtune
- rows_with_activity (list of lists) – a list for each SID chip with a list of “active” row numbers
Returns: the row granularity (the largest common factor across all periods of inactivity)
Return type: int
-
Lilypond Class¶
-
class
chiptunesak.lilypond.Lilypond[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIO-
to_bin(mchirp_song, **kwargs)[source]¶ Exports MChirp to lilypond text
Parameters: - mchirp_song (MChirpSong) – song to export
- options –
- format (string) - format, either ‘song’ or ‘clip’
- autosort (bool) - sort tracks from highest to lowest average pitch
- measures (list) - list of contiguous measures, from one track. Required for ‘clip’ format, ignored otherwise.
Returns: lilypond text
Return type: str
-
to_file(mchirp_song, filename, **kwargs)[source]¶ Exports MChirp to lilypond source file
Parameters: - mchirp_song (MChirpSong) – song to export
- filename (str) – filename to write
- options – see to_bin()
Returns: lilypond text
Return type: str
-
measure_to_lilypond(measure)[source]¶ Converts contents of a measure into Lilypond text
Parameters: measure – A ctsMeasure.Measure object Returns: Lilypond text encoding the measure content.
-
export_clip_to_lilypond(mchirp_song, measures)[source]¶ Turns a set of measures into Lilypond suitable for use as a clip. All the music will be on a single line with no margins. It is recommended that this clip be turned into Lilypond using the command line:
lilypond -ddelete-intermediate-files -dbackend=eps -dresolution=600 -dpixmap-format=pngalpha --png <filename>Parameters: - mchirp_song (MChirpSong) – ChirpSong from which the measures were taken.
- measures (list) – List of measures.
Returns: Lilypond markup ascii
Return type: str
-
export_song_to_lilypond(mchirp_song)[source]¶ Converts a song to Lilypond format. Optimized for multi-page PDF output of the song. Recommended lilypond command:
lilypond <filename>Parameters: mchirp_song (MChirpSong) – ChirpSong to convert to Lilypond format Returns: Lilypond markup ascii Return type: str
-
C128 Basic Class¶
-
class
chiptunesak.c128_basic.C128Basic[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIOThe IO interface for C128BASIC Supports to_bin() and to_file() conversions from mchirp to C128 BASIC options: format, arch, instruments
-
set_options(**kwargs)[source]¶ Sets the options for commodore export
Parameters: kwargs (keyword arguments) – keyword arguments for options
-
to_bin(mchirp_song, **kwargs)[source]¶ Convert an MChirpSong into a C128 BASIC music program
Parameters: - mchirp_song (MChirpSong) – mchirp data
- options – see to_file()
Returns: C128 BASIC program
Return type: str or bytearray
-
to_file(mchirp_song, filename, **kwargs)[source]¶ Converts and saves MChirpSong as a C128 BASIC music program
Parameters: - mchirp_song (MChirpSong) – mchirp data
- filename (str) – path and filename
- options –
- arch (str) - architecture name (see base for complete list)
- format (str) - ‘bas’ for BASIC source code or ‘prg’ for prg
- instruments (list of str) - list of 3 instruments for the three voices (in order).
- Default is [‘piano’, ‘piano’, ‘piano’]
- Supports the default C128 BASIC instruments: 0:’piano’, 1:’accordion’, 2:’calliope’, 3:’drum’, 4:’flute’, 5:’guitar’, 6:’harpsichord’, 7:’organ’, 8:’trumpet’, 9:’xylophone
- tempo_override (int) - override the computed tempo
- rem_override (string) - use passed string for leading REM statement instead of filename
-
export_mchirp_to_C128_BASIC(mchirp_song)[source]¶ Convert mchirp into a C128 Basic program that plays the song. This method is invoked via the C128Basic ChiptuneSAKIO class
Parameters: mchirp_song (MChirpSong) – An mchirp song Returns: Returns an ascii BASIC program Return type: str
-
ML64 Class¶
-
class
chiptunesak.ml64.ML64[source]¶ Bases:
chiptunesak.base.ChiptuneSAKIO-
to_bin(song, **kwargs)[source]¶ Generates an ML64 string for a song
Parameters: - song (ChirpSong or mchirp.MChirpSong) – song
- options –
- format (string) - ‘compact’, ‘standard’, or ‘measures’; ‘measures’ requires MChirp; the others convert from Chirp
Returns: ML64 encoding of song
Return type: str
-
to_file(song, filename, **kwargs)[source]¶ Writes ML64 to a file
Parameters: - song (ChirpSong or mchirp.MChirpSong) – song
- options – see to_bin()
Returns: ML64 encoding of song
Return type: str
-
export_chirp_to_ml64(chirp_song)[source]¶ Export song to ML64 format, with a minimum number of notes, either with or without measure comments. With measure comments, the comments appear within the measure but are not guaranteed to be exactly at the beginning of the measure, as tied notes will take precedence. In compact mode, the ML64 emitted is almost as small as possible. :param chirp_song: :type chirp_song:
-
export_mchirp_to_ml64(mchirp_song)[source]¶ Export the song in ML64 format, grouping notes into measures. The measure comments are guaranteed to appear at the beginning of each measure; tied notes will be split to accommodate the measure markers. :param mchirp_song: An mchirp song :type mchirp_song: MChirpSong
-
Compression Classes¶
One-Pass Class¶
-
class
chiptunesak.one_pass_compress.OnePass[source]¶ Bases:
chiptunesak.base.ChiptuneSAKCompress-
find_best_repeats(repeats)[source]¶ Find the best repeats to use for a set of repeats. Right now, the metric is coverage, with the shortest repeats that give a certain coverage used, but the metric can easily be changed. :param repeats: list of valid repeats :type repeats: list of Repeat objects :return: list of optimal repeats :rtype: list of Repeat objects
-
apply_pattern(pattern_index, repeats, order)[source]¶ Given a pattern index and a set of repeats that match the pattern, mark the affected rows as used and insert them into the temporary orderlist :param pattern_index: Pattern number for the cstRChirpSong :type pattern_index: int :param repeats: Repeats that match the pattern :type repeats: list of Repeat objects :param order: temporary dictionary for the orderlist :type order: dictionary of (start_row, transposition) tuples :return: order :rtype: orderlist dictionary
-
trim_repeats(repeats)[source]¶ Trims the list of repeats to exclude rows that have been used. :param repeats: list of all repeats :type repeats: list of Repeat objects :return: list of valid repeats :rtype: list of Repeat objects
-
get_hole_lengths()[source]¶ Creates list of the holes of unused rows in a set of rows. :return: :rtype:
-
static
add_rchirp_pattern_to_song(rchirp_song, pattern)[source]¶ Adds a pattern to an RChirpSong. It checks to be sue that the pattern has not been used. :param rchirp_song: An RChirpSong :type rchirp_song: rchirpSong :param pattern: the pattern to add to the song :type pattern: rchirp.RChirpPattern :return: Index of pattern :rtype: int
-
static
make_orderlist(order)[source]¶ Converts the temporary dictionary-based orderlist into an RChirp-compatible orderlist :param order: dictionary orderlist (created internally) :type order: dictionary of (start_row, transposition) :return: orderlist to put into a rchirp.RChirpVoice :rtype: rchirp.RChirpOrderList
-
One-Pass Global Class¶
-
class
chiptunesak.one_pass_compress.OnePassGlobal[source]¶ Bases:
chiptunesak.one_pass_compress.OnePassGlobal greedy compression algorithm for GoatTracker
This algorithm attempts to find the best repeats to compress at every iteration; it begins by finding all possible repeats longer than min_pattern_length (which is O(n^2)) and then at each iteration chooses the set of repeats with the highest score. The rows used are removed and the algorithm iterates. At each iteration the available repeats are trimmed to avoid the used rows.
-
compress(rchirp_song, **kwargs)[source]¶ Compresses the RChirp using a single-pass global greedy pattern detection. It finds all repeats in the song and turns the lrgest one into a pattern. It continues this operation until the longest repeat is shorter than min_pattern_length, after which it fills in the gaps.
Parameters: - rchirp_song (rchirp.RChirpSong) – RChirp song to compress
- options –
- min_pattern_length (int) - minimum pattern length in rows
- min_transpose (int) - minimum transposition, in semitones, for a pattern to be a match (GoatTracker = -15)
- max_transpose (int) - maximum transposition, in semitones, allowed for a pattern to be a match (GoatTracker = +14)
- for no transposition, set both min_transpose and max_transpose to 0.
Returns: rchirp_song with compression information added
Return type:
-
find_all_repeats(rows)[source]¶ Find every possible repeat in the rows longer than a minimum length :param rows: list of rows to search for repeats :type rows: list of cts.RChirpRows :return: list of all repeats found :rtype: list of Repeat
-
compress_global(rchirp_song)[source]¶ Global greedy compression algorithm for GoatTracker
This algorithm attempts to find the best repeats to compress at every iteration; it begins by finding all possible repeats longer than min_pattern_length (which is O(n^2)) and then at each iteration chooses the set of repeats with the highest score. The rows used are removed and the algorithm iterates. At each iteration the available repeats are trimmed to avoid the used rows.
Parameters: rchirp_song (rchirp.RChirpSong) – RChirp song to compress Returns: rchirp_song with compression information added Return type: rchirp.RChirpSong
-
One-Pass Left-to-Right Class¶
-
class
chiptunesak.one_pass_compress.OnePassLeftToRight[source]¶ Bases:
chiptunesak.one_pass_compress.OnePassLeft-to-right left single-pass compression for GoatTracker
This compression algorithm is the fastest; it can compress even the longest song in less than a second. It compresses the song in a manner similar to how a GoatTracker song would be constructed; starting from the beginning row, it finds the repeats of rows starting at that position that give the best score, and then moves to the first gap in the remaining rows and repeats. If the algorithm does not find any suitable repeats at a position, it moves to the next, and the unused rows are put into patterns after all the repeats have been found.
-
compress(rchirp_song, **kwargs)[source]¶ Compresses the RChirp using a single-pass left-to-right pattern detection. Starting at the first row, it finds the longest pattern that repeats, and if it is longer than min_pattern_length it removes the pattern and all repeats from the remaining rows. It then performs the same operation on the first available row until all patterns have been found, and then fills in the gaps.
Parameters: - rchirp_song (rchirp.RChirpSong) – RChirp song to compress
- options –
- min_pattern_length (int) - minimum pattern length in rows
- min_transpose (int) - minimum transposition, in semitones, for a pattern to be a match (GoatTracker = -15)
- max_transpose (int) - maximum transposition, in semitones, allowed for a pattern to be a match (GoatTracker = +14)
- for no transposition, set both min_transpose and max_transpose to 0.
Returns: rchirp_song with compression information added
Return type:
-
compress_lr(rchirp_song)[source]¶ Right-to-left single-pass compression for GoatTracker
This compression algorithm is the fastest; it can compress even the longest song in less than a second. It compresses the song in a manner similar to how a GT song would be constructed; starting from the beginning row, it finds the repeats of rows starting at that position that give the best score, and then moves to the first gap in the remaining rows and repeats. If the algorithm does not find any suitable repeats at a position, it moves to the next, and the unused rows are put into patterns after all the repeats have been found.
Parameters: rchirp_song (rchirp.RChirpSong) – RChirp song to compress Returns: rchirp_song with compression information added Return type: rchirp.RChirpSong
-