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 11198x                               98x     98x 9418x                 98x 112x             98x 4x 4x                       98x 9189x                 98x 94x           98x 55x                                           98x 318x 318x 318x       98x 316x 316x 316x       98x 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);
};