Intermediate Represention (ir) of pattern data to be compiled.
Using IR format allows us to easily convert between formats where the process for converting a given input to a given output follows:
<input> -> IR -> <output>
Where input is typically a TBM, or another module format like FTM or MPT, and output can be ASM, GBS, TBM, etc.
Example uses:
Input | Output | Description |
---|---|---|
*.ftm | *.tbm | FamiTracker module converter |
*.tbm | *.asm | Pattern compiler, export module to Game Boy assembly |
*.tbm | *.gbs | GBS exporter |
Creating IR can be done by using the getIr procs, or created manually.
Types
FrequencyMod = enum freqPortamento, freqPitchUp, freqPitchDown, freqNoteUp, freqNoteDown, freqArpeggio
- Enum for a frequency modulation effect. Source Edit
Operation = object flags*: set[OperationFlag] ## The set of flags that are active on this operation. settings*: array[OperationSetting, uint8] ## Array of settings for each flag that has one. A setting value can be ## ignored if its flag is not set. patternCommand*: PatternCommand ## The pattern command to perform if flag `opsPatternCommand` is set. freqMod*: FrequencyMod ## The type of frequency modulation to perform. This field should only ## be accessed when `opsFreqMod` is set.
-
An Operation is the processed form of a TrackRow, that can be performed by a playback engine, or exported to an output format.
You can convert a TrackRow to an Operation via the toOperation proc.
Source Edit OperationFlag = enum opsPatternCommand, ## Effects Bxx, Dxx opsSpeed, ## Effect Fxx opsVolume, ## Effect Jxy opsNote, ## Note column opsInstrument, ## Instrument column opsDelay, ## Effect Gxx opsDuration, ## Effect Sxx or note cut (duration = 0) opsEnvelope, ## Effect Exx opsTimbre, ## Effect V0x opsPanning, ## Effect I0x opsSweep, ## Effect Hxx opsFreqMod, ## Effects 0xy, 1xx, 2xx, 3xx, Qxy, Rxy opsVibrato, ## Effect 4xy opsVibratoDelay, ## Effect 5xx opsTune, ## Effect Pxx opsHalt, ## Effect C00 opsShouldLock ## Effect L00
- Enum of flags that specify what the operation does. Each flag is either a column of the TrackRow (note, instrument) or an effect instance. Source Edit
OperationSetting = range[opsPatternCommand .. opsTune]
- Subrange of OperationFlag that have a uint8 setting. Flags in this range have an additional uint8 value to be processed, ie, an effect parameter or a note. Source Edit
PatternCommand = enum pcNone, ## No pattern command, do not change pattern pcNext, ## Skip to the next pattern in the order, starting at a given row. pcJump ## Jump to the given pattern in the order.
- Enum for commands that change the current pattern. Source Edit
PatternVisit = object pattern*: int ## The index in the song's order of the pattern being visited rows*: int ## The number of rows that were visited. startRow*: int ## The starting row of the visit, 0 in most cases. When a visit's starting ## row is nonzero, this means that the Dxx effect (pattern skip) with a ## nonzero parameter was encountered in the previous pattern visit.
- A visit to a pattern contains its pattern index and the number of rows encountered before reaching the end or a pattern command occurred. Source Edit
RowIr = object case kind*: RowIrKind of rikRest: restDuration*: int ## The number of rows to rest for. Must be positive! of rikOp: op*: Operation ## The operation to perform
- Row intermediate representation. A RowIR is an intermediate representation of a single non-empty TrackRow (operation), or 1 or more empty TrackRows (rest). Source Edit
RowIrKind = enum rikRest, ## This kind of IR is a rest, or a duration of time where the track is ## not playing anything. This is represented by a group of empty rows ## in a Track. rikOp ## This kind of IR is an operation, or a non-empty row that performs ## some kind of action.
- Enum for the two different kinds of RowIr, rests and operations. Source Edit
SongPath = object visits*: seq[PatternVisit] loopIndex*: Option[int]
- A path of patterns in the order that they will be played out for a song, with an optional loop index. If loopIndex.isNone() then the song will halt at the last pattern visited. Source Edit
Procs
func fromIr(ir: TrackIr): Track {....raises: [], tags: [].}
- Converts a TrackIr into a Track. Source Edit
func isNoop(op: Operation): bool {....raises: [], tags: [].}
- Determines if the operation has no effect, or is a no-op. Operations with this property can be safely excluded from the compilation process. Source Edit
proc setFromIr(track: var Track; ir: TrackIr) {....raises: [], tags: [].}
- Sets the given track's row data using the given ir data. This proc does not clear the track beforehand for optimization purposes, ensure that track is an empty one first before calling this function. Source Edit
func toEffectType(x: FrequencyMod): EffectType {....raises: [], tags: [].}
- Converts a FrequencyMod enum to an EffectType enum Source Edit
func toEffectType(x: PatternCommand): EffectType {....raises: [], tags: [].}
- Converts a PatternCommand enum to an EffectType enum Source Edit
func toIr(t: TrackView): TrackIr {....raises: [], tags: [].}
- Gets the immediate representation, ir, of a given track. Source Edit
func toOperation(row: TrackRow): Operation {....raises: [], tags: [].}
- Converts a TrackRow to an Operation. An Operation is a simplified version of a TrackRow, which removes any redundant effects. Some information in row may be lost when converting the operation back to a TrackRow. Source Edit
Templates
template `[]`(op: Operation; flag: OperationSetting): uint8
- Shortcut for op.getSetting(flag) Source Edit
template contains(op: Operation; flag: OperationFlag): bool
- Shortcut for flag in op.flags Source Edit
template forflagPresent(op: Operation; flag: OperationFlag; body: untyped): untyped
- Template that executes body if flag is present in op Source Edit
template getSetting(op: Operation; flag: OperationSetting): uint8
- Gets the uint8 setting associated with the given flag. If flag is not present in op, 0 is returned. Source Edit