Skip to content

Commit effbf98

Browse files
committed
Address some review comments by @FallingSnow and myself format and rebuild
1 parent fbebb3d commit effbf98

File tree

8 files changed

+104
-37
lines changed

8 files changed

+104
-37
lines changed

README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,21 @@ allows rebuilding the documentation.
7070

7171
## Performance Benchmarks
7272

73-
As of version `0.4.0`, the whole codebase has been ported to TypeScript, tooling has been modernized and dependencies were updated. The pakcage is now also marked as side-effect free, which allows bundlers to tree-shake the code for unused symbols when imported.
73+
As of version `0.4.0`, the whole codebase has been ported to TypeScript, tooling
74+
has been modernized and dependencies were updated. The package is now also
75+
marked as side-effect free, which allows bundlers to tree-shake the code for
76+
unused symbols when imported.
7477

7578
Alongside these updates, two performance optimizations were introduced:
7679

77-
- `_copy` has been optimized by a loop factor of 16. [`bench`](bench/deinterleave-bench.html)
78-
- `deinterleave` has been optimized by a loop unroll factor of 4. [`bench`](bench/copy-bench.html)
80+
- `_copy` has been optimized by a loop factor of 16.
81+
[`bench`](bench/deinterleave-bench.html)
82+
- `deinterleave` has been optimized by unrolling the loop with a factor of 4.
83+
[`bench`](bench/copy-bench.html)
7984

80-
Early, and limited test results have shown
81-
a substantial performance improvement in buffer copying by **~325%**. For ongoing monitoring in engine behaviour, benchmarks have been added for independent verification of the results.
85+
Early, and limited test results have shown a substantial performance improvement
86+
in buffer copying by **~325%**. For ongoing monitoring in engine behaviour,
87+
benchmarks have been added for independent verification of the results.
8288

8389
## Compatibility
8490

@@ -97,7 +103,7 @@ As of 2023-05-25, the following browsers are compatible:
97103
- Chrome Desktop and Chromium-based browsers (for a long time)
98104
- Chrome for Android
99105
- Safari
100-
106+
101107
## License
102108

103109
Mozilla Public License 2.0

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,17 @@
2222
"types": "./dist/index.d.cts",
2323
"sideEffects": false,
2424
"engines": {
25-
"node": ">=14",
26-
"npm": ">=6"
25+
"node": ">=18",
26+
"npm": ">=9"
2727
},
2828
"keywords": [
2929
"ring buffer",
3030
"shared array buffer",
3131
"thread-safe",
3232
"single-consumer",
3333
"single-producer",
34-
"wait-free"
34+
"wait-free",
35+
"garbage collector"
3536
],
3637
"scripts": {
3738
"build": "pkgroll --sourcemap",

public/example/index.js

Lines changed: 29 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/audioqueue.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import type { RingBuffer } from "./ringbuf.ts";
1111
* where n is the channel count.
1212
* @param output is an array of 128-frames arrays.
1313
*/
14-
export function deinterleave(input: Float32Array, output: Float32Array[]): void {
14+
export function deinterleave(
15+
input: Float32Array,
16+
output: Float32Array[],
17+
): void {
1518
const channel_count = input.length / 128;
1619
if (output.length !== channel_count) {
1720
throw new RangeError(
@@ -20,7 +23,7 @@ export function deinterleave(input: Float32Array, output: Float32Array[]): void
2023
}
2124

2225
/* Original algorithm:
23-
26+
2427
for (let i = 0; i < channel_count; i++) {
2528
const out_channel = output[i];
2629
let interleaved_idx = i;

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export {
44
deinterleave,
55
interleave,
66
} from "./audioqueue.js";
7-
export { ParameterReader, ParameterWriter } from "./param.js";
8-
export { RingBuffer } from "./ringbuf.js";
7+
export { ParameterReader, ParameterWriter } from "./param";
8+
export { RingBuffer } from "./ringbuf";

src/param.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,29 @@ export class ParameterWriter {
4848
* @param value The value of the parameter.
4949
* @return True if enqueuing succeeded, false otherwise.
5050
*/
51-
enqueue_change(index: number, value: number): boolean {
51+
enqueueChange(index: number, value: number): boolean {
5252
const SIZE_ELEMENT = 5;
5353
if (this.ringbuf.availableWrite() < SIZE_ELEMENT) {
5454
return false;
5555
}
5656
this.view.setUint8(0, index);
57-
this.view.setFloat32(1, value);
57+
this.view.setFloat32(1, value);
5858
return this.ringbuf.push(this.array) === SIZE_ELEMENT;
5959
}
60+
61+
/**
62+
* Enqueue a parameter change for parameter of index `index`, with a new value
63+
* of `value`.
64+
*
65+
* @param index The index of the parameter.
66+
* @param value The value of the parameter.
67+
* @return True if enqueuing succeeded, false otherwise.
68+
*
69+
* @deprecated
70+
*/
71+
enqueue_change(index: number, value: number): boolean {
72+
return this.enqueueChange(index, value);
73+
}
6074
}
6175

6276
/**
@@ -99,7 +113,7 @@ export class ParameterReader {
99113
* @param o An object with two attributes: `index` and `value`.
100114
* @return true if a parameter change has been dequeued, false otherwise.
101115
*/
102-
dequeue_change(o: { index: number; value: number }): boolean {
116+
dequeueChange(o: { index: number; value: number }): boolean {
103117
if (this.ringbuf.empty()) {
104118
return false;
105119
}
@@ -109,4 +123,15 @@ export class ParameterReader {
109123

110124
return rv === this.array.length;
111125
}
126+
127+
/**
128+
* Attempt to dequeue a single parameter change.
129+
* @param o An object with two attributes: `index` and `value`.
130+
* @return true if a parameter change has been dequeued, false otherwise.
131+
*
132+
* @deprecated
133+
*/
134+
dequeue_change(o: { index: number; value: number }): boolean {
135+
return this.dequeueChange(o);
136+
}
112137
}

src/ringbuf.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import type { RingBufferWriteCallback, RingBufferWriteCallbackWithOffset, TypedArray, TypedArrayConstructor } from "./types";
2-
3-
/**
1+
import type {
2+
RingBufferWriteCallback,
3+
RingBufferWriteCallbackWithOffset,
4+
TypedArray,
5+
TypedArrayConstructor,
6+
} from "./types";
7+
8+
/**
49
* The base RingBuffer class
510
*
611
* A Single Producer - Single Consumer thread-safe wait-free ring buffer.
@@ -9,7 +14,6 @@ import type { RingBufferWriteCallback, RingBufferWriteCallbackWithOffset, TypedA
914
* except with external synchronization.
1015
*/
1116
export class RingBuffer {
12-
1317
/** Allocate the SharedArrayBuffer for a RingBuffer, based on the type and
1418
* capacity required
1519
* @param capacity The number of elements the ring buffer will be
@@ -18,7 +22,10 @@ export class RingBuffer {
1822
* buffer will hold.
1923
* @return A SharedArrayBuffer of the right size.
2024
*/
21-
static getStorageForCapacity(capacity: number, type: TypedArrayConstructor): SharedArrayBuffer {
25+
static getStorageForCapacity(
26+
capacity: number,
27+
type: TypedArrayConstructor,
28+
): SharedArrayBuffer {
2229
if (!type.BYTES_PER_ELEMENT) {
2330
throw TypeError("Pass in an ArrayBuffer subclass");
2431
}
@@ -80,7 +87,7 @@ export class RingBuffer {
8087

8188
if ((wr + 1) % this._storage_capacity() === rd) {
8289
// full
83-
return 0;
90+
return 0;
8491
}
8592

8693
const len = length !== undefined ? length : elements.length;
@@ -94,9 +101,9 @@ export class RingBuffer {
94101

95102
// publish the enqueued data to the other side
96103
Atomics.store(
97-
this.write_ptr,
98-
0,
99-
(wr + to_write) % this._storage_capacity()
104+
this.write_ptr,
105+
0,
106+
(wr + to_write) % this._storage_capacity(),
100107
);
101108

102109
return to_write;
@@ -179,7 +186,10 @@ export class RingBuffer {
179186
* been written started at the beginning of the requested buffer space.
180187
* @return The number of elements written to the queue.
181188
*/
182-
writeCallbackWithOffset(amount: number, cb: RingBufferWriteCallbackWithOffset) {
189+
writeCallbackWithOffset(
190+
amount: number,
191+
cb: RingBufferWriteCallbackWithOffset,
192+
) {
183193
const rd = Atomics.load(this.read_ptr, 0);
184194
const wr = Atomics.load(this.write_ptr, 0);
185195

@@ -233,7 +243,7 @@ export class RingBuffer {
233243
this._copy(this.storage, 0, elements, offset + first_part, second_part);
234244

235245
Atomics.store(this.read_ptr, 0, (rd + to_read) % this._storage_capacity());
236-
246+
237247
return to_read;
238248
}
239249

@@ -292,7 +302,7 @@ export class RingBuffer {
292302
return this.availableRead();
293303
}
294304

295-
/**
305+
/**
296306
* @return The number of elements available for writing. This can be late, and
297307
* report less elements that is actually available for writing, when something
298308
* has just been dequeued.
@@ -360,9 +370,8 @@ export class RingBuffer {
360370
offset_input: number,
361371
output: TypedArray,
362372
offset_output: number,
363-
size: number
373+
size: number,
364374
): void {
365-
366375
if (!size) {
367376
return;
368377
}
@@ -416,4 +425,4 @@ export class RingBuffer {
416425
output[offset_output + i] = input[offset_input + i];
417426
}
418427
}
419-
}
428+
}
File renamed without changes.

0 commit comments

Comments
 (0)