rockbox-ffi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -0
- package/dist/api.d.ts +64 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/bun.d.ts +52 -0
- package/dist/bun.d.ts.map +1 -0
- package/dist/bun.js +96 -0
- package/dist/bun.js.map +10 -0
- package/dist/chunk-ewj9g332.js +99 -0
- package/dist/chunk-ewj9g332.js.map +10 -0
- package/dist/chunk-raaa0pkf.js +215 -0
- package/dist/chunk-raaa0pkf.js.map +11 -0
- package/dist/deno.d.ts +52 -0
- package/dist/deno.d.ts.map +1 -0
- package/dist/deno.js +90 -0
- package/dist/deno.js.map +10 -0
- package/dist/enums.d.ts +35 -0
- package/dist/enums.d.ts.map +1 -0
- package/dist/ffi.d.ts +37 -0
- package/dist/ffi.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +10 -0
- package/dist/node.d.ts +52 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +88 -0
- package/dist/node.js.map +10 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +50 -0
- package/src/api.ts +221 -0
- package/src/bun.ts +95 -0
- package/src/deno.ts +83 -0
- package/src/enums.ts +44 -0
- package/src/ffi.ts +144 -0
- package/src/index.ts +37 -0
- package/src/node.ts +87 -0
- package/src/types.ts +80 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// src/enums.ts
|
|
5
|
+
var DspReplayGainMode = {
|
|
6
|
+
TRACK: 0,
|
|
7
|
+
ALBUM: 1,
|
|
8
|
+
SHUFFLE: 2,
|
|
9
|
+
OFF: 3
|
|
10
|
+
};
|
|
11
|
+
var ReplayGainMode = {
|
|
12
|
+
OFF: 0,
|
|
13
|
+
TRACK: 1,
|
|
14
|
+
ALBUM: 2
|
|
15
|
+
};
|
|
16
|
+
var CrossfadeMode = {
|
|
17
|
+
OFF: 0,
|
|
18
|
+
AUTO_SKIP: 1,
|
|
19
|
+
MANUAL_SKIP: 2,
|
|
20
|
+
SHUFFLE: 3,
|
|
21
|
+
SHUFFLE_OR_MANUAL: 4,
|
|
22
|
+
ALWAYS: 5
|
|
23
|
+
};
|
|
24
|
+
var MixMode = {
|
|
25
|
+
CROSSFADE: 0,
|
|
26
|
+
MIX: 1
|
|
27
|
+
};
|
|
28
|
+
var ChannelConfig = {
|
|
29
|
+
STEREO: 0,
|
|
30
|
+
MONO: 1,
|
|
31
|
+
CUSTOM: 2,
|
|
32
|
+
MONO_LEFT: 3,
|
|
33
|
+
MONO_RIGHT: 4,
|
|
34
|
+
KARAOKE: 5,
|
|
35
|
+
SWAP: 6
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/api.ts
|
|
39
|
+
var opt = (v) => v === null || v === undefined ? Number.NaN : v;
|
|
40
|
+
function makeApi(raw) {
|
|
41
|
+
const s = raw.sym;
|
|
42
|
+
const abiVersion = () => Number(s.rb_ffi_abi_version());
|
|
43
|
+
const metadata = {
|
|
44
|
+
read(path) {
|
|
45
|
+
const json = raw.takeString(s.rb_meta_read_json(raw.cstr(path)));
|
|
46
|
+
if (json === null)
|
|
47
|
+
throw new Error(`could not read metadata from ${path}`);
|
|
48
|
+
return JSON.parse(json);
|
|
49
|
+
},
|
|
50
|
+
probe(filename) {
|
|
51
|
+
return raw.takeString(s.rb_meta_probe(raw.cstr(filename)));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
class Dsp {
|
|
56
|
+
#h;
|
|
57
|
+
constructor(sampleRate) {
|
|
58
|
+
this.#h = s.rb_dsp_new(sampleRate);
|
|
59
|
+
if (raw.isNull(this.#h))
|
|
60
|
+
throw new Error("rb_dsp_new returned NULL");
|
|
61
|
+
}
|
|
62
|
+
close() {
|
|
63
|
+
if (!raw.isNull(this.#h)) {
|
|
64
|
+
s.rb_dsp_free(this.#h);
|
|
65
|
+
this.#h = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
[Symbol.dispose]() {
|
|
69
|
+
this.close();
|
|
70
|
+
}
|
|
71
|
+
setInputFrequency(hz) {
|
|
72
|
+
s.rb_dsp_set_input_frequency(this.#h, hz);
|
|
73
|
+
}
|
|
74
|
+
flush() {
|
|
75
|
+
s.rb_dsp_flush(this.#h);
|
|
76
|
+
}
|
|
77
|
+
eqEnable(enable) {
|
|
78
|
+
s.rb_dsp_eq_enable(this.#h, enable);
|
|
79
|
+
}
|
|
80
|
+
setEqBand(band, cutoffHz, q, gainDb) {
|
|
81
|
+
s.rb_dsp_set_eq_band(this.#h, band, cutoffHz, q, gainDb);
|
|
82
|
+
}
|
|
83
|
+
setEqPrecut(db) {
|
|
84
|
+
s.rb_dsp_set_eq_precut(this.#h, db);
|
|
85
|
+
}
|
|
86
|
+
setTone(bassDb, trebleDb) {
|
|
87
|
+
s.rb_dsp_set_tone(this.#h, bassDb, trebleDb);
|
|
88
|
+
}
|
|
89
|
+
setToneCutoffs(bassHz, trebleHz) {
|
|
90
|
+
s.rb_dsp_set_tone_cutoffs(this.#h, bassHz, trebleHz);
|
|
91
|
+
}
|
|
92
|
+
setSurround(delayMs, balance, fx1, fx2) {
|
|
93
|
+
s.rb_dsp_set_surround(this.#h, delayMs, balance, fx1, fx2);
|
|
94
|
+
}
|
|
95
|
+
setChannelConfig(mode) {
|
|
96
|
+
s.rb_dsp_set_channel_config(this.#h, mode);
|
|
97
|
+
}
|
|
98
|
+
setStereoWidth(percent) {
|
|
99
|
+
s.rb_dsp_set_stereo_width(this.#h, percent);
|
|
100
|
+
}
|
|
101
|
+
setCompressor(threshold, makeupGain, ratio, knee, releaseTime, attackTime) {
|
|
102
|
+
s.rb_dsp_set_compressor(this.#h, threshold, makeupGain, ratio, knee, releaseTime, attackTime);
|
|
103
|
+
}
|
|
104
|
+
setReplaygain(mode, noclip, preampDb) {
|
|
105
|
+
s.rb_dsp_set_replaygain(this.#h, mode, noclip, preampDb);
|
|
106
|
+
}
|
|
107
|
+
setReplaygainGains(trackGainDb, albumGainDb, trackPeak, albumPeak) {
|
|
108
|
+
s.rb_dsp_set_replaygain_gains(this.#h, opt(trackGainDb), opt(albumGainDb), opt(trackPeak), opt(albumPeak));
|
|
109
|
+
}
|
|
110
|
+
setReplaygainGainsRaw(trackGain, albumGain, trackPeak, albumPeak) {
|
|
111
|
+
s.rb_dsp_set_replaygain_gains_raw(this.#h, trackGain, albumGain, trackPeak, albumPeak);
|
|
112
|
+
}
|
|
113
|
+
process(samples) {
|
|
114
|
+
if (samples.length % 2 !== 0) {
|
|
115
|
+
throw new Error("input must be interleaved stereo (even length)");
|
|
116
|
+
}
|
|
117
|
+
const out = raw.sizeOut();
|
|
118
|
+
const ptr = s.rb_dsp_process(this.#h, raw.i16in(samples), samples.length, out.arg);
|
|
119
|
+
const n = out.value();
|
|
120
|
+
if (raw.isNull(ptr) || n === 0)
|
|
121
|
+
return new Int16Array(0);
|
|
122
|
+
return raw.takeI16(ptr, n);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
class Player {
|
|
127
|
+
#h;
|
|
128
|
+
constructor(config) {
|
|
129
|
+
if (config === undefined) {
|
|
130
|
+
this.#h = s.rb_player_new();
|
|
131
|
+
} else {
|
|
132
|
+
this.#h = s.rb_player_new_with_config(config.sampleRate ?? 0, config.bufferSeconds ?? 4, config.volume ?? 1, config.replaygainMode ?? ReplayGainMode.OFF, config.replaygainPreampDb ?? 0, config.replaygainPreventClipping ?? true, config.crossfadeMode ?? CrossfadeMode.OFF, config.fadeOutDelayMs ?? 0, config.fadeOutDurationMs ?? 2000, config.fadeInDelayMs ?? 0, config.fadeInDurationMs ?? 2000, config.mixMode ?? MixMode.CROSSFADE);
|
|
133
|
+
}
|
|
134
|
+
if (raw.isNull(this.#h)) {
|
|
135
|
+
throw new Error("failed to create Player (no output device?)");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
close() {
|
|
139
|
+
if (!raw.isNull(this.#h)) {
|
|
140
|
+
s.rb_player_free(this.#h);
|
|
141
|
+
this.#h = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
[Symbol.dispose]() {
|
|
145
|
+
this.close();
|
|
146
|
+
}
|
|
147
|
+
setQueue(paths) {
|
|
148
|
+
s.rb_player_set_queue_json(this.#h, raw.cstr(JSON.stringify(paths)));
|
|
149
|
+
}
|
|
150
|
+
enqueue(path) {
|
|
151
|
+
s.rb_player_enqueue(this.#h, raw.cstr(path));
|
|
152
|
+
}
|
|
153
|
+
play() {
|
|
154
|
+
s.rb_player_play(this.#h);
|
|
155
|
+
}
|
|
156
|
+
pause() {
|
|
157
|
+
s.rb_player_pause(this.#h);
|
|
158
|
+
}
|
|
159
|
+
toggle() {
|
|
160
|
+
s.rb_player_toggle(this.#h);
|
|
161
|
+
}
|
|
162
|
+
stop() {
|
|
163
|
+
s.rb_player_stop(this.#h);
|
|
164
|
+
}
|
|
165
|
+
next() {
|
|
166
|
+
s.rb_player_next(this.#h);
|
|
167
|
+
}
|
|
168
|
+
previous() {
|
|
169
|
+
s.rb_player_previous(this.#h);
|
|
170
|
+
}
|
|
171
|
+
skipTo(index) {
|
|
172
|
+
s.rb_player_skip_to(this.#h, index);
|
|
173
|
+
}
|
|
174
|
+
seekMs(ms) {
|
|
175
|
+
s.rb_player_seek_ms(this.#h, BigInt(ms));
|
|
176
|
+
}
|
|
177
|
+
setVolume(vol) {
|
|
178
|
+
s.rb_player_set_volume(this.#h, vol);
|
|
179
|
+
}
|
|
180
|
+
volume() {
|
|
181
|
+
return Number(s.rb_player_volume(this.#h));
|
|
182
|
+
}
|
|
183
|
+
sampleRate() {
|
|
184
|
+
return Number(s.rb_player_sample_rate(this.#h));
|
|
185
|
+
}
|
|
186
|
+
setCrossfade(mode, foDelayMs = 0, foDurMs = 2000, fiDelayMs = 0, fiDurMs = 2000, mixMode = MixMode.CROSSFADE) {
|
|
187
|
+
s.rb_player_set_crossfade(this.#h, mode, foDelayMs, foDurMs, fiDelayMs, fiDurMs, mixMode);
|
|
188
|
+
}
|
|
189
|
+
setReplaygain(mode, preampDb, preventClipping) {
|
|
190
|
+
s.rb_player_set_replaygain(this.#h, mode, preampDb, preventClipping);
|
|
191
|
+
}
|
|
192
|
+
status() {
|
|
193
|
+
const json = raw.takeString(s.rb_player_status_json(this.#h));
|
|
194
|
+
if (json === null)
|
|
195
|
+
throw new Error("rb_player_status_json returned NULL");
|
|
196
|
+
return JSON.parse(json);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return { abiVersion, metadata, Dsp, Player };
|
|
200
|
+
}
|
|
201
|
+
function sineStereo(freqHz, seconds, rate, amplitude = 16000) {
|
|
202
|
+
const n = Math.floor(seconds * rate);
|
|
203
|
+
const buf = new Int16Array(n * 2);
|
|
204
|
+
for (let i = 0;i < n; i++) {
|
|
205
|
+
let v = Math.round(Math.sin(i * 2 * Math.PI * freqHz / rate) * amplitude);
|
|
206
|
+
v = Math.max(-32768, Math.min(32767, v));
|
|
207
|
+
buf[i * 2] = v;
|
|
208
|
+
buf[i * 2 + 1] = v;
|
|
209
|
+
}
|
|
210
|
+
return buf;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export { __require, DspReplayGainMode, ReplayGainMode, CrossfadeMode, MixMode, ChannelConfig, makeApi, sineStereo };
|
|
214
|
+
|
|
215
|
+
//# debugId=6272FB156285E34764756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/enums.ts", "../src/api.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Enum constants for the Rockbox FFI.\n//\n// NOTE: the DSP and player use *different* ReplayGain mode integers (a quirk\n// of the underlying C ABI). Use DspReplayGainMode with `Dsp.setReplaygain`\n// and ReplayGainMode with `Player.setReplaygain`.\n\n/** For `Dsp.setReplaygain` (native Rockbox values). */\nexport const DspReplayGainMode = {\n TRACK: 0,\n ALBUM: 1,\n SHUFFLE: 2,\n OFF: 3,\n} as const;\n\n/** For `Player.setReplaygain`. */\nexport const ReplayGainMode = {\n OFF: 0,\n TRACK: 1,\n ALBUM: 2,\n} as const;\n\nexport const CrossfadeMode = {\n OFF: 0,\n AUTO_SKIP: 1,\n MANUAL_SKIP: 2,\n SHUFFLE: 3,\n SHUFFLE_OR_MANUAL: 4,\n ALWAYS: 5,\n} as const;\n\nexport const MixMode = {\n CROSSFADE: 0,\n MIX: 1,\n} as const;\n\nexport const ChannelConfig = {\n STEREO: 0,\n MONO: 1,\n CUSTOM: 2,\n MONO_LEFT: 3,\n MONO_RIGHT: 4,\n KARAOKE: 5,\n SWAP: 6,\n} as const;\n",
|
|
6
|
+
"// Runtime-agnostic high-level API, written once against the Raw backend.\n\nimport type { Raw } from \"./ffi.ts\";\nimport { CrossfadeMode, MixMode, ReplayGainMode } from \"./enums.ts\";\nimport type { Metadata, PlayerConfig, PlayerStatus } from \"./types.ts\";\n\nconst opt = (v: number | null | undefined): number =>\n v === null || v === undefined ? Number.NaN : v;\n\nexport function makeApi(raw: Raw) {\n const s = raw.sym;\n\n const abiVersion = (): number => Number(s.rb_ffi_abi_version());\n\n const metadata = {\n /** Parse the metadata of the audio file at `path`. */\n read(path: string): Metadata {\n const json = raw.takeString(s.rb_meta_read_json(raw.cstr(path)));\n if (json === null) throw new Error(`could not read metadata from ${path}`);\n return JSON.parse(json) as Metadata;\n },\n /** Guess the codec label from a filename's extension (null if unknown). */\n probe(filename: string): string | null {\n return raw.takeString(s.rb_meta_probe(raw.cstr(filename)));\n },\n };\n\n /** Interleaved-S16LE-stereo DSP instance. Single instance per process. */\n class Dsp {\n #h: unknown;\n constructor(sampleRate: number) {\n this.#h = s.rb_dsp_new(sampleRate);\n if (raw.isNull(this.#h)) throw new Error(\"rb_dsp_new returned NULL\");\n }\n close(): void {\n if (!raw.isNull(this.#h)) {\n s.rb_dsp_free(this.#h);\n this.#h = null;\n }\n }\n [Symbol.dispose](): void {\n this.close();\n }\n\n setInputFrequency(hz: number): void {\n s.rb_dsp_set_input_frequency(this.#h, hz);\n }\n flush(): void {\n s.rb_dsp_flush(this.#h);\n }\n eqEnable(enable: boolean): void {\n s.rb_dsp_eq_enable(this.#h, enable);\n }\n setEqBand(band: number, cutoffHz: number, q: number, gainDb: number): void {\n s.rb_dsp_set_eq_band(this.#h, band, cutoffHz, q, gainDb);\n }\n setEqPrecut(db: number): void {\n s.rb_dsp_set_eq_precut(this.#h, db);\n }\n setTone(bassDb: number, trebleDb: number): void {\n s.rb_dsp_set_tone(this.#h, bassDb, trebleDb);\n }\n setToneCutoffs(bassHz: number, trebleHz: number): void {\n s.rb_dsp_set_tone_cutoffs(this.#h, bassHz, trebleHz);\n }\n setSurround(delayMs: number, balance: number, fx1: number, fx2: number): void {\n s.rb_dsp_set_surround(this.#h, delayMs, balance, fx1, fx2);\n }\n setChannelConfig(mode: number): void {\n s.rb_dsp_set_channel_config(this.#h, mode);\n }\n setStereoWidth(percent: number): void {\n s.rb_dsp_set_stereo_width(this.#h, percent);\n }\n setCompressor(\n threshold: number, makeupGain: number, ratio: number, knee: number,\n releaseTime: number, attackTime: number,\n ): void {\n s.rb_dsp_set_compressor(this.#h, threshold, makeupGain, ratio, knee, releaseTime, attackTime);\n }\n /** mode: DspReplayGainMode (TRACK=0, ALBUM=1, SHUFFLE=2, OFF=3). */\n setReplaygain(mode: number, noclip: boolean, preampDb: number): void {\n s.rb_dsp_set_replaygain(this.#h, mode, noclip, preampDb);\n }\n /** Per-track gains in plain dB, peaks as linear amplitude. undefined => absent. */\n setReplaygainGains(\n trackGainDb?: number | null, albumGainDb?: number | null,\n trackPeak?: number | null, albumPeak?: number | null,\n ): void {\n s.rb_dsp_set_replaygain_gains(\n this.#h, opt(trackGainDb), opt(albumGainDb), opt(trackPeak), opt(albumPeak),\n );\n }\n /** Native Q7.24 factors (the `raw_*` metadata fields); use BigInt. */\n setReplaygainGainsRaw(\n trackGain: bigint, albumGain: bigint, trackPeak: bigint, albumPeak: bigint,\n ): void {\n s.rb_dsp_set_replaygain_gains_raw(this.#h, trackGain, albumGain, trackPeak, albumPeak);\n }\n /** Run interleaved stereo S16 samples through the pipeline. */\n process(samples: Int16Array): Int16Array {\n if (samples.length % 2 !== 0) {\n throw new Error(\"input must be interleaved stereo (even length)\");\n }\n const out = raw.sizeOut();\n const ptr = s.rb_dsp_process(this.#h, raw.i16in(samples), samples.length, out.arg);\n const n = out.value();\n if (raw.isNull(ptr) || n === 0) return new Int16Array(0);\n return raw.takeI16(ptr, n);\n }\n }\n\n /** Queue-based player. Owns a live output device + engine thread. */\n class Player {\n #h: unknown;\n constructor(config?: PlayerConfig) {\n if (config === undefined) {\n this.#h = s.rb_player_new();\n } else {\n this.#h = s.rb_player_new_with_config(\n config.sampleRate ?? 0,\n config.bufferSeconds ?? 4.0,\n config.volume ?? 1.0,\n config.replaygainMode ?? ReplayGainMode.OFF,\n config.replaygainPreampDb ?? 0.0,\n config.replaygainPreventClipping ?? true,\n config.crossfadeMode ?? CrossfadeMode.OFF,\n config.fadeOutDelayMs ?? 0,\n config.fadeOutDurationMs ?? 2000,\n config.fadeInDelayMs ?? 0,\n config.fadeInDurationMs ?? 2000,\n config.mixMode ?? MixMode.CROSSFADE,\n );\n }\n if (raw.isNull(this.#h)) {\n throw new Error(\"failed to create Player (no output device?)\");\n }\n }\n close(): void {\n if (!raw.isNull(this.#h)) {\n s.rb_player_free(this.#h);\n this.#h = null;\n }\n }\n [Symbol.dispose](): void {\n this.close();\n }\n\n setQueue(paths: string[]): void {\n s.rb_player_set_queue_json(this.#h, raw.cstr(JSON.stringify(paths)));\n }\n enqueue(path: string): void {\n s.rb_player_enqueue(this.#h, raw.cstr(path));\n }\n play(): void {\n s.rb_player_play(this.#h);\n }\n pause(): void {\n s.rb_player_pause(this.#h);\n }\n toggle(): void {\n s.rb_player_toggle(this.#h);\n }\n stop(): void {\n s.rb_player_stop(this.#h);\n }\n next(): void {\n s.rb_player_next(this.#h);\n }\n previous(): void {\n s.rb_player_previous(this.#h);\n }\n skipTo(index: number): void {\n s.rb_player_skip_to(this.#h, index);\n }\n seekMs(ms: number | bigint): void {\n s.rb_player_seek_ms(this.#h, BigInt(ms));\n }\n setVolume(vol: number): void {\n s.rb_player_set_volume(this.#h, vol);\n }\n volume(): number {\n return Number(s.rb_player_volume(this.#h));\n }\n sampleRate(): number {\n return Number(s.rb_player_sample_rate(this.#h));\n }\n setCrossfade(\n mode: number, foDelayMs = 0, foDurMs = 2000, fiDelayMs = 0, fiDurMs = 2000,\n mixMode = MixMode.CROSSFADE,\n ): void {\n s.rb_player_set_crossfade(this.#h, mode, foDelayMs, foDurMs, fiDelayMs, fiDurMs, mixMode);\n }\n /** mode: ReplayGainMode (OFF=0, TRACK=1, ALBUM=2). */\n setReplaygain(mode: number, preampDb: number, preventClipping: boolean): void {\n s.rb_player_set_replaygain(this.#h, mode, preampDb, preventClipping);\n }\n status(): PlayerStatus {\n const json = raw.takeString(s.rb_player_status_json(this.#h));\n if (json === null) throw new Error(\"rb_player_status_json returned NULL\");\n return JSON.parse(json) as PlayerStatus;\n }\n }\n\n return { abiVersion, metadata, Dsp, Player };\n}\n\n/** Generate `seconds` of a sine as interleaved stereo Int16. */\nexport function sineStereo(\n freqHz: number, seconds: number, rate: number, amplitude = 16000,\n): Int16Array {\n const n = Math.floor(seconds * rate);\n const buf = new Int16Array(n * 2);\n for (let i = 0; i < n; i++) {\n let v = Math.round(Math.sin((i * 2 * Math.PI * freqHz) / rate) * amplitude);\n v = Math.max(-32768, Math.min(32767, v));\n buf[i * 2] = v;\n buf[i * 2 + 1] = v;\n }\n return buf;\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "6272FB156285E34764756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/dist/deno.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sineStereo } from "./api.ts";
|
|
2
|
+
export declare const abiVersion: () => number, metadata: {
|
|
3
|
+
read(path: string): import("./types.ts").Metadata;
|
|
4
|
+
probe(filename: string): string | null;
|
|
5
|
+
}, Dsp: {
|
|
6
|
+
new (sampleRate: number): {
|
|
7
|
+
"__#private@#h": unknown;
|
|
8
|
+
close(): void;
|
|
9
|
+
setInputFrequency(hz: number): void;
|
|
10
|
+
flush(): void;
|
|
11
|
+
eqEnable(enable: boolean): void;
|
|
12
|
+
setEqBand(band: number, cutoffHz: number, q: number, gainDb: number): void;
|
|
13
|
+
setEqPrecut(db: number): void;
|
|
14
|
+
setTone(bassDb: number, trebleDb: number): void;
|
|
15
|
+
setToneCutoffs(bassHz: number, trebleHz: number): void;
|
|
16
|
+
setSurround(delayMs: number, balance: number, fx1: number, fx2: number): void;
|
|
17
|
+
setChannelConfig(mode: number): void;
|
|
18
|
+
setStereoWidth(percent: number): void;
|
|
19
|
+
setCompressor(threshold: number, makeupGain: number, ratio: number, knee: number, releaseTime: number, attackTime: number): void;
|
|
20
|
+
setReplaygain(mode: number, noclip: boolean, preampDb: number): void;
|
|
21
|
+
setReplaygainGains(trackGainDb?: number | null, albumGainDb?: number | null, trackPeak?: number | null, albumPeak?: number | null): void;
|
|
22
|
+
setReplaygainGainsRaw(trackGain: bigint, albumGain: bigint, trackPeak: bigint, albumPeak: bigint): void;
|
|
23
|
+
process(samples: Int16Array): Int16Array;
|
|
24
|
+
[Symbol.dispose](): void;
|
|
25
|
+
};
|
|
26
|
+
}, Player: {
|
|
27
|
+
new (config?: import("./types.ts").PlayerConfig): {
|
|
28
|
+
"__#private@#h": unknown;
|
|
29
|
+
close(): void;
|
|
30
|
+
setQueue(paths: string[]): void;
|
|
31
|
+
enqueue(path: string): void;
|
|
32
|
+
play(): void;
|
|
33
|
+
pause(): void;
|
|
34
|
+
toggle(): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
next(): void;
|
|
37
|
+
previous(): void;
|
|
38
|
+
skipTo(index: number): void;
|
|
39
|
+
seekMs(ms: number | bigint): void;
|
|
40
|
+
setVolume(vol: number): void;
|
|
41
|
+
volume(): number;
|
|
42
|
+
sampleRate(): number;
|
|
43
|
+
setCrossfade(mode: number, foDelayMs?: number, foDurMs?: number, fiDelayMs?: number, fiDurMs?: number, mixMode?: 0): void;
|
|
44
|
+
setReplaygain(mode: number, preampDb: number, preventClipping: boolean): void;
|
|
45
|
+
status(): import("./types.ts").PlayerStatus;
|
|
46
|
+
[Symbol.dispose](): void;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export { sineStereo };
|
|
50
|
+
export * from "./enums.ts";
|
|
51
|
+
export type { Metadata, PlayerConfig, PlayerStatus } from "./types.ts";
|
|
52
|
+
//# sourceMappingURL=deno.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deno.d.ts","sourceRoot":"","sources":["../src/deno.ts"],"names":[],"mappings":"AAOA,OAAO,EAAW,UAAU,EAAE,MAAM,UAAU,CAAC;AAwE/C,eAAO,MAAQ,UAAU,gBAAE,QAAQ;;;GAAE,GAAG;;;;;;;;;;;;;;;;;;;;;GAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;CAAQ,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/deno.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SPEC,
|
|
3
|
+
resolveLibPath
|
|
4
|
+
} from "./chunk-ewj9g332.js";
|
|
5
|
+
import {
|
|
6
|
+
ChannelConfig,
|
|
7
|
+
CrossfadeMode,
|
|
8
|
+
DspReplayGainMode,
|
|
9
|
+
MixMode,
|
|
10
|
+
ReplayGainMode,
|
|
11
|
+
makeApi,
|
|
12
|
+
sineStereo
|
|
13
|
+
} from "./chunk-raaa0pkf.js";
|
|
14
|
+
|
|
15
|
+
// src/deno.ts
|
|
16
|
+
import { existsSync } from "node:fs";
|
|
17
|
+
import { dirname, join } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
var D = globalThis.Deno;
|
|
20
|
+
var TOK = {
|
|
21
|
+
void: "void",
|
|
22
|
+
ptr: "pointer",
|
|
23
|
+
u32: "u32",
|
|
24
|
+
i32: "i32",
|
|
25
|
+
u64: "u64",
|
|
26
|
+
usize: "usize",
|
|
27
|
+
f32: "f32",
|
|
28
|
+
bool: "bool",
|
|
29
|
+
strbuf: "buffer",
|
|
30
|
+
i16in: "buffer",
|
|
31
|
+
outsize: "buffer"
|
|
32
|
+
};
|
|
33
|
+
function makeRaw() {
|
|
34
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
const libPath = resolveLibPath(here, (k) => D.env.get(k), existsSync, join, dirname);
|
|
36
|
+
const defs = {};
|
|
37
|
+
for (const [name, spec] of Object.entries(SPEC)) {
|
|
38
|
+
defs[name] = { parameters: spec.args.map((t) => TOK[t]), result: TOK[spec.ret] };
|
|
39
|
+
}
|
|
40
|
+
const lib = D.dlopen(libPath, defs);
|
|
41
|
+
const sym = lib.symbols;
|
|
42
|
+
const enc = new TextEncoder;
|
|
43
|
+
return {
|
|
44
|
+
sym,
|
|
45
|
+
cstr(s) {
|
|
46
|
+
return enc.encode(s + "\x00");
|
|
47
|
+
},
|
|
48
|
+
i16in(a) {
|
|
49
|
+
return a;
|
|
50
|
+
},
|
|
51
|
+
sizeOut() {
|
|
52
|
+
const buf = new Uint8Array(8);
|
|
53
|
+
const view = new DataView(buf.buffer);
|
|
54
|
+
return { arg: buf, value: () => Number(view.getBigUint64(0, true)) };
|
|
55
|
+
},
|
|
56
|
+
takeString(p) {
|
|
57
|
+
if (p === null)
|
|
58
|
+
return null;
|
|
59
|
+
const str = new D.UnsafePointerView(p).getCString();
|
|
60
|
+
sym.rb_string_free(p);
|
|
61
|
+
return str;
|
|
62
|
+
},
|
|
63
|
+
takeI16(p, len) {
|
|
64
|
+
const ab = new D.UnsafePointerView(p).getArrayBuffer(len * 2);
|
|
65
|
+
const copy = new Int16Array(len);
|
|
66
|
+
copy.set(new Int16Array(ab));
|
|
67
|
+
sym.rb_buffer_free(p, len);
|
|
68
|
+
return copy;
|
|
69
|
+
},
|
|
70
|
+
isNull(p) {
|
|
71
|
+
return p === null || p === undefined;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
var api = makeApi(makeRaw());
|
|
76
|
+
var { abiVersion, metadata, Dsp, Player } = api;
|
|
77
|
+
export {
|
|
78
|
+
sineStereo,
|
|
79
|
+
metadata,
|
|
80
|
+
abiVersion,
|
|
81
|
+
ReplayGainMode,
|
|
82
|
+
Player,
|
|
83
|
+
MixMode,
|
|
84
|
+
DspReplayGainMode,
|
|
85
|
+
Dsp,
|
|
86
|
+
CrossfadeMode,
|
|
87
|
+
ChannelConfig
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
//# debugId=373B14C256C3D42D64756E2164756E21
|
package/dist/deno.js.map
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/deno.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Deno backend + full API. Import from here under Deno:\n// import { Dsp, Player, metadata } from \"./src/deno.ts\";\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { makeApi, sineStereo } from \"./api.ts\";\nimport { resolveLibPath, SPEC, type Raw, type Tok } from \"./ffi.ts\";\n\n// deno-lint-ignore no-explicit-any\nconst D = (globalThis as any).Deno;\n\nconst TOK: Record<Tok, string> = {\n void: \"void\",\n ptr: \"pointer\",\n u32: \"u32\",\n i32: \"i32\",\n u64: \"u64\",\n usize: \"usize\",\n f32: \"f32\",\n bool: \"bool\",\n strbuf: \"buffer\",\n i16in: \"buffer\",\n outsize: \"buffer\",\n};\n\nfunction makeRaw(): Raw {\n const here = dirname(fileURLToPath(import.meta.url));\n const libPath = resolveLibPath(\n here,\n (k) => D.env.get(k),\n existsSync,\n join,\n dirname,\n );\n\n const defs: Record<string, { parameters: string[]; result: string }> = {};\n for (const [name, spec] of Object.entries(SPEC)) {\n defs[name] = { parameters: spec.args.map((t) => TOK[t]), result: TOK[spec.ret] };\n }\n const lib = D.dlopen(libPath, defs);\n const sym = lib.symbols as Record<string, (...a: any[]) => any>;\n\n const enc = new TextEncoder();\n\n return {\n sym,\n cstr(s: string) {\n return enc.encode(s + \"\\0\");\n },\n i16in(a: Int16Array) {\n return a;\n },\n sizeOut() {\n const buf = new Uint8Array(8);\n const view = new DataView(buf.buffer);\n return { arg: buf, value: () => Number(view.getBigUint64(0, true)) };\n },\n takeString(p: unknown) {\n if (p === null) return null;\n const str = new D.UnsafePointerView(p).getCString();\n sym.rb_string_free(p);\n return str;\n },\n takeI16(p: unknown, len: number) {\n const ab = new D.UnsafePointerView(p).getArrayBuffer(len * 2);\n const copy = new Int16Array(len);\n copy.set(new Int16Array(ab));\n sym.rb_buffer_free(p, len);\n return copy;\n },\n isNull(p: unknown) {\n return p === null || p === undefined;\n },\n };\n}\n\nconst api = makeApi(makeRaw());\nexport const { abiVersion, metadata, Dsp, Player } = api;\nexport { sineStereo };\nexport * from \"./enums.ts\";\nexport type { Metadata, PlayerConfig, PlayerStatus } from \"./types.ts\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;AAGA;AACA;AACA;AAMA,IAAM,IAAK,WAAmB;AAE9B,IAAM,MAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEA,SAAS,OAAO,GAAQ;AAAA,EACtB,MAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EACnD,MAAM,UAAU,eACd,MACA,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,GAClB,YACA,MACA,OACF;AAAA,EAEA,MAAM,OAAiE,CAAC;AAAA,EACxE,YAAY,MAAM,SAAS,OAAO,QAAQ,IAAI,GAAG;AAAA,IAC/C,KAAK,QAAQ,EAAE,YAAY,KAAK,KAAK,IAAI,CAAC,MAAM,IAAI,EAAE,GAAG,QAAQ,IAAI,KAAK,KAAK;AAAA,EACjF;AAAA,EACA,MAAM,MAAM,EAAE,OAAO,SAAS,IAAI;AAAA,EAClC,MAAM,MAAM,IAAI;AAAA,EAEhB,MAAM,MAAM,IAAI;AAAA,EAEhB,OAAO;AAAA,IACL;AAAA,IACA,IAAI,CAAC,GAAW;AAAA,MACd,OAAO,IAAI,OAAO,IAAI,MAAI;AAAA;AAAA,IAE5B,KAAK,CAAC,GAAe;AAAA,MACnB,OAAO;AAAA;AAAA,IAET,OAAO,GAAG;AAAA,MACR,MAAM,MAAM,IAAI,WAAW,CAAC;AAAA,MAC5B,MAAM,OAAO,IAAI,SAAS,IAAI,MAAM;AAAA,MACpC,OAAO,EAAE,KAAK,KAAK,OAAO,MAAM,OAAO,KAAK,aAAa,GAAG,IAAI,CAAC,EAAE;AAAA;AAAA,IAErE,UAAU,CAAC,GAAY;AAAA,MACrB,IAAI,MAAM;AAAA,QAAM,OAAO;AAAA,MACvB,MAAM,MAAM,IAAI,EAAE,kBAAkB,CAAC,EAAE,WAAW;AAAA,MAClD,IAAI,eAAe,CAAC;AAAA,MACpB,OAAO;AAAA;AAAA,IAET,OAAO,CAAC,GAAY,KAAa;AAAA,MAC/B,MAAM,KAAK,IAAI,EAAE,kBAAkB,CAAC,EAAE,eAAe,MAAM,CAAC;AAAA,MAC5D,MAAM,OAAO,IAAI,WAAW,GAAG;AAAA,MAC/B,KAAK,IAAI,IAAI,WAAW,EAAE,CAAC;AAAA,MAC3B,IAAI,eAAe,GAAG,GAAG;AAAA,MACzB,OAAO;AAAA;AAAA,IAET,MAAM,CAAC,GAAY;AAAA,MACjB,OAAO,MAAM,QAAQ,MAAM;AAAA;AAAA,EAE/B;AAAA;AAGF,IAAM,MAAM,QAAQ,QAAQ,CAAC;AACtB,MAAQ,YAAY,UAAU,KAAK,WAAW;",
|
|
8
|
+
"debugId": "373B14C256C3D42D64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/enums.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** For `Dsp.setReplaygain` (native Rockbox values). */
|
|
2
|
+
export declare const DspReplayGainMode: {
|
|
3
|
+
readonly TRACK: 0;
|
|
4
|
+
readonly ALBUM: 1;
|
|
5
|
+
readonly SHUFFLE: 2;
|
|
6
|
+
readonly OFF: 3;
|
|
7
|
+
};
|
|
8
|
+
/** For `Player.setReplaygain`. */
|
|
9
|
+
export declare const ReplayGainMode: {
|
|
10
|
+
readonly OFF: 0;
|
|
11
|
+
readonly TRACK: 1;
|
|
12
|
+
readonly ALBUM: 2;
|
|
13
|
+
};
|
|
14
|
+
export declare const CrossfadeMode: {
|
|
15
|
+
readonly OFF: 0;
|
|
16
|
+
readonly AUTO_SKIP: 1;
|
|
17
|
+
readonly MANUAL_SKIP: 2;
|
|
18
|
+
readonly SHUFFLE: 3;
|
|
19
|
+
readonly SHUFFLE_OR_MANUAL: 4;
|
|
20
|
+
readonly ALWAYS: 5;
|
|
21
|
+
};
|
|
22
|
+
export declare const MixMode: {
|
|
23
|
+
readonly CROSSFADE: 0;
|
|
24
|
+
readonly MIX: 1;
|
|
25
|
+
};
|
|
26
|
+
export declare const ChannelConfig: {
|
|
27
|
+
readonly STEREO: 0;
|
|
28
|
+
readonly MONO: 1;
|
|
29
|
+
readonly CUSTOM: 2;
|
|
30
|
+
readonly MONO_LEFT: 3;
|
|
31
|
+
readonly MONO_RIGHT: 4;
|
|
32
|
+
readonly KARAOKE: 5;
|
|
33
|
+
readonly SWAP: 6;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=enums.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAMA,uDAAuD;AACvD,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC;AAEX,kCAAkC;AAClC,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;CAOhB,CAAC;AAEX,eAAO,MAAM,OAAO;;;CAGV,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;CAQhB,CAAC"}
|
package/dist/ffi.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Abstract argument/return type tokens used by the symbol spec. */
|
|
2
|
+
export type Tok = "void" | "ptr" | "u32" | "i32" | "u64" | "usize" | "f32" | "bool" | "strbuf" | "i16in" | "outsize";
|
|
3
|
+
export interface SymSpec {
|
|
4
|
+
args: Tok[];
|
|
5
|
+
ret: Tok;
|
|
6
|
+
}
|
|
7
|
+
export declare const SPEC: Record<string, SymSpec>;
|
|
8
|
+
/**
|
|
9
|
+
* The low-level backend a runtime loader must provide. High-level classes in
|
|
10
|
+
* api.ts are written once against this interface.
|
|
11
|
+
*/
|
|
12
|
+
export interface Raw {
|
|
13
|
+
/** The dlopen'd symbol table; call e.g. `sym.rb_dsp_new(44100)`. */
|
|
14
|
+
sym: Record<string, (...a: any[]) => any>;
|
|
15
|
+
/** Marshal a JS string as a `const char *` argument. */
|
|
16
|
+
cstr(s: string): unknown;
|
|
17
|
+
/** Marshal an Int16Array as a `const int16_t *` argument. */
|
|
18
|
+
i16in(a: Int16Array): unknown;
|
|
19
|
+
/** Allocate a `size_t` out-parameter; `value()` reads it after the call. */
|
|
20
|
+
sizeOut(): {
|
|
21
|
+
arg: unknown;
|
|
22
|
+
value(): number;
|
|
23
|
+
};
|
|
24
|
+
/** Read a returned `char *` into a string and free it (null => null). */
|
|
25
|
+
takeString(p: unknown): string | null;
|
|
26
|
+
/** Read a returned `int16_t *` of `len` samples into a copy and free it. */
|
|
27
|
+
takeI16(p: unknown, len: number): Int16Array;
|
|
28
|
+
/** True if a returned handle/pointer is NULL. */
|
|
29
|
+
isNull(p: unknown): boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Locate the shared library: `ROCKBOX_FFI_LIB` env var first, then by walking
|
|
33
|
+
* up from `startDir` to a `target/release` directory. `exists` and the path
|
|
34
|
+
* ops are injected so this works under both Bun and Deno.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveLibPath(startDir: string, env: (k: string) => string | undefined, exists: (p: string) => boolean, join: (...p: string[]) => string, dirname: (p: string) => string): string;
|
|
37
|
+
//# sourceMappingURL=ffi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ffi.d.ts","sourceRoot":"","sources":["../src/ffi.ts"],"names":[],"mappings":"AAGA,oEAAoE;AACpE,MAAM,MAAM,GAAG,GACX,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,OAAO,GACP,KAAK,GACL,MAAM,GACN,QAAQ,GACR,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,GAAG,EAAE,GAAG,CAAC;CACV;AAGD,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA+DxC,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC;IAC1C,wDAAwD;IACxD,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,6DAA6D;IAC7D,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,IAAI;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,KAAK,IAAI,MAAM,CAAA;KAAE,CAAC;IAC7C,yEAAyE;IACzE,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACtC,4EAA4E;IAC5E,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7C,iDAAiD;IACjD,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,EAC9B,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM,EAChC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAC7B,MAAM,CAqBR"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { makeApi } from "./api.ts";
|
|
2
|
+
export * from "./enums.ts";
|
|
3
|
+
export { sineStereo } from "./api.ts";
|
|
4
|
+
export type { Metadata, PlayerConfig, PlayerStatus } from "./types.ts";
|
|
5
|
+
type Api = ReturnType<typeof makeApi>;
|
|
6
|
+
/**
|
|
7
|
+
* Load the binding for the current runtime (Bun or Deno). Uses a dynamic
|
|
8
|
+
* import so the other runtime's FFI module is never parsed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function load(): Promise<Api>;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEvE,KAAK,GAAG,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAItC;;;GAGG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAgBzC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChannelConfig,
|
|
3
|
+
CrossfadeMode,
|
|
4
|
+
DspReplayGainMode,
|
|
5
|
+
MixMode,
|
|
6
|
+
ReplayGainMode,
|
|
7
|
+
__require,
|
|
8
|
+
sineStereo
|
|
9
|
+
} from "./chunk-raaa0pkf.js";
|
|
10
|
+
|
|
11
|
+
// src/index.ts
|
|
12
|
+
var cached;
|
|
13
|
+
async function load() {
|
|
14
|
+
if (cached)
|
|
15
|
+
return cached;
|
|
16
|
+
const g = globalThis;
|
|
17
|
+
let mod;
|
|
18
|
+
if (typeof g.Bun !== "undefined") {
|
|
19
|
+
mod = await import("./bun.js");
|
|
20
|
+
} else if (typeof g.Deno !== "undefined") {
|
|
21
|
+
mod = await import("./deno.js");
|
|
22
|
+
} else if (typeof g.process !== "undefined" && g.process.versions?.node) {
|
|
23
|
+
mod = await import("./node.js");
|
|
24
|
+
} else {
|
|
25
|
+
throw new Error("unsupported runtime: need Bun, Deno, or Node.js");
|
|
26
|
+
}
|
|
27
|
+
cached = { abiVersion: mod.abiVersion, metadata: mod.metadata, Dsp: mod.Dsp, Player: mod.Player };
|
|
28
|
+
return cached;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
sineStereo,
|
|
32
|
+
load,
|
|
33
|
+
ReplayGainMode,
|
|
34
|
+
MixMode,
|
|
35
|
+
DspReplayGainMode,
|
|
36
|
+
CrossfadeMode,
|
|
37
|
+
ChannelConfig
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//# debugId=2E576C7A1A0B797464756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Runtime auto-detecting entry point.\n//\n// Prefer importing the runtime-specific module directly (`rockbox-ffi/bun` or\n// `./src/deno.ts`) — those load synchronously. This helper exists for code\n// that wants a single import and can await initialization.\n\nimport type { makeApi } from \"./api.ts\";\n\nexport * from \"./enums.ts\";\nexport { sineStereo } from \"./api.ts\";\nexport type { Metadata, PlayerConfig, PlayerStatus } from \"./types.ts\";\n\ntype Api = ReturnType<typeof makeApi>;\n\nlet cached: Api | undefined;\n\n/**\n * Load the binding for the current runtime (Bun or Deno). Uses a dynamic\n * import so the other runtime's FFI module is never parsed.\n */\nexport async function load(): Promise<Api> {\n if (cached) return cached;\n // deno-lint-ignore no-explicit-any\n const g = globalThis as any;\n let mod: { abiVersion: Api[\"abiVersion\"]; metadata: Api[\"metadata\"]; Dsp: Api[\"Dsp\"]; Player: Api[\"Player\"] };\n if (typeof g.Bun !== \"undefined\") {\n mod = await import(\"./bun.ts\");\n } else if (typeof g.Deno !== \"undefined\") {\n mod = await import(\"./deno.ts\");\n } else if (typeof g.process !== \"undefined\" && g.process.versions?.node) {\n mod = await import(\"./node.ts\");\n } else {\n throw new Error(\"unsupported runtime: need Bun, Deno, or Node.js\");\n }\n cached = { abiVersion: mod.abiVersion, metadata: mod.metadata, Dsp: mod.Dsp, Player: mod.Player };\n return cached;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;AAcA,IAAI;AAMJ,eAAsB,IAAI,GAAiB;AAAA,EACzC,IAAI;AAAA,IAAQ,OAAO;AAAA,EAEnB,MAAM,IAAI;AAAA,EACV,IAAI;AAAA,EACJ,IAAI,OAAO,EAAE,QAAQ,aAAa;AAAA,IAChC,MAAM,MAAa;AAAA,EACrB,EAAO,SAAI,OAAO,EAAE,SAAS,aAAa;AAAA,IACxC,MAAM,MAAa;AAAA,EACrB,EAAO,SAAI,OAAO,EAAE,YAAY,eAAe,EAAE,QAAQ,UAAU,MAAM;AAAA,IACvE,MAAM,MAAa;AAAA,EACrB,EAAO;AAAA,IACL,MAAM,IAAI,MAAM,iDAAiD;AAAA;AAAA,EAEnE,SAAS,EAAE,YAAY,IAAI,YAAY,UAAU,IAAI,UAAU,KAAK,IAAI,KAAK,QAAQ,IAAI,OAAO;AAAA,EAChG,OAAO;AAAA;",
|
|
8
|
+
"debugId": "2E576C7A1A0B797464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sineStereo } from "./api.ts";
|
|
2
|
+
export declare const abiVersion: () => number, metadata: {
|
|
3
|
+
read(path: string): import("./types.ts").Metadata;
|
|
4
|
+
probe(filename: string): string | null;
|
|
5
|
+
}, Dsp: {
|
|
6
|
+
new (sampleRate: number): {
|
|
7
|
+
"__#private@#h": unknown;
|
|
8
|
+
close(): void;
|
|
9
|
+
setInputFrequency(hz: number): void;
|
|
10
|
+
flush(): void;
|
|
11
|
+
eqEnable(enable: boolean): void;
|
|
12
|
+
setEqBand(band: number, cutoffHz: number, q: number, gainDb: number): void;
|
|
13
|
+
setEqPrecut(db: number): void;
|
|
14
|
+
setTone(bassDb: number, trebleDb: number): void;
|
|
15
|
+
setToneCutoffs(bassHz: number, trebleHz: number): void;
|
|
16
|
+
setSurround(delayMs: number, balance: number, fx1: number, fx2: number): void;
|
|
17
|
+
setChannelConfig(mode: number): void;
|
|
18
|
+
setStereoWidth(percent: number): void;
|
|
19
|
+
setCompressor(threshold: number, makeupGain: number, ratio: number, knee: number, releaseTime: number, attackTime: number): void;
|
|
20
|
+
setReplaygain(mode: number, noclip: boolean, preampDb: number): void;
|
|
21
|
+
setReplaygainGains(trackGainDb?: number | null, albumGainDb?: number | null, trackPeak?: number | null, albumPeak?: number | null): void;
|
|
22
|
+
setReplaygainGainsRaw(trackGain: bigint, albumGain: bigint, trackPeak: bigint, albumPeak: bigint): void;
|
|
23
|
+
process(samples: Int16Array): Int16Array;
|
|
24
|
+
[Symbol.dispose](): void;
|
|
25
|
+
};
|
|
26
|
+
}, Player: {
|
|
27
|
+
new (config?: import("./types.ts").PlayerConfig): {
|
|
28
|
+
"__#private@#h": unknown;
|
|
29
|
+
close(): void;
|
|
30
|
+
setQueue(paths: string[]): void;
|
|
31
|
+
enqueue(path: string): void;
|
|
32
|
+
play(): void;
|
|
33
|
+
pause(): void;
|
|
34
|
+
toggle(): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
next(): void;
|
|
37
|
+
previous(): void;
|
|
38
|
+
skipTo(index: number): void;
|
|
39
|
+
seekMs(ms: number | bigint): void;
|
|
40
|
+
setVolume(vol: number): void;
|
|
41
|
+
volume(): number;
|
|
42
|
+
sampleRate(): number;
|
|
43
|
+
setCrossfade(mode: number, foDelayMs?: number, foDurMs?: number, fiDelayMs?: number, fiDurMs?: number, mixMode?: 0): void;
|
|
44
|
+
setReplaygain(mode: number, preampDb: number, preventClipping: boolean): void;
|
|
45
|
+
status(): import("./types.ts").PlayerStatus;
|
|
46
|
+
[Symbol.dispose](): void;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export { sineStereo };
|
|
50
|
+
export * from "./enums.ts";
|
|
51
|
+
export type { Metadata, PlayerConfig, PlayerStatus } from "./types.ts";
|
|
52
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAWA,OAAO,EAAW,UAAU,EAAE,MAAM,UAAU,CAAC;AAwE/C,eAAO,MAAQ,UAAU,gBAAE,QAAQ;;;GAAE,GAAG;;;;;;;;;;;;;;;;;;;;;GAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;CAAQ,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|