@al8b/audio 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.
Files changed (56) hide show
  1. package/README.md +23 -0
  2. package/dist/constants.d.mts +8 -0
  3. package/dist/constants.d.ts +8 -0
  4. package/dist/constants.js +37 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/constants.mjs +10 -0
  7. package/dist/constants.mjs.map +1 -0
  8. package/dist/core/audio-core.d.mts +98 -0
  9. package/dist/core/audio-core.d.ts +98 -0
  10. package/dist/core/audio-core.js +664 -0
  11. package/dist/core/audio-core.js.map +1 -0
  12. package/dist/core/audio-core.mjs +641 -0
  13. package/dist/core/audio-core.mjs.map +1 -0
  14. package/dist/core/audio-worklet.d.mts +3 -0
  15. package/dist/core/audio-worklet.d.ts +3 -0
  16. package/dist/core/audio-worklet.js +153 -0
  17. package/dist/core/audio-worklet.js.map +1 -0
  18. package/dist/core/audio-worklet.mjs +128 -0
  19. package/dist/core/audio-worklet.mjs.map +1 -0
  20. package/dist/core/index.d.mts +2 -0
  21. package/dist/core/index.d.ts +2 -0
  22. package/dist/core/index.js +666 -0
  23. package/dist/core/index.js.map +1 -0
  24. package/dist/core/index.mjs +641 -0
  25. package/dist/core/index.mjs.map +1 -0
  26. package/dist/devices/beeper.d.mts +21 -0
  27. package/dist/devices/beeper.d.ts +21 -0
  28. package/dist/devices/beeper.js +286 -0
  29. package/dist/devices/beeper.js.map +1 -0
  30. package/dist/devices/beeper.mjs +261 -0
  31. package/dist/devices/beeper.mjs.map +1 -0
  32. package/dist/devices/index.d.mts +3 -0
  33. package/dist/devices/index.d.ts +3 -0
  34. package/dist/devices/index.js +534 -0
  35. package/dist/devices/index.js.map +1 -0
  36. package/dist/devices/index.mjs +507 -0
  37. package/dist/devices/index.mjs.map +1 -0
  38. package/dist/devices/music.d.mts +27 -0
  39. package/dist/devices/music.d.ts +27 -0
  40. package/dist/devices/music.js +104 -0
  41. package/dist/devices/music.js.map +1 -0
  42. package/dist/devices/music.mjs +81 -0
  43. package/dist/devices/music.mjs.map +1 -0
  44. package/dist/devices/sound.d.mts +22 -0
  45. package/dist/devices/sound.d.ts +22 -0
  46. package/dist/devices/sound.js +198 -0
  47. package/dist/devices/sound.js.map +1 -0
  48. package/dist/devices/sound.mjs +175 -0
  49. package/dist/devices/sound.mjs.map +1 -0
  50. package/dist/index.d.mts +4 -0
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.js +916 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/index.mjs +888 -0
  55. package/dist/index.mjs.map +1 -0
  56. package/package.json +37 -0
@@ -0,0 +1,507 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/constants.ts
5
+ var A4_FREQUENCY = 440;
6
+ var SEMITONE_RATIO = 2 ** (1 / 12);
7
+ var A4_MIDI_NOTE = 69;
8
+
9
+ // src/devices/beeper.ts
10
+ var Beeper = class {
11
+ static {
12
+ __name(this, "Beeper");
13
+ }
14
+ audio;
15
+ notes = {};
16
+ plainNotes = {};
17
+ currentOctave = 5;
18
+ currentDuration = 0.5;
19
+ currentVolume = 0.5;
20
+ currentSpan = 1;
21
+ currentWaveform = "square";
22
+ constructor(audio) {
23
+ this.audio = audio;
24
+ this.initializeNotes();
25
+ }
26
+ /**
27
+ * Initialize note mappings
28
+ */
29
+ initializeNotes() {
30
+ const noteNames = [
31
+ [
32
+ "C",
33
+ "DO"
34
+ ],
35
+ [
36
+ "C#",
37
+ "DO#",
38
+ "Db",
39
+ "REb"
40
+ ],
41
+ [
42
+ "D",
43
+ "RE"
44
+ ],
45
+ [
46
+ "D#",
47
+ "RE#",
48
+ "Eb",
49
+ "MIb"
50
+ ],
51
+ [
52
+ "E",
53
+ "MI"
54
+ ],
55
+ [
56
+ "F",
57
+ "FA"
58
+ ],
59
+ [
60
+ "F#",
61
+ "FA#",
62
+ "Gb",
63
+ "SOLb"
64
+ ],
65
+ [
66
+ "G",
67
+ "SOL"
68
+ ],
69
+ [
70
+ "G#",
71
+ "SOL#",
72
+ "Ab",
73
+ "LAb"
74
+ ],
75
+ [
76
+ "A",
77
+ "LA"
78
+ ],
79
+ [
80
+ "A#",
81
+ "LA#",
82
+ "Bb",
83
+ "SIb"
84
+ ],
85
+ [
86
+ "B",
87
+ "SI"
88
+ ]
89
+ ];
90
+ for (let i = 0; i <= 127; i++) {
91
+ this.notes[i] = i;
92
+ const oct = Math.floor(i / 12) - 1;
93
+ for (const n of noteNames[i % 12]) {
94
+ this.notes[n + oct] = i;
95
+ }
96
+ if (oct === -1) {
97
+ for (const n of noteNames[i % 12]) {
98
+ this.plainNotes[n] = i;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ /**
104
+ * Parse and play beep sequence
105
+ */
106
+ beep(input) {
107
+ let status = "normal";
108
+ const sequence = [];
109
+ const loops = [];
110
+ let note;
111
+ const parsed = input.split(" ");
112
+ for (const t of parsed) {
113
+ if (t === "") continue;
114
+ switch (status) {
115
+ case "normal":
116
+ if (this.notes[t] !== void 0) {
117
+ note = this.notes[t];
118
+ this.currentOctave = Math.floor(note / 12);
119
+ sequence.push({
120
+ frequency: A4_FREQUENCY * SEMITONE_RATIO ** (note - A4_MIDI_NOTE),
121
+ volume: this.currentVolume,
122
+ span: this.currentSpan,
123
+ duration: this.currentDuration,
124
+ waveform: this.currentWaveform
125
+ });
126
+ } else if (this.plainNotes[t] !== void 0) {
127
+ note = this.plainNotes[t] + this.currentOctave * 12;
128
+ sequence.push({
129
+ frequency: A4_FREQUENCY * SEMITONE_RATIO ** (note - A4_MIDI_NOTE),
130
+ volume: this.currentVolume,
131
+ span: this.currentSpan,
132
+ duration: this.currentDuration,
133
+ waveform: this.currentWaveform
134
+ });
135
+ } else if ([
136
+ "square",
137
+ "sine",
138
+ "saw",
139
+ "noise"
140
+ ].includes(t)) {
141
+ this.currentWaveform = t;
142
+ } else if ([
143
+ "tempo",
144
+ "duration",
145
+ "volume",
146
+ "span",
147
+ "loop",
148
+ "to"
149
+ ].includes(t)) {
150
+ status = t;
151
+ } else if (t === "-") {
152
+ sequence.push({
153
+ frequency: A4_FREQUENCY,
154
+ volume: 0,
155
+ span: this.currentSpan,
156
+ duration: this.currentDuration,
157
+ waveform: this.currentWaveform
158
+ });
159
+ } else if (t === "end") {
160
+ if (loops.length > 0 && sequence.length > 0) {
161
+ sequence.push({
162
+ frequency: A4_FREQUENCY,
163
+ volume: 0,
164
+ span: this.currentSpan,
165
+ duration: 0,
166
+ waveform: this.currentWaveform
167
+ });
168
+ const lop = loops.splice(loops.length - 1, 1)[0];
169
+ sequence[sequence.length - 1].loopto = lop.start;
170
+ sequence[sequence.length - 1].repeats = lop.repeats;
171
+ }
172
+ }
173
+ break;
174
+ case "tempo": {
175
+ status = "normal";
176
+ const tempo = Number.parseFloat(t);
177
+ if (!Number.isNaN(tempo) && tempo > 0) {
178
+ this.currentDuration = 60 / tempo;
179
+ }
180
+ break;
181
+ }
182
+ case "duration": {
183
+ status = "normal";
184
+ const duration = Number.parseFloat(t);
185
+ if (!Number.isNaN(duration) && duration > 0) {
186
+ this.currentDuration = duration / 1e3;
187
+ }
188
+ break;
189
+ }
190
+ case "volume": {
191
+ status = "normal";
192
+ const volume = Number.parseFloat(t);
193
+ if (!Number.isNaN(volume)) {
194
+ this.currentVolume = volume / 100;
195
+ }
196
+ break;
197
+ }
198
+ case "span": {
199
+ status = "normal";
200
+ const span = Number.parseFloat(t);
201
+ if (!Number.isNaN(span)) {
202
+ this.currentSpan = span / 100;
203
+ }
204
+ break;
205
+ }
206
+ case "loop": {
207
+ status = "normal";
208
+ loops.push({
209
+ start: sequence.length
210
+ });
211
+ const repeats = Number.parseFloat(t);
212
+ if (!Number.isNaN(repeats)) {
213
+ loops[loops.length - 1].repeats = repeats;
214
+ }
215
+ break;
216
+ }
217
+ case "to":
218
+ status = "normal";
219
+ if (note !== void 0) {
220
+ let n;
221
+ if (this.notes[t] !== void 0) {
222
+ n = this.notes[t];
223
+ } else if (this.plainNotes[t] !== void 0) {
224
+ n = this.plainNotes[t] + this.currentOctave * 12;
225
+ }
226
+ if (n !== void 0 && n !== note) {
227
+ const step = n > note ? 1 : -1;
228
+ for (let i = note + step; step > 0 ? i <= n : i >= n; i += step) {
229
+ sequence.push({
230
+ frequency: A4_FREQUENCY * SEMITONE_RATIO ** (i - A4_MIDI_NOTE),
231
+ volume: this.currentVolume,
232
+ span: this.currentSpan,
233
+ duration: this.currentDuration,
234
+ waveform: this.currentWaveform
235
+ });
236
+ }
237
+ note = n;
238
+ }
239
+ }
240
+ break;
241
+ }
242
+ }
243
+ if (loops.length > 0 && sequence.length > 0) {
244
+ const lop = loops.splice(loops.length - 1, 1)[0];
245
+ sequence.push({
246
+ frequency: A4_FREQUENCY,
247
+ volume: 0,
248
+ span: this.currentSpan,
249
+ duration: 0,
250
+ waveform: this.currentWaveform
251
+ });
252
+ sequence[sequence.length - 1].loopto = lop.start;
253
+ sequence[sequence.length - 1].repeats = lop.repeats;
254
+ }
255
+ this.audio.addBeeps(sequence);
256
+ }
257
+ };
258
+
259
+ // src/devices/music.ts
260
+ var Music = class {
261
+ static {
262
+ __name(this, "Music");
263
+ }
264
+ ready = 1;
265
+ name = "";
266
+ url;
267
+ tag;
268
+ playing = false;
269
+ audio;
270
+ constructor(audio, url) {
271
+ this.audio = audio;
272
+ this.url = url;
273
+ this.tag = new Audio(this.url);
274
+ this.ready = 1;
275
+ }
276
+ /**
277
+ * Play music with volume and loop (HTML5 Audio implementation)
278
+ */
279
+ play(volume = 1, loopit = false) {
280
+ this.playing = true;
281
+ this.tag.loop = !!loopit;
282
+ this.tag.volume = Math.max(0, Math.min(1, volume));
283
+ if (this.audio.isStarted()) {
284
+ this.tag.play();
285
+ } else {
286
+ this.audio.addToWakeUpList(this);
287
+ }
288
+ this.audio.addPlaying(this);
289
+ return {
290
+ play: /* @__PURE__ */ __name(() => {
291
+ return this.tag.play();
292
+ }, "play"),
293
+ stop: /* @__PURE__ */ __name(() => {
294
+ this.playing = false;
295
+ this.tag.pause();
296
+ this.audio.removePlaying(this);
297
+ }, "stop"),
298
+ setVolume: /* @__PURE__ */ __name((v) => {
299
+ this.tag.volume = Math.max(0, Math.min(1, v));
300
+ }, "setVolume"),
301
+ getPosition: /* @__PURE__ */ __name(() => {
302
+ return this.tag.currentTime;
303
+ }, "getPosition"),
304
+ getDuration: /* @__PURE__ */ __name(() => {
305
+ return this.tag.duration;
306
+ }, "getDuration"),
307
+ setPosition: /* @__PURE__ */ __name((pos) => {
308
+ this.tag.pause();
309
+ this.tag.currentTime = Math.max(0, Math.min(this.tag.duration, pos));
310
+ if (this.playing) {
311
+ this.tag.play();
312
+ }
313
+ }, "setPosition")
314
+ };
315
+ }
316
+ /**
317
+ * Wake up audio (for autoplay policy)
318
+ */
319
+ wakeUp() {
320
+ if (this.playing) {
321
+ this.tag.play();
322
+ }
323
+ }
324
+ /**
325
+ * Stop music
326
+ */
327
+ stop() {
328
+ this.playing = false;
329
+ this.tag.pause();
330
+ this.audio.removePlaying(this);
331
+ }
332
+ };
333
+
334
+ // src/devices/sound.ts
335
+ import { APIErrorCode, reportRuntimeError } from "@al8b/diagnostics";
336
+ var Sound = class _Sound {
337
+ static {
338
+ __name(this, "Sound");
339
+ }
340
+ ready = 0;
341
+ buffer;
342
+ name = "";
343
+ url;
344
+ audio;
345
+ constructor(audio, url) {
346
+ this.audio = audio;
347
+ if (url instanceof AudioBuffer) {
348
+ this.buffer = url;
349
+ this.url = "";
350
+ this.ready = 1;
351
+ } else {
352
+ this.url = url;
353
+ this.loadSound(url);
354
+ }
355
+ }
356
+ /**
357
+ * Load sound from URL
358
+ */
359
+ loadSound(url) {
360
+ const request = new XMLHttpRequest();
361
+ request.open("GET", url, true);
362
+ request.responseType = "arraybuffer";
363
+ request.onload = () => {
364
+ this.audio.context.decodeAudioData(request.response, (buffer) => {
365
+ this.buffer = buffer;
366
+ this.ready = 1;
367
+ }, (err) => {
368
+ reportRuntimeError(this.audio?.runtime?.listener, APIErrorCode.E7016, {
369
+ error: `Audio decoding failed: ${String(err)}`
370
+ });
371
+ });
372
+ };
373
+ request.onerror = () => {
374
+ reportRuntimeError(this.audio?.runtime?.listener, APIErrorCode.E7016, {
375
+ error: `Failed to load sound: ${url}`
376
+ });
377
+ };
378
+ request.send();
379
+ }
380
+ /**
381
+ * Play sound with volume, pitch, pan, and loop
382
+ */
383
+ play(volume = 1, pitch = 1, pan = 0, loopit = false) {
384
+ if (!this.buffer) return {
385
+ stop: /* @__PURE__ */ __name(() => {
386
+ }, "stop"),
387
+ finished: true
388
+ };
389
+ const context = this.audio.context;
390
+ const source = context.createBufferSource();
391
+ source.playbackRate.value = pitch;
392
+ source.buffer = this.buffer;
393
+ if (loopit) source.loop = true;
394
+ const gain = context.createGain();
395
+ gain.gain.value = volume;
396
+ const panner = context.createPanner();
397
+ panner.panningModel = "equalpower";
398
+ panner.setPan = (p) => {
399
+ panner.setPosition(p, 0, 1 - Math.abs(p));
400
+ };
401
+ panner.setPan(pan);
402
+ source.connect(gain);
403
+ gain.connect(panner);
404
+ panner.connect(context.destination);
405
+ source.start();
406
+ let playing = null;
407
+ if (loopit) {
408
+ playing = {
409
+ stop: /* @__PURE__ */ __name(() => {
410
+ source.stop();
411
+ }, "stop")
412
+ };
413
+ this.audio.addPlaying(playing);
414
+ }
415
+ const res = {
416
+ stop: /* @__PURE__ */ __name(() => {
417
+ source.stop();
418
+ if (playing) this.audio.removePlaying(playing);
419
+ return 1;
420
+ }, "stop"),
421
+ setVolume: /* @__PURE__ */ __name((v) => {
422
+ gain.gain.value = Math.max(0, Math.min(1, v));
423
+ }, "setVolume"),
424
+ setPitch: /* @__PURE__ */ __name((p) => {
425
+ source.playbackRate.value = Math.max(1e-3, Math.min(1e3, p));
426
+ }, "setPitch"),
427
+ setPan: /* @__PURE__ */ __name((p) => {
428
+ panner.setPan(Math.max(-1, Math.min(1, p)));
429
+ }, "setPan"),
430
+ getDuration: /* @__PURE__ */ __name(() => {
431
+ return source.buffer ? source.buffer.duration : 0;
432
+ }, "getDuration"),
433
+ finished: false
434
+ };
435
+ source.onended = () => {
436
+ res.finished = true;
437
+ };
438
+ return res;
439
+ }
440
+ /**
441
+ * Create MicroSound class for procedural sound generation
442
+ */
443
+ static createSoundClass(audiocore) {
444
+ return class MicroSound {
445
+ static {
446
+ __name(this, "MicroSound");
447
+ }
448
+ static classname = "Sound";
449
+ channels;
450
+ length;
451
+ sampleRate;
452
+ sound;
453
+ buffer;
454
+ constructor(channels, length, sampleRate = 44100) {
455
+ channels = channels === 1 ? 1 : 2;
456
+ if (!(length > 1 && length < 44100 * 1e3)) {
457
+ length = 44100;
458
+ }
459
+ if (!(sampleRate >= 8e3 && sampleRate <= 96e3)) {
460
+ sampleRate = 44100;
461
+ }
462
+ this.channels = channels;
463
+ this.length = length;
464
+ this.sampleRate = sampleRate;
465
+ this.buffer = audiocore.context.createBuffer(channels, length, sampleRate);
466
+ this.sound = new _Sound(audiocore, this.buffer);
467
+ }
468
+ /**
469
+ * Play the sound
470
+ */
471
+ play(volume, pitch, pan, loopit) {
472
+ return this.sound.play(volume, pitch, pan, loopit);
473
+ }
474
+ /**
475
+ * Write sample value to buffer
476
+ */
477
+ write(channel, position, value) {
478
+ if (channel === 0) {
479
+ const ch1 = this.buffer.getChannelData(0);
480
+ ch1[position] = value;
481
+ } else if (this.channels === 2) {
482
+ const ch2 = this.buffer.getChannelData(1);
483
+ ch2[position] = value;
484
+ }
485
+ }
486
+ /**
487
+ * Read sample value from buffer
488
+ */
489
+ read(channel, position) {
490
+ if (channel === 0) {
491
+ const ch1 = this.buffer.getChannelData(0);
492
+ return ch1[position];
493
+ } else if (this.channels === 2) {
494
+ const ch2 = this.buffer.getChannelData(1);
495
+ return ch2[position];
496
+ }
497
+ return 0;
498
+ }
499
+ };
500
+ }
501
+ };
502
+ export {
503
+ Beeper,
504
+ Music,
505
+ Sound
506
+ };
507
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants.ts","../../src/devices/beeper.ts","../../src/devices/music.ts","../../src/devices/sound.ts"],"sourcesContent":["/** A4 reference frequency in Hz (concert pitch) */\nexport const A4_FREQUENCY = 440;\n\n/** Ratio between adjacent semitones in equal temperament */\nexport const SEMITONE_RATIO = 2 ** (1 / 12);\n\n/** MIDI note number for A4 */\nexport const A4_MIDI_NOTE = 69;\n","/**\n * Beeper - Procedural sound generation from text sequences\n * Converts music notation strings into beep sequences\n * Example: \"square tempo 120 C4 D4 E4 F4\"\n */\nimport { A4_FREQUENCY, A4_MIDI_NOTE, SEMITONE_RATIO } from \"../constants\";\nexport class Beeper {\n\tprivate audio: any;\n\tprivate notes: Record<string | number, number> = {};\n\tprivate plainNotes: Record<string, number> = {};\n\tprivate currentOctave = 5;\n\tprivate currentDuration = 0.5;\n\tprivate currentVolume = 0.5;\n\tprivate currentSpan = 1;\n\tprivate currentWaveform = \"square\";\n\n\tconstructor(audio: any) {\n\t\tthis.audio = audio;\n\t\tthis.initializeNotes();\n\t}\n\n\t/**\n\t * Initialize note mappings\n\t */\n\tprivate initializeNotes(): void {\n\t\tconst noteNames = [\n\t\t\t[\"C\", \"DO\"],\n\t\t\t[\"C#\", \"DO#\", \"Db\", \"REb\"],\n\t\t\t[\"D\", \"RE\"],\n\t\t\t[\"D#\", \"RE#\", \"Eb\", \"MIb\"],\n\t\t\t[\"E\", \"MI\"],\n\t\t\t[\"F\", \"FA\"],\n\t\t\t[\"F#\", \"FA#\", \"Gb\", \"SOLb\"],\n\t\t\t[\"G\", \"SOL\"],\n\t\t\t[\"G#\", \"SOL#\", \"Ab\", \"LAb\"],\n\t\t\t[\"A\", \"LA\"],\n\t\t\t[\"A#\", \"LA#\", \"Bb\", \"SIb\"],\n\t\t\t[\"B\", \"SI\"],\n\t\t];\n\n\t\tfor (let i = 0; i <= 127; i++) {\n\t\t\tthis.notes[i] = i;\n\t\t\tconst oct = Math.floor(i / 12) - 1;\n\n\t\t\tfor (const n of noteNames[i % 12]) {\n\t\t\t\tthis.notes[n + oct] = i;\n\t\t\t}\n\n\t\t\tif (oct === -1) {\n\t\t\t\tfor (const n of noteNames[i % 12]) {\n\t\t\t\t\tthis.plainNotes[n] = i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Parse and play beep sequence\n\t */\n\tpublic beep(input: string): void {\n\t\tlet status: string = \"normal\";\n\t\tconst sequence: any[] = [];\n\t\tconst loops: any[] = [];\n\t\tlet note: number | undefined;\n\n\t\tconst parsed = input.split(\" \");\n\n\t\tfor (const t of parsed) {\n\t\t\tif (t === \"\") continue;\n\n\t\t\tswitch (status) {\n\t\t\t\tcase \"normal\":\n\t\t\t\t\tif (this.notes[t] !== undefined) {\n\t\t\t\t\t\t// Full note with octave (e.g., \"C4\")\n\t\t\t\t\t\tnote = this.notes[t];\n\t\t\t\t\t\tthis.currentOctave = Math.floor(note / 12);\n\t\t\t\t\t\tsequence.push({\n\t\t\t\t\t\t\tfrequency: A4_FREQUENCY * SEMITONE_RATIO ** (note - A4_MIDI_NOTE),\n\t\t\t\t\t\t\tvolume: this.currentVolume,\n\t\t\t\t\t\t\tspan: this.currentSpan,\n\t\t\t\t\t\t\tduration: this.currentDuration,\n\t\t\t\t\t\t\twaveform: this.currentWaveform,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (this.plainNotes[t] !== undefined) {\n\t\t\t\t\t\t// Note without octave (e.g., \"C\")\n\t\t\t\t\t\tnote = this.plainNotes[t] + this.currentOctave * 12;\n\t\t\t\t\t\tsequence.push({\n\t\t\t\t\t\t\tfrequency: A4_FREQUENCY * SEMITONE_RATIO ** (note - A4_MIDI_NOTE),\n\t\t\t\t\t\t\tvolume: this.currentVolume,\n\t\t\t\t\t\t\tspan: this.currentSpan,\n\t\t\t\t\t\t\tduration: this.currentDuration,\n\t\t\t\t\t\t\twaveform: this.currentWaveform,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if ([\"square\", \"sine\", \"saw\", \"noise\"].includes(t)) {\n\t\t\t\t\t\t// Waveform\n\t\t\t\t\t\tthis.currentWaveform = t;\n\t\t\t\t\t} else if ([\"tempo\", \"duration\", \"volume\", \"span\", \"loop\", \"to\"].includes(t)) {\n\t\t\t\t\t\t// Commands\n\t\t\t\t\t\tstatus = t;\n\t\t\t\t\t} else if (t === \"-\") {\n\t\t\t\t\t\t// Rest/silence\n\t\t\t\t\t\tsequence.push({\n\t\t\t\t\t\t\tfrequency: A4_FREQUENCY,\n\t\t\t\t\t\t\tvolume: 0,\n\t\t\t\t\t\t\tspan: this.currentSpan,\n\t\t\t\t\t\t\tduration: this.currentDuration,\n\t\t\t\t\t\t\twaveform: this.currentWaveform,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (t === \"end\") {\n\t\t\t\t\t\t// End loop\n\t\t\t\t\t\tif (loops.length > 0 && sequence.length > 0) {\n\t\t\t\t\t\t\tsequence.push({\n\t\t\t\t\t\t\t\tfrequency: A4_FREQUENCY,\n\t\t\t\t\t\t\t\tvolume: 0,\n\t\t\t\t\t\t\t\tspan: this.currentSpan,\n\t\t\t\t\t\t\t\tduration: 0,\n\t\t\t\t\t\t\t\twaveform: this.currentWaveform,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst lop = loops.splice(loops.length - 1, 1)[0];\n\t\t\t\t\t\t\tsequence[sequence.length - 1].loopto = lop.start;\n\t\t\t\t\t\t\tsequence[sequence.length - 1].repeats = lop.repeats;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"tempo\": {\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tconst tempo = Number.parseFloat(t);\n\t\t\t\t\tif (!Number.isNaN(tempo) && tempo > 0) {\n\t\t\t\t\t\tthis.currentDuration = 60 / tempo;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"duration\": {\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tconst duration = Number.parseFloat(t);\n\t\t\t\t\tif (!Number.isNaN(duration) && duration > 0) {\n\t\t\t\t\t\tthis.currentDuration = duration / 1000;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"volume\": {\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tconst volume = Number.parseFloat(t);\n\t\t\t\t\tif (!Number.isNaN(volume)) {\n\t\t\t\t\t\tthis.currentVolume = volume / 100;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"span\": {\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tconst span = Number.parseFloat(t);\n\t\t\t\t\tif (!Number.isNaN(span)) {\n\t\t\t\t\t\tthis.currentSpan = span / 100;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"loop\": {\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tloops.push({\n\t\t\t\t\t\tstart: sequence.length,\n\t\t\t\t\t});\n\t\t\t\t\tconst repeats = Number.parseFloat(t);\n\t\t\t\t\tif (!Number.isNaN(repeats)) {\n\t\t\t\t\t\tloops[loops.length - 1].repeats = repeats;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"to\":\n\t\t\t\t\tstatus = \"normal\";\n\t\t\t\t\tif (note !== undefined) {\n\t\t\t\t\t\tlet n: number | undefined;\n\n\t\t\t\t\t\tif (this.notes[t] !== undefined) {\n\t\t\t\t\t\t\tn = this.notes[t];\n\t\t\t\t\t\t} else if (this.plainNotes[t] !== undefined) {\n\t\t\t\t\t\t\tn = this.plainNotes[t] + this.currentOctave * 12;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (n !== undefined && n !== note) {\n\t\t\t\t\t\t\t// Generate slide from note to n\n\t\t\t\t\t\t\tconst step = n > note ? 1 : -1;\n\t\t\t\t\t\t\tfor (let i = note + step; step > 0 ? i <= n : i >= n; i += step) {\n\t\t\t\t\t\t\t\tsequence.push({\n\t\t\t\t\t\t\t\t\tfrequency: A4_FREQUENCY * SEMITONE_RATIO ** (i - A4_MIDI_NOTE),\n\t\t\t\t\t\t\t\t\tvolume: this.currentVolume,\n\t\t\t\t\t\t\t\t\tspan: this.currentSpan,\n\t\t\t\t\t\t\t\t\tduration: this.currentDuration,\n\t\t\t\t\t\t\t\t\twaveform: this.currentWaveform,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnote = n;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Close any remaining loops\n\t\tif (loops.length > 0 && sequence.length > 0) {\n\t\t\tconst lop = loops.splice(loops.length - 1, 1)[0];\n\t\t\tsequence.push({\n\t\t\t\tfrequency: A4_FREQUENCY,\n\t\t\t\tvolume: 0,\n\t\t\t\tspan: this.currentSpan,\n\t\t\t\tduration: 0,\n\t\t\t\twaveform: this.currentWaveform,\n\t\t\t});\n\n\t\t\tsequence[sequence.length - 1].loopto = lop.start;\n\t\t\tsequence[sequence.length - 1].repeats = lop.repeats;\n\t\t}\n\n\t\tthis.audio.addBeeps(sequence);\n\t}\n}\n","/**\n * Music - Music streaming and playback using HTML5 Audio\n * L8B Music class for LootiScript\n */\nexport class Music {\n\tpublic ready: number = 1;\n\tpublic name: string = \"\";\n\tpublic url: string;\n\tpublic tag: HTMLAudioElement;\n\tpublic playing: boolean = false;\n\tprivate audio: any;\n\n\tconstructor(audio: any, url: string) {\n\t\tthis.audio = audio;\n\t\tthis.url = url;\n\t\tthis.tag = new Audio(this.url);\n\t\tthis.ready = 1;\n\t}\n\n\t/**\n\t * Play music with volume and loop (HTML5 Audio implementation)\n\t */\n\tpublic play(volume: number = 1, loopit: boolean = false): any {\n\t\tthis.playing = true;\n\t\tthis.tag.loop = !!loopit;\n\t\tthis.tag.volume = Math.max(0, Math.min(1, volume));\n\n\t\tif (this.audio.isStarted()) {\n\t\t\tthis.tag.play();\n\t\t} else {\n\t\t\tthis.audio.addToWakeUpList(this);\n\t\t}\n\n\t\tthis.audio.addPlaying(this);\n\n\t\treturn {\n\t\t\tplay: () => {\n\t\t\t\treturn this.tag.play();\n\t\t\t},\n\t\t\tstop: () => {\n\t\t\t\tthis.playing = false;\n\t\t\t\tthis.tag.pause();\n\t\t\t\tthis.audio.removePlaying(this);\n\t\t\t},\n\t\t\tsetVolume: (v: number) => {\n\t\t\t\tthis.tag.volume = Math.max(0, Math.min(1, v));\n\t\t\t},\n\t\t\tgetPosition: () => {\n\t\t\t\treturn this.tag.currentTime;\n\t\t\t},\n\t\t\tgetDuration: () => {\n\t\t\t\treturn this.tag.duration;\n\t\t\t},\n\t\t\tsetPosition: (pos: number) => {\n\t\t\t\tthis.tag.pause();\n\t\t\t\tthis.tag.currentTime = Math.max(0, Math.min(this.tag.duration, pos));\n\t\t\t\tif (this.playing) {\n\t\t\t\t\tthis.tag.play();\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Wake up audio (for autoplay policy)\n\t */\n\tpublic wakeUp(): void {\n\t\tif (this.playing) {\n\t\t\tthis.tag.play();\n\t\t}\n\t}\n\n\t/**\n\t * Stop music\n\t */\n\tpublic stop(): void {\n\t\tthis.playing = false;\n\t\tthis.tag.pause();\n\t\tthis.audio.removePlaying(this);\n\t}\n}\n","/**\n * Sound - Sound effect playback\n * Handles loading and playing audio buffers\n */\nimport { APIErrorCode, reportRuntimeError } from \"@al8b/diagnostics\";\n\nexport class Sound {\n\tpublic ready: number = 0;\n\tpublic buffer?: AudioBuffer;\n\tpublic name: string = \"\";\n\tpublic url: string;\n\tprivate audio: any;\n\n\tconstructor(audio: any, url: string | AudioBuffer) {\n\t\tthis.audio = audio;\n\n\t\tif (url instanceof AudioBuffer) {\n\t\t\tthis.buffer = url;\n\t\t\tthis.url = \"\";\n\t\t\tthis.ready = 1;\n\t\t} else {\n\t\t\tthis.url = url;\n\t\t\tthis.loadSound(url);\n\t\t}\n\t}\n\n\t/**\n\t * Load sound from URL\n\t */\n\tprivate loadSound(url: string): void {\n\t\tconst request = new XMLHttpRequest();\n\t\trequest.open(\"GET\", url, true);\n\t\trequest.responseType = \"arraybuffer\";\n\n\t\trequest.onload = () => {\n\t\t\tthis.audio.context.decodeAudioData(\n\t\t\t\trequest.response,\n\t\t\t\t(buffer: AudioBuffer) => {\n\t\t\t\t\tthis.buffer = buffer;\n\t\t\t\t\tthis.ready = 1;\n\t\t\t\t},\n\t\t\t\t(err: any) => {\n\t\t\t\t\treportRuntimeError(this.audio?.runtime?.listener, APIErrorCode.E7016, {\n\t\t\t\t\t\terror: `Audio decoding failed: ${String(err)}`,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\trequest.onerror = () => {\n\t\t\treportRuntimeError(this.audio?.runtime?.listener, APIErrorCode.E7016, {\n\t\t\t\terror: `Failed to load sound: ${url}`,\n\t\t\t});\n\t\t};\n\n\t\trequest.send();\n\t}\n\n\t/**\n\t * Play sound with volume, pitch, pan, and loop\n\t */\n\tpublic play(volume: number = 1, pitch: number = 1, pan: number = 0, loopit: boolean = false): any {\n\t\tif (!this.buffer)\n\t\t\treturn {\n\t\t\t\tstop: () => {},\n\t\t\t\tfinished: true,\n\t\t\t};\n\n\t\tconst context = this.audio.context;\n\n\t\t// Create source\n\t\tconst source = context.createBufferSource();\n\t\tsource.playbackRate.value = pitch;\n\t\tsource.buffer = this.buffer;\n\t\tif (loopit) source.loop = true;\n\n\t\t// Create gain node\n\t\tconst gain = context.createGain();\n\t\tgain.gain.value = volume;\n\n\t\t// Create panner\n\t\tconst panner: any = context.createPanner();\n\t\tpanner.panningModel = \"equalpower\";\n\t\tpanner.setPan = (p: number) => {\n\t\t\tpanner.setPosition(p, 0, 1 - Math.abs(p));\n\t\t};\n\t\tpanner.setPan(pan);\n\n\t\t// Connect nodes\n\t\tsource.connect(gain);\n\t\tgain.connect(panner);\n\t\tpanner.connect(context.destination);\n\n\t\t// Start playback\n\t\tsource.start();\n\n\t\t// Track playing sounds for looping\n\t\tlet playing: any = null;\n\t\tif (loopit) {\n\t\t\tplaying = {\n\t\t\t\tstop: () => {\n\t\t\t\t\tsource.stop();\n\t\t\t\t},\n\t\t\t};\n\t\t\tthis.audio.addPlaying(playing);\n\t\t}\n\n\t\t// Return control interface\n\t\tconst res = {\n\t\t\tstop: () => {\n\t\t\t\tsource.stop();\n\t\t\t\tif (playing) this.audio.removePlaying(playing);\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t\tsetVolume: (v: number) => {\n\t\t\t\tgain.gain.value = Math.max(0, Math.min(1, v));\n\t\t\t},\n\t\t\tsetPitch: (p: number) => {\n\t\t\t\tsource.playbackRate.value = Math.max(0.001, Math.min(1000, p));\n\t\t\t},\n\t\t\tsetPan: (p: number) => {\n\t\t\t\tpanner.setPan(Math.max(-1, Math.min(1, p)));\n\t\t\t},\n\t\t\tgetDuration: () => {\n\t\t\t\treturn source.buffer ? source.buffer.duration : 0;\n\t\t\t},\n\t\t\tfinished: false,\n\t\t};\n\n\t\tsource.onended = () => {\n\t\t\tres.finished = true;\n\t\t};\n\n\t\treturn res;\n\t}\n\n\t/**\n\t * Create MicroSound class for procedural sound generation\n\t */\n\tpublic static createSoundClass(audiocore: any): any {\n\t\treturn class MicroSound {\n\t\t\tpublic static classname = \"Sound\";\n\t\t\tpublic channels: number;\n\t\t\tpublic length: number;\n\t\t\tpublic sampleRate: number;\n\t\t\tprivate sound: Sound;\n\t\t\tprivate buffer: AudioBuffer;\n\n\t\t\tconstructor(channels: number, length: number, sampleRate: number = 44100) {\n\t\t\t\t// Validate parameters\n\t\t\t\tchannels = channels === 1 ? 1 : 2;\n\t\t\t\tif (!(length > 1 && length < 44100 * 1000)) {\n\t\t\t\t\tlength = 44100;\n\t\t\t\t}\n\t\t\t\tif (!(sampleRate >= 8000 && sampleRate <= 96000)) {\n\t\t\t\t\tsampleRate = 44100;\n\t\t\t\t}\n\n\t\t\t\tthis.channels = channels;\n\t\t\t\tthis.length = length;\n\t\t\t\tthis.sampleRate = sampleRate;\n\n\t\t\t\t// Create audio buffer\n\t\t\t\tthis.buffer = audiocore.context.createBuffer(channels, length, sampleRate);\n\t\t\t\tthis.sound = new Sound(audiocore, this.buffer);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Play the sound\n\t\t\t */\n\t\t\tpublic play(volume?: number, pitch?: number, pan?: number, loopit?: boolean): any {\n\t\t\t\treturn this.sound.play(volume, pitch, pan, loopit);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Write sample value to buffer\n\t\t\t */\n\t\t\tpublic write(channel: number, position: number, value: number): void {\n\t\t\t\tif (channel === 0) {\n\t\t\t\t\tconst ch1 = this.buffer.getChannelData(0);\n\t\t\t\t\tch1[position] = value;\n\t\t\t\t} else if (this.channels === 2) {\n\t\t\t\t\tconst ch2 = this.buffer.getChannelData(1);\n\t\t\t\t\tch2[position] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Read sample value from buffer\n\t\t\t */\n\t\t\tpublic read(channel: number, position: number): number {\n\t\t\t\tif (channel === 0) {\n\t\t\t\t\tconst ch1 = this.buffer.getChannelData(0);\n\t\t\t\t\treturn ch1[position];\n\t\t\t\t} else if (this.channels === 2) {\n\t\t\t\t\tconst ch2 = this.buffer.getChannelData(1);\n\t\t\t\t\treturn ch2[position];\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["A4_FREQUENCY","SEMITONE_RATIO","A4_MIDI_NOTE","Beeper","audio","notes","plainNotes","currentOctave","currentDuration","currentVolume","currentSpan","currentWaveform","initializeNotes","noteNames","i","oct","Math","floor","n","beep","input","status","sequence","loops","note","parsed","split","t","undefined","push","frequency","A4_FREQUENCY","SEMITONE_RATIO","A4_MIDI_NOTE","volume","span","duration","waveform","includes","length","lop","splice","loopto","start","repeats","tempo","Number","parseFloat","isNaN","step","addBeeps","Music","ready","name","url","tag","playing","audio","Audio","play","volume","loopit","loop","Math","max","min","isStarted","addToWakeUpList","addPlaying","stop","pause","removePlaying","setVolume","v","getPosition","currentTime","getDuration","duration","setPosition","pos","wakeUp","APIErrorCode","reportRuntimeError","Sound","ready","buffer","name","url","audio","AudioBuffer","loadSound","request","XMLHttpRequest","open","responseType","onload","context","decodeAudioData","response","err","reportRuntimeError","runtime","listener","APIErrorCode","E7016","error","String","onerror","send","play","volume","pitch","pan","loopit","stop","finished","source","createBufferSource","playbackRate","value","loop","gain","createGain","panner","createPanner","panningModel","setPan","p","setPosition","Math","abs","connect","destination","start","playing","addPlaying","res","removePlaying","setVolume","v","max","min","setPitch","getDuration","duration","onended","createSoundClass","audiocore","MicroSound","classname","channels","length","sampleRate","sound","createBuffer","write","channel","position","ch1","getChannelData","ch2","read"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Music - Music streaming and playback using HTML5 Audio
3
+ * L8B Music class for LootiScript
4
+ */
5
+ declare class Music {
6
+ ready: number;
7
+ name: string;
8
+ url: string;
9
+ tag: HTMLAudioElement;
10
+ playing: boolean;
11
+ private audio;
12
+ constructor(audio: any, url: string);
13
+ /**
14
+ * Play music with volume and loop (HTML5 Audio implementation)
15
+ */
16
+ play(volume?: number, loopit?: boolean): any;
17
+ /**
18
+ * Wake up audio (for autoplay policy)
19
+ */
20
+ wakeUp(): void;
21
+ /**
22
+ * Stop music
23
+ */
24
+ stop(): void;
25
+ }
26
+
27
+ export { Music };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Music - Music streaming and playback using HTML5 Audio
3
+ * L8B Music class for LootiScript
4
+ */
5
+ declare class Music {
6
+ ready: number;
7
+ name: string;
8
+ url: string;
9
+ tag: HTMLAudioElement;
10
+ playing: boolean;
11
+ private audio;
12
+ constructor(audio: any, url: string);
13
+ /**
14
+ * Play music with volume and loop (HTML5 Audio implementation)
15
+ */
16
+ play(volume?: number, loopit?: boolean): any;
17
+ /**
18
+ * Wake up audio (for autoplay policy)
19
+ */
20
+ wakeUp(): void;
21
+ /**
22
+ * Stop music
23
+ */
24
+ stop(): void;
25
+ }
26
+
27
+ export { Music };