43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import type { Command } from './types';
|
|
|
|
const MINUS = '\u2212';
|
|
|
|
export function fmtDb(level: number): string {
|
|
if (!(level > 0.0001)) return MINUS + '\u221e';
|
|
const db = 20 * Math.log10(level);
|
|
return (db >= 0 ? '+' : MINUS) + Math.abs(db).toFixed(1) + ' dB';
|
|
}
|
|
|
|
export function fmtTime(bar: number, bpm: number): string {
|
|
const seconds = Math.max(0, bar - 1) * 4 * (60 / Math.max(40, bpm));
|
|
const minutes = Math.floor(seconds / 60);
|
|
const rest = seconds - minutes * 60;
|
|
return String(minutes).padStart(2, '0') + ':' + rest.toFixed(1).padStart(4, '0');
|
|
}
|
|
|
|
export function fmtBar(bar: number): string {
|
|
return (Math.round(bar * 10) / 10).toFixed(1);
|
|
}
|
|
|
|
export function fmtTempo(bpm: number): string {
|
|
return Number.isInteger(bpm) ? String(bpm) : bpm.toFixed(1);
|
|
}
|
|
|
|
export function commandLabel(command: Command): string {
|
|
switch (command.type) {
|
|
case 'play': return 'play';
|
|
case 'stop': return 'stop';
|
|
case 'strike': return `strike ${command.vein} ${command.velocity.toFixed(2)}`;
|
|
case 'set_tempo': return `tempo ${fmtTempo(command.bpm)}`;
|
|
case 'set_vein_gain': return `${command.vein} gain ${command.gain.toFixed(2)}`;
|
|
case 'strike_face': return `strike ${command.core} f${command.face + 1}`;
|
|
case 'set_pattern_step': return `step ${command.row + 1}:${command.step + 1} at ${command.velocity}`;
|
|
case 'set_pattern_face': return `${command.core} f${command.face + 1} on row ${command.row + 1}`;
|
|
case 'get_snapshot': return 'snapshot';
|
|
}
|
|
}
|
|
|
|
export function eventLabel(event: { kind: string }): string {
|
|
return event.kind.replace('_', ' ');
|
|
}
|