All files / src/shared/lib/uge song.ts

100% Statements 36/36
100% Branches 0/0
100% Functions 9/9
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 11162x                               62x     62x 9162x                 62x 108x             62x 4x 4x                       62x 9189x                 62x 94x           62x 44x                                           62x 318x 318x 318x       62x 316x 316x 316x       62x 316x 316x 316x    
import {
  TRACKER_NUM_CHANNELS,
  TRACKER_PATTERN_LENGTH,
  TRACKER_SUBPATTERN_LENGTH,
} from "consts";
import {
  Song,
  Pattern,
  SequenceItem,
  PatternCell,
  SubPatternCell,
  DutyInstrument,
  WaveInstrument,
  NoiseInstrument,
} from "./types";
 
const LAST_VERSION = 6;
 
/** Creates a new empty PatternCell with all fields set to null. */
export const createPatternCell = (): PatternCell => {
  return {
    note: null,
    instrument: null,
    effectCode: null,
    effectParam: null,
  };
};
 
/** Creates a new empty Pattern with `TRACKER_PATTERN_LENGTH` rows. */
export const createPattern = (): Pattern => {
  return Array.from(
    { length: TRACKER_PATTERN_LENGTH },
    createPatternCell,
  ) as Pattern;
};
 
/** Maps a linked UI pattern index to four per-channel pattern indices. */
export const createSequenceItem = (patternId: number): SequenceItem => {
  const basePatternId = patternId * TRACKER_NUM_CHANNELS;
  return {
    splitPattern: false,
    channels: [
      basePatternId,
      basePatternId + 1,
      basePatternId + 2,
      basePatternId + 3,
    ],
  };
};
 
/** Creates a new empty SubPatternCell with all fields set to null. */
export const createSubPatternCell = (): SubPatternCell => {
  return {
    note: null,
    jump: null,
    effectCode: null,
    effectParam: null,
  };
};
 
/** Creates a new empty subpattern with `TRACKER_SUBPATTERN_LENGTH` empty cells. */
export const createSubPattern = (): SubPatternCell[] => {
  return Array.from({ length: TRACKER_SUBPATTERN_LENGTH }).map(
    createSubPatternCell,
  );
};
 
/** Creates a new blank Song with default values and empty instrument/pattern lists. */
export const createSong = (): Song => {
  return {
    version: LAST_VERSION,
    name: "",
    artist: "",
    comment: "",
    filename: "song",
 
    dutyInstruments: [],
    waveInstruments: [],
    noiseInstruments: [],
    waves: [],
    ticksPerRow: 6,
 
    timerEnabled: false,
    timerDivider: 0,
 
    patterns: [],
    sequence: [],
  };
};
 
/** Appends a DutyInstrument to the song, setting its index to the current list length. */
export const addDutyInstrument = (song: Song, instrument: DutyInstrument) => {
  const list = song.dutyInstruments;
  instrument.index = list.length;
  list.push(instrument);
};
 
/** Appends a WaveInstrument to the song, setting its index to the current list length. */
export const addWaveInstrument = (song: Song, instrument: WaveInstrument) => {
  const list = song.waveInstruments;
  instrument.index = list.length;
  list.push(instrument);
};
 
/** Appends a NoiseInstrument to the song, setting its index to the current list length. */
export const addNoiseInstrument = (song: Song, instrument: NoiseInstrument) => {
  const list = song.noiseInstruments;
  instrument.index = list.length;
  list.push(instrument);
};