55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
export type StrongPartial<T> = { [P in keyof T]?: T[P] | undefined };
|
|
|
|
/**
|
|
* get sign of number, including 0 and -0.
|
|
* true if positive, false if negative.
|
|
* Infinity and NaN return false.
|
|
*/
|
|
export function sign0(value: number) {
|
|
return 1 / value > 0;
|
|
}
|
|
|
|
/**
|
|
* get a number with the least decimal digits that when rounded to
|
|
* float32, will be the same as the value put in.
|
|
* this is only used for displaying samplerates and probably doesn't
|
|
* work outside of that one exact task.
|
|
*/
|
|
export function f32ToRound10(value: number): number {
|
|
// this is stupid but it works for numbers less
|
|
// than 10 digits on one side of the decimal point
|
|
const p7 = +value.toPrecision(7);
|
|
if (Math.fround(p7) === value) {
|
|
return p7;
|
|
}
|
|
const p8 = +value.toPrecision(8);
|
|
if (Math.fround(p8) === value) {
|
|
return p8;
|
|
}
|
|
return +value.toPrecision(9);
|
|
|
|
// for the range that sampleRate uses:
|
|
// 62677722 numbers needs precision 7
|
|
// 127630886 numbers needs precision 8
|
|
// 2629376 numbers needs precision 9
|
|
}
|
|
|
|
/**
|
|
* used to check if values from message passing are safe.
|
|
* can't detect proxies.
|
|
*/
|
|
export function isPlainObject(value: unknown): value is object {
|
|
if (typeof value === "object" && value) {
|
|
const proto = Object.getPrototypeOf(value);
|
|
return proto && !Object.getPrototypeOf(proto);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
export type SmallSongMode = "Signed Bytebeat" | "Floatbeat" | "Funcbeat";
|
|
export type SongMode = "Bytebeat" | SmallSongMode;
|
|
export type Song = {
|
|
code: string;
|
|
sampleRate: number;
|
|
mode: SongMode;
|
|
};
|