Files
ep-133-project-export/src/lib/utils.ts

99 lines
2.2 KiB
TypeScript

import { Pad, Sound } from '../types/types';
import { PAD_DISPLAY_FROM_INDEX } from './constants';
export function findPad(pad: string, pads: Record<string, Pad[]>) {
const group = pad[0];
const padNumber = parseInt(pad.slice(1), 10);
const padData = pads[group][padNumber];
return padData;
}
export function findSoundIdByPad(pad: string, pads: Record<string, Pad[]>) {
const padData = findPad(pad, pads);
if (!padData) {
return null;
}
if (padData.soundId === 0) {
return null;
}
return padData.soundId;
}
export function findSoundByPad(pad: string, pads: Record<string, Pad[]>, sounds: Sound[]) {
const soundId = findSoundIdByPad(pad, pads);
return sounds.find((s) => s.id === soundId) || null;
}
export function audioFormatAsBitDepth(s: string) {
switch (s) {
case 's16':
return 16;
case 's24':
return 24;
case 'float':
return 32;
default:
throw new Error('unknown bit depth');
}
}
export function calculateSoundLength(sound: Sound) {
const sampleRate = sound.meta?.samplerate;
const channels = sound.meta?.channels;
const fileSize = sound.fileNode?.fileSize;
if (!sampleRate || !channels || !fileSize) {
return 0;
}
return fileSize / 2 / sampleRate / channels;
}
export class AbortError extends Error {
constructor() {
super('The operation was aborted.');
this.name = 'AbortError';
}
}
export function getPadDisplayName(group: string, index: number): string {
const padChar = PAD_DISPLAY_FROM_INDEX[index] ?? '?';
return `${group.toUpperCase()} ${padChar}`;
}
export function hasMultipleNoteVariations(
group: string,
scenes: { patterns: { pad: string; notes: { note: number }[] }[] }[],
) {
const trackNotes: Record<string, Set<number>> = {};
for (const scene of scenes) {
for (const pattern of scene.patterns) {
if (!pattern.pad.startsWith(group)) {
continue;
}
if (!trackNotes[pattern.pad]) {
trackNotes[pattern.pad] = new Set();
}
for (const note of pattern.notes) {
trackNotes[pattern.pad].add(note.note);
}
}
}
for (const padCode in trackNotes) {
if (trackNotes[padCode].size > 1) {
return true;
}
}
return false;
}