jsbeeb 1.4.0 → 1.5.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/package.json +1 -1
- package/src/6502.js +26 -21
- package/src/6502.opcodes.js +20 -15
- package/src/acia.js +21 -7
- package/src/bbc-palette.js +24 -0
- package/src/cmos.js +12 -1
- package/src/config.js +23 -0
- package/src/fake6502.js +9 -2
- package/src/fdc.js +51 -54
- package/src/keyboard.js +7 -4
- package/src/machine-session.js +13 -3
- package/src/main.js +93 -32
- package/src/models.js +111 -83
- package/src/soundchip.js +78 -0
- package/src/speech-output.js +85 -0
- package/src/teletext.js +31 -16
- package/src/via.js +1 -1
- package/src/video.js +206 -34
- package/src/wd-fdc.js +6 -1
- package/src/web/audio-handler.js +1 -1
package/src/teletext.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { makeChars } from "./teletext_data.js";
|
|
3
3
|
import { makeFast32 } from "./utils.js";
|
|
4
|
+
import { BbcDefaultPalette as BbcDefaultCollook } from "./bbc-palette.js";
|
|
4
5
|
|
|
5
6
|
export class Teletext {
|
|
6
7
|
constructor() {
|
|
@@ -35,22 +36,8 @@ export class Teletext {
|
|
|
35
36
|
init() {
|
|
36
37
|
const charData = makeChars();
|
|
37
38
|
|
|
38
|
-
// Build palette
|
|
39
|
-
|
|
40
|
-
for (let i = 0; i < 256; ++i) {
|
|
41
|
-
const alpha = (i & 3) / 3.0;
|
|
42
|
-
const foregroundR = !!(i & 4);
|
|
43
|
-
const foregroundG = !!(i & 8);
|
|
44
|
-
const foregroundB = !!(i & 16);
|
|
45
|
-
const backgroundR = !!(i & 32);
|
|
46
|
-
const backgroundG = !!(i & 64);
|
|
47
|
-
const backgroundB = !!(i & 128);
|
|
48
|
-
// Gamma-corrected blending
|
|
49
|
-
const blendedR = Math.pow(foregroundR * alpha + backgroundR * (1.0 - alpha), gamma) * 240;
|
|
50
|
-
const blendedG = Math.pow(foregroundG * alpha + backgroundG * (1.0 - alpha), gamma) * 240;
|
|
51
|
-
const blendedB = Math.pow(foregroundB * alpha + backgroundB * (1.0 - alpha), gamma) * 240;
|
|
52
|
-
this.colour[i] = blendedR | (blendedG << 8) | (blendedB << 16) | (0xff << 24);
|
|
53
|
-
}
|
|
39
|
+
// Build palette from BBC default colours.
|
|
40
|
+
this.rebuildColours(BbcDefaultCollook);
|
|
54
41
|
|
|
55
42
|
function getLoResGlyphRow(c, row) {
|
|
56
43
|
if (row < 0 || row >= 20) {
|
|
@@ -135,6 +122,34 @@ export class Teletext {
|
|
|
135
122
|
makeHiResGlyphs(this.separatedGlyphs, true);
|
|
136
123
|
}
|
|
137
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Rebuild the 256-entry colour lookup from a 16-entry ABGR collook palette.
|
|
127
|
+
* Each entry encodes: bits 7-5 = background colour index (0-7),
|
|
128
|
+
* bits 4-2 = foreground colour index (0-7), bits 1-0 = blend weight.
|
|
129
|
+
* Reference: b-em mode7_gen_nula_lookup().
|
|
130
|
+
* @param {Uint32Array} collook - 16-entry palette in ABGR format (0xffBBGGRR).
|
|
131
|
+
*/
|
|
132
|
+
rebuildColours(collook) {
|
|
133
|
+
const gamma = 1.0 / 2.2;
|
|
134
|
+
for (let i = 0; i < 256; ++i) {
|
|
135
|
+
const weight = (i & 3) / 3.0;
|
|
136
|
+
const fgIndex = (i >> 2) & 7;
|
|
137
|
+
const bgIndex = (i >> 5) & 7;
|
|
138
|
+
const fgColour = collook[fgIndex];
|
|
139
|
+
const bgColour = collook[bgIndex];
|
|
140
|
+
const fgR = (fgColour & 0xff) / 255;
|
|
141
|
+
const fgG = ((fgColour >> 8) & 0xff) / 255;
|
|
142
|
+
const fgB = ((fgColour >> 16) & 0xff) / 255;
|
|
143
|
+
const bgR = (bgColour & 0xff) / 255;
|
|
144
|
+
const bgG = ((bgColour >> 8) & 0xff) / 255;
|
|
145
|
+
const bgB = ((bgColour >> 16) & 0xff) / 255;
|
|
146
|
+
const blendedR = Math.pow(fgR * weight + bgR * (1.0 - weight), gamma) * 240;
|
|
147
|
+
const blendedG = Math.pow(fgG * weight + bgG * (1.0 - weight), gamma) * 240;
|
|
148
|
+
const blendedB = Math.pow(fgB * weight + bgB * (1.0 - weight), gamma) * 240;
|
|
149
|
+
this.colour[i] = blendedR | 0 | ((blendedG | 0) << 8) | ((blendedB | 0) << 16) | (0xff << 24);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
138
153
|
setNextChars() {
|
|
139
154
|
if (this.gfx) {
|
|
140
155
|
if (this.sep) {
|
package/src/via.js
CHANGED
|
@@ -460,7 +460,7 @@ class Via {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
export class SysVia extends Via {
|
|
463
|
-
constructor(cpu, scheduler, video, soundChip, cmos, isMaster, initialLayout, getGamepads) {
|
|
463
|
+
constructor(cpu, scheduler, { video, soundChip, cmos, isMaster, initialLayout, getGamepads } = {}) {
|
|
464
464
|
super(cpu, scheduler, 0x01);
|
|
465
465
|
|
|
466
466
|
this.IC32 = 0;
|
package/src/video.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { Teletext } from "./teletext.js";
|
|
3
3
|
import * as utils from "./utils.js";
|
|
4
|
+
import { BbcDefaultPalette as NulaDefaultPalette } from "./bbc-palette.js";
|
|
4
5
|
|
|
5
6
|
export const VDISPENABLE = 1 << 0;
|
|
6
7
|
export const HDISPENABLE = 1 << 1;
|
|
@@ -15,43 +16,182 @@ export const OPAQUE_BLACK = 0xff000000;
|
|
|
15
16
|
export const OPAQUE_WHITE = 0xffffffff;
|
|
16
17
|
|
|
17
18
|
////////////////////
|
|
18
|
-
//
|
|
19
|
+
// VideoNULA - programmable 12-bit RGB palette extension (RobC hardware mod).
|
|
20
|
+
// Reference: b-em src/video.c (stardot/b-em).
|
|
21
|
+
// Addresses &FE22 (control) and &FE23 (palette) via 2-byte write protocol.
|
|
22
|
+
|
|
23
|
+
////////////////////
|
|
24
|
+
// ULA interface (includes NULA programmable palette support)
|
|
19
25
|
class Ula {
|
|
20
26
|
constructor(video) {
|
|
21
27
|
this.video = video;
|
|
28
|
+
// NULA state
|
|
29
|
+
this.collook = new Uint32Array(16);
|
|
30
|
+
this.flash = new Uint8Array(8);
|
|
31
|
+
this.paletteWriteFlag = false;
|
|
32
|
+
this.paletteFirstByte = 0;
|
|
33
|
+
this.paletteMode = 0;
|
|
34
|
+
this.horizontalOffset = 0;
|
|
35
|
+
this.leftBlank = 0;
|
|
36
|
+
this.disabled = false;
|
|
37
|
+
this.attributeMode = 0;
|
|
38
|
+
this.attributeText = 0;
|
|
39
|
+
this.reset();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
reset() {
|
|
43
|
+
this.collook.set(NulaDefaultPalette);
|
|
44
|
+
this.flash.fill(1);
|
|
45
|
+
this.paletteWriteFlag = false;
|
|
46
|
+
this.paletteFirstByte = 0;
|
|
47
|
+
this.paletteMode = 0;
|
|
48
|
+
this.horizontalOffset = 0;
|
|
49
|
+
this.leftBlank = 0;
|
|
50
|
+
this.attributeMode = 0;
|
|
51
|
+
this.attributeText = 0;
|
|
52
|
+
// Note: disabled is NOT cleared by reset (matches b-em behaviour).
|
|
53
|
+
// Recompute rendered palette so any custom NULA colours are flushed.
|
|
54
|
+
this._recomputeUlaPal(!!(this.video.ulactrl & 1));
|
|
55
|
+
// Rebuild MODE 7 teletext colours from the restored default palette.
|
|
56
|
+
this.video.teletext.rebuildColours(this.collook);
|
|
22
57
|
}
|
|
23
58
|
|
|
24
59
|
write(addr, val) {
|
|
25
60
|
addr |= 0;
|
|
26
61
|
val |= 0;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
62
|
+
let reg = addr & 3;
|
|
63
|
+
|
|
64
|
+
// When NULA is disabled, mask off bit 1 so &FE22/&FE23 become &FE20/&FE21.
|
|
65
|
+
if (reg >= 2 && this.disabled) {
|
|
66
|
+
reg &= ~2;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
switch (reg) {
|
|
70
|
+
case 0:
|
|
71
|
+
this._writeControl(val);
|
|
72
|
+
break;
|
|
73
|
+
case 1:
|
|
74
|
+
this._writePalette(val);
|
|
75
|
+
break;
|
|
76
|
+
case 2:
|
|
77
|
+
this._writeNulaControl(val);
|
|
78
|
+
break;
|
|
79
|
+
case 3:
|
|
80
|
+
this._writeNulaPalette(val);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ULA control register (&FE20).
|
|
86
|
+
_writeControl(val) {
|
|
87
|
+
if ((this.video.ulactrl ^ val) & 1) {
|
|
88
|
+
// Flash state has changed - recompute all palette entries.
|
|
89
|
+
this._recomputeUlaPal(!!(val & 1));
|
|
90
|
+
}
|
|
91
|
+
this.video.ulactrl = val;
|
|
92
|
+
this.video.pixelsPerChar = val & 0x10 ? 8 : 16;
|
|
93
|
+
this.video.halfClock = !(val & 0x10);
|
|
94
|
+
const newMode = (val >>> 2) & 3;
|
|
95
|
+
if (newMode !== this.video.ulaMode) {
|
|
96
|
+
this.video.ulaMode = newMode;
|
|
97
|
+
}
|
|
98
|
+
this.video.teletextMode = !!(val & 2);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ULA palette register (&FE21).
|
|
102
|
+
_writePalette(val) {
|
|
103
|
+
const index = (val >>> 4) & 0xf;
|
|
104
|
+
this.video.actualPal[index] = val & 0xf;
|
|
105
|
+
// Default: XOR lower 3 bits with 7 for steady colour.
|
|
106
|
+
let colour = this.collook[(val & 0xf) ^ 7];
|
|
107
|
+
// Flash override: if flash bit set, flash globally enabled, and per-colour flash active.
|
|
108
|
+
if (val & 8 && this.video.ulactrl & 1 && this.flash[(val & 7) ^ 7]) {
|
|
109
|
+
colour = this.collook[val & 0xf];
|
|
110
|
+
}
|
|
111
|
+
if (this.video.ulaPal[index] !== colour) {
|
|
112
|
+
this.video.ulaPal[index] = colour;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// NULA control register (&FE22).
|
|
117
|
+
_writeNulaControl(val) {
|
|
118
|
+
const reg = (val >>> 4) & 0xf;
|
|
119
|
+
const param = val & 0xf;
|
|
120
|
+
switch (reg) {
|
|
121
|
+
case 1:
|
|
122
|
+
this.paletteMode = param & 1;
|
|
123
|
+
break;
|
|
124
|
+
case 2:
|
|
125
|
+
this.horizontalOffset = param & 7;
|
|
126
|
+
break;
|
|
127
|
+
case 3:
|
|
128
|
+
this.leftBlank = param & 0xf;
|
|
129
|
+
break;
|
|
130
|
+
case 4:
|
|
131
|
+
this.reset();
|
|
132
|
+
break;
|
|
133
|
+
case 5:
|
|
134
|
+
this.disabled = true;
|
|
135
|
+
break;
|
|
136
|
+
case 6:
|
|
137
|
+
this.attributeMode = param & 3;
|
|
138
|
+
break;
|
|
139
|
+
case 7:
|
|
140
|
+
this.attributeText = param & 1;
|
|
141
|
+
break;
|
|
142
|
+
case 8:
|
|
143
|
+
this.flash[0] = param & 8 ? 1 : 0;
|
|
144
|
+
this.flash[1] = param & 4 ? 1 : 0;
|
|
145
|
+
this.flash[2] = param & 2 ? 1 : 0;
|
|
146
|
+
this.flash[3] = param & 1 ? 1 : 0;
|
|
147
|
+
this._recomputeUlaPal(!!(this.video.ulactrl & 1));
|
|
148
|
+
break;
|
|
149
|
+
case 9:
|
|
150
|
+
this.flash[4] = param & 8 ? 1 : 0;
|
|
151
|
+
this.flash[5] = param & 4 ? 1 : 0;
|
|
152
|
+
this.flash[6] = param & 2 ? 1 : 0;
|
|
153
|
+
this.flash[7] = param & 1 ? 1 : 0;
|
|
154
|
+
this._recomputeUlaPal(!!(this.video.ulactrl & 1));
|
|
155
|
+
break;
|
|
156
|
+
// Regs 14 (border colour) and 15 (blank colour) are stubbed - rendering not yet implemented.
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// NULA palette register (&FE23) - 2-byte write protocol.
|
|
161
|
+
_writeNulaPalette(val) {
|
|
162
|
+
if (this.paletteWriteFlag) {
|
|
163
|
+
const c = (this.paletteFirstByte >>> 4) & 0xf;
|
|
164
|
+
const r = this.paletteFirstByte & 0x0f;
|
|
165
|
+
const g = (val >>> 4) & 0x0f;
|
|
166
|
+
const b = val & 0x0f;
|
|
167
|
+
// Expand 4-bit channels to 8-bit by duplicating the nibble.
|
|
168
|
+
// Store in ABGR format (Uint32Array on little-endian = canvas RGBA).
|
|
169
|
+
this.collook[c] = 0xff000000 | ((b | (b << 4)) << 16) | ((g | (g << 4)) << 8) | (r | (r << 4));
|
|
170
|
+
// Colours 8-15 default to solid (non-flashing) when programmed.
|
|
171
|
+
if (c >= 8) this.flash[c - 8] = 0;
|
|
172
|
+
// Recompute all rendered palette entries from current state.
|
|
173
|
+
this._recomputeUlaPal(!!(this.video.ulactrl & 1));
|
|
174
|
+
// MODE 7 teletext uses its own colour lookup; rebuild when a base colour changes.
|
|
175
|
+
if (c < 8) this.video.teletext.rebuildColours(this.collook);
|
|
35
176
|
} else {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
177
|
+
this.paletteFirstByte = val;
|
|
178
|
+
}
|
|
179
|
+
this.paletteWriteFlag = !this.paletteWriteFlag;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Recompute all 16 ulaPal entries from actualPal + NULA collook + flash state.
|
|
183
|
+
// Follows b-em's palette recomputation logic exactly.
|
|
184
|
+
_recomputeUlaPal(flashEnabled) {
|
|
185
|
+
const video = this.video;
|
|
186
|
+
for (let i = 0; i < 16; ++i) {
|
|
187
|
+
const palVal = video.actualPal[i];
|
|
188
|
+
let colour = this.collook[(palVal & 0xf) ^ 7];
|
|
189
|
+
if (palVal & 8 && flashEnabled && this.flash[(palVal & 7) ^ 7]) {
|
|
190
|
+
colour = this.collook[palVal & 0xf];
|
|
46
191
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.video.halfClock = !(val & 0x10);
|
|
50
|
-
const newMode = (val >>> 2) & 3;
|
|
51
|
-
if (newMode !== this.video.ulaMode) {
|
|
52
|
-
this.video.ulaMode = newMode;
|
|
192
|
+
if (video.ulaPal[i] !== colour) {
|
|
193
|
+
video.ulaPal[i] = colour;
|
|
53
194
|
}
|
|
54
|
-
this.video.teletextMode = !!(val & 2);
|
|
55
195
|
}
|
|
56
196
|
}
|
|
57
197
|
}
|
|
@@ -320,16 +460,20 @@ export class Video {
|
|
|
320
460
|
destOffset |= 0;
|
|
321
461
|
const offset = table4bppOffset(this.ulaMode, dat);
|
|
322
462
|
const fb32 = this.fb32;
|
|
323
|
-
|
|
463
|
+
// In NULA palette mode, bypass the ULA palette (ulaPal) and look up
|
|
464
|
+
// pixel colours directly from the NULA 12-bit colour table (collook).
|
|
465
|
+
// This skips the XOR-7 logical↔physical colour mapping that the
|
|
466
|
+
// standard ULA applies. Reference: b-em src/video.c lines 1083, 1117.
|
|
467
|
+
const colourLookup = this.ula.paletteMode ? this.ula.collook : this.ulaPal;
|
|
324
468
|
const table4bpp = this.table4bpp;
|
|
325
469
|
// Take advantage of numPixels being either 8 or 16
|
|
326
470
|
if (numPixels === 8) {
|
|
327
471
|
for (let i = 0; i < 8; ++i) {
|
|
328
|
-
fb32[destOffset + i] =
|
|
472
|
+
fb32[destOffset + i] = colourLookup[table4bpp[offset + i]];
|
|
329
473
|
}
|
|
330
474
|
} else {
|
|
331
475
|
for (let i = 0; i < 16; ++i) {
|
|
332
|
-
fb32[destOffset + i] =
|
|
476
|
+
fb32[destOffset + i] = colourLookup[table4bpp[offset + i]];
|
|
333
477
|
}
|
|
334
478
|
}
|
|
335
479
|
}
|
|
@@ -656,9 +800,11 @@ export class Video {
|
|
|
656
800
|
// Read data from address pointer if both horizontal and vertical display enabled.
|
|
657
801
|
const dat = this.readVideoMem();
|
|
658
802
|
if (insideBorder) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
803
|
+
// Always feed the SAA5050 pipeline: on real hardware IC15
|
|
804
|
+
// permanently connects the video bus to the SAA5050 inputs
|
|
805
|
+
// regardless of ULA mode. Required for the "TTX trick".
|
|
806
|
+
// See https://github.com/mattgodbolt/jsbeeb/issues/546
|
|
807
|
+
this.teletext.fetchData(dat);
|
|
662
808
|
|
|
663
809
|
// Check cursor start.
|
|
664
810
|
if (
|
|
@@ -691,7 +837,17 @@ export class Video {
|
|
|
691
837
|
|
|
692
838
|
if ((this.dispEnabled & EVERYTHINGENABLED) === EVERYTHINGENABLED) {
|
|
693
839
|
if (this.teletextMode) {
|
|
694
|
-
|
|
840
|
+
if (this.halfClock) {
|
|
841
|
+
// Proper MODE 7 (1MHz clock + teletext): render SAA5050 output normally.
|
|
842
|
+
this.teletext.render(this.fb32, offset);
|
|
843
|
+
} else {
|
|
844
|
+
// 2MHz clock + teletext bit set (the "TTX trick"): the Video ULA
|
|
845
|
+
// forces DISPEN to the SAA5050 to 0 in 2MHz modes (0/1/2/3), so
|
|
846
|
+
// the SAA5050 outputs black. Confirmed by Rich Talbot-Watkins (RTW)
|
|
847
|
+
// at ABUG 2026-03-13.
|
|
848
|
+
// See https://github.com/mattgodbolt/jsbeeb/issues/546
|
|
849
|
+
this.fb32.fill(OPAQUE_BLACK, offset, offset + this.pixelsPerChar);
|
|
850
|
+
}
|
|
695
851
|
} else {
|
|
696
852
|
this.blitFb(dat, offset, this.pixelsPerChar, doubledLines);
|
|
697
853
|
}
|
|
@@ -705,6 +861,14 @@ export class Video {
|
|
|
705
861
|
}
|
|
706
862
|
}
|
|
707
863
|
|
|
864
|
+
// IC37/IC36: during H blanking with V display active, always feed
|
|
865
|
+
// the SAA5050 pipeline with the video bus data, forcing bit 6 high.
|
|
866
|
+
// On real hardware IC37/IC36 operates regardless of ULA mode —
|
|
867
|
+
// it is wired to the CRTC DISPEN signal, not the ULA teletext bit.
|
|
868
|
+
if (!(this.dispEnabled & HDISPENABLE) && this.dispEnabled & VDISPENABLE) {
|
|
869
|
+
this.teletext.fetchData(this.readVideoMem() | 0x40);
|
|
870
|
+
}
|
|
871
|
+
|
|
708
872
|
// CRTC MA always increments, inside display border or not.
|
|
709
873
|
this.addr = (this.addr + 1) & 0x3fff;
|
|
710
874
|
|
|
@@ -777,11 +941,19 @@ export class Video {
|
|
|
777
941
|
|
|
778
942
|
export class FakeVideo {
|
|
779
943
|
constructor() {
|
|
780
|
-
this.
|
|
944
|
+
this.crtc = {
|
|
945
|
+
read: function () {
|
|
946
|
+
return 0xff;
|
|
947
|
+
},
|
|
948
|
+
write: utils.noop,
|
|
949
|
+
};
|
|
950
|
+
this.ula = {
|
|
781
951
|
read: function () {
|
|
782
952
|
return 0xff;
|
|
783
953
|
},
|
|
784
954
|
write: utils.noop,
|
|
955
|
+
reset: utils.noop,
|
|
956
|
+
disabled: false,
|
|
785
957
|
};
|
|
786
958
|
this.regs = new Uint8Array(32);
|
|
787
959
|
}
|
package/src/wd-fdc.js
CHANGED
|
@@ -804,7 +804,12 @@ export class WdFdc {
|
|
|
804
804
|
if (this._indexPulseCount < 6) return;
|
|
805
805
|
if (this._commandType === 1) this._statusRegister |= Status.typeISpinUpDone;
|
|
806
806
|
if (this._isCommandSettle) {
|
|
807
|
-
|
|
807
|
+
// The WD1770 datasheet specifies 30ms head settle, but empirical testing
|
|
808
|
+
// against b-em (which uses 15ms for all WD1770/2 variants) shows 15ms is
|
|
809
|
+
// correct for BBC hardware. Using 30ms causes disc streaming demos (e.g.
|
|
810
|
+
// STNICC-beeb on Master 128) to hang because sectors don't arrive before
|
|
811
|
+
// the first vsync IRQ. The WD1772 also uses 15ms per its datasheet.
|
|
812
|
+
const settleMs = 15;
|
|
808
813
|
this._startTimer(TimerState.settle, settleMs * 1000);
|
|
809
814
|
} else {
|
|
810
815
|
this._dispatchCommand();
|
package/src/web/audio-handler.js
CHANGED
|
@@ -9,7 +9,7 @@ const rendererUrl = new URL("./audio-renderer.js", import.meta.url).href;
|
|
|
9
9
|
const music5000WorkletUrl = new URL("../music5000-worklet.js", import.meta.url).href;
|
|
10
10
|
|
|
11
11
|
export class AudioHandler {
|
|
12
|
-
constructor(warningNode, statsNode, audioFilterFreq, audioFilterQ, noSeek) {
|
|
12
|
+
constructor({ warningNode, statsNode, audioFilterFreq, audioFilterQ, noSeek } = {}) {
|
|
13
13
|
this.warningNode = warningNode;
|
|
14
14
|
this.warningNode.toggle(false);
|
|
15
15
|
this.chart = new SmoothieChart({
|