@ain1084/audio-worklet-stream 0.1.8 → 1.0.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 (57) hide show
  1. package/README.md +12 -27
  2. package/dist/events.d.ts +6 -6
  3. package/dist/events.js +8 -8
  4. package/dist/events.js.map +1 -1
  5. package/dist/frame-buffer/buffer-config.d.ts +67 -0
  6. package/dist/frame-buffer/buffer-config.js +64 -0
  7. package/dist/frame-buffer/buffer-config.js.map +1 -0
  8. package/dist/frame-buffer/buffer-factory.d.ts +1 -2
  9. package/dist/frame-buffer/buffer-factory.js +6 -3
  10. package/dist/frame-buffer/buffer-factory.js.map +1 -1
  11. package/dist/frame-buffer/buffer-reader.d.ts +29 -10
  12. package/dist/frame-buffer/buffer-reader.js +37 -16
  13. package/dist/frame-buffer/buffer-reader.js.map +1 -1
  14. package/dist/frame-buffer/buffer-utils.js +2 -2
  15. package/dist/frame-buffer/buffer-utils.js.map +1 -1
  16. package/dist/frame-buffer/buffer-writer.d.ts +31 -12
  17. package/dist/frame-buffer/buffer-writer.js +39 -18
  18. package/dist/frame-buffer/buffer-writer.js.map +1 -1
  19. package/dist/frame-buffer/buffer.d.ts +33 -22
  20. package/dist/frame-buffer/buffer.js +50 -40
  21. package/dist/frame-buffer/buffer.js.map +1 -1
  22. package/dist/output-message.d.ts +9 -9
  23. package/dist/output-stream-node.d.ts +13 -19
  24. package/dist/output-stream-node.js +20 -26
  25. package/dist/output-stream-node.js.map +1 -1
  26. package/dist/output-stream-processor.js +25 -18
  27. package/dist/output-stream-processor.js.map +1 -1
  28. package/dist/stream-node-factory.d.ts +10 -0
  29. package/dist/stream-node-factory.js +27 -12
  30. package/dist/stream-node-factory.js.map +1 -1
  31. package/dist/write-strategy/manual.d.ts +1 -1
  32. package/dist/write-strategy/manual.js +1 -1
  33. package/dist/write-strategy/manual.js.map +1 -1
  34. package/dist/write-strategy/timed.d.ts +1 -1
  35. package/dist/write-strategy/timed.js +1 -1
  36. package/dist/write-strategy/timed.js.map +1 -1
  37. package/dist/write-strategy/worker/message.d.ts +1 -1
  38. package/dist/write-strategy/worker/strategy.d.ts +1 -1
  39. package/dist/write-strategy/worker/worker.js +1 -1
  40. package/dist/write-strategy/worker/worker.js.map +1 -1
  41. package/package.json +9 -9
  42. package/src/events.ts +4 -4
  43. package/src/frame-buffer/buffer-config.ts +129 -0
  44. package/src/frame-buffer/buffer-reader.ts +37 -16
  45. package/src/frame-buffer/buffer-writer.ts +39 -18
  46. package/src/frame-buffer/buffer.ts +51 -40
  47. package/src/output-message.ts +9 -9
  48. package/src/output-stream-node.ts +23 -29
  49. package/src/output-stream-processor.ts +25 -18
  50. package/src/stream-node-factory.ts +33 -15
  51. package/src/write-strategy/manual.ts +1 -1
  52. package/src/write-strategy/timed.ts +1 -1
  53. package/src/write-strategy/worker/message.ts +1 -1
  54. package/src/write-strategy/worker/strategy.ts +1 -1
  55. package/src/write-strategy/worker/worker.ts +1 -1
  56. package/src/frame-buffer/buffer-factory.ts +0 -115
  57. package/src/frame-buffer/buffer-utils.ts +0 -48
@@ -1,4 +1,3 @@
1
- import { enumFrames } from './buffer-utils';
2
1
  /**
3
2
  * FrameBufferWriter class
4
3
  * This class writes audio frame data to a shared Float32Array buffer.
@@ -6,46 +5,68 @@ import { enumFrames } from './buffer-utils';
6
5
  */
7
6
  export class FrameBufferWriter {
8
7
  _frameBuffer;
9
- _usedFrameInBuffer;
8
+ _usedFramesInBuffer;
10
9
  _totalFrames;
11
10
  _index = 0;
12
11
  /**
13
12
  * Creates an instance of FrameBufferWriter.
14
13
  * @param frameBuffer - The shared buffer to write to.
15
- * @param usedFrameInBuffer - The Uint32Array tracking the usage of the buffer.
14
+ * @param usedFramesInBuffer - The Uint32Array tracking the usage of the buffer.
16
15
  * @param totalFrames - The BigUint64Array tracking the total frames written to the buffer.
17
16
  */
18
- constructor(frameBuffer, usedFrameInBuffer, totalFrames) {
17
+ constructor(frameBuffer, usedFramesInBuffer, totalFrames) {
19
18
  this._frameBuffer = frameBuffer;
20
- this._usedFrameInBuffer = usedFrameInBuffer;
19
+ this._usedFramesInBuffer = usedFramesInBuffer;
21
20
  this._totalFrames = totalFrames;
22
21
  }
23
22
  /**
24
- * Get the number of available spaces in the buffer.
25
- * @returns The number of available spaces in the buffer.
23
+ * Get the number of available frames in the buffer.
24
+ * This represents the number of frames that can be written before the buffer is full.
25
+ * @returns The number of available frames in the buffer.
26
26
  */
27
- get available() {
28
- return this._frameBuffer.length - Atomics.load(this._usedFrameInBuffer, 0);
27
+ get availableFrames() {
28
+ return this._frameBuffer.frameCount - Atomics.load(this._usedFramesInBuffer, 0);
29
29
  }
30
30
  /**
31
31
  * Get the total number of frames written to the buffer.
32
+ *
32
33
  * @returns The total number of frames written.
33
34
  */
34
35
  get totalFrames() {
36
+ // This class is not used concurrently by multiple threads,
37
+ // so `Atomics` is not necessary when reading `totalFrames`.
35
38
  return this._totalFrames[0];
36
39
  }
37
40
  /**
38
- * Write audio frame data to the buffer using the provided frameCallback.
39
- * @param frameCallback - The frameCallback function to process each section of the buffer.
40
- * @returns The number of frames processed.
41
- * @throws RangeError - If the processed length exceeds the part length.
41
+ * Writes audio frame data into the buffer using the provided callback.
42
+ * This method handles one or more writable segments within the ring buffer
43
+ * and invokes the callback for each segment.
44
+ *
45
+ * @param processFrameSegment - The callback function invoked for each writable segment
46
+ * of the ring buffer. It receives:
47
+ * 1. `buffer`: A Float32Array representing the writable segment of the buffer.
48
+ * 2. `offset`: The cumulative number of frames processed so far, used as the starting index
49
+ * for the current segment relative to the entire data.
50
+ * The callback must return the number of frames it successfully wrote.
51
+ * If the callback writes fewer frames than available in the current segment,
52
+ * processing will stop early.
53
+ *
54
+ * @returns The total number of frames written across all segments.
55
+ * Note: The return value is in frames, not in samples.
56
+ *
57
+ * @throws RangeError - If the processFrameSegment callback returns a written length greater than the available space in the current segment.
58
+ *
59
+ * @remarks The buffer is an array of samples, but it is always provided in frame-sized segments.
60
+ * Each frame consists of multiple samples (e.g., for stereo, a frame contains a sample for the left channel
61
+ * and one for the right channel). You must access and process the buffer in frame-sized chunks,
62
+ * based on the structure of the frames.
42
63
  */
43
- write(frameCallback) {
44
- const result = enumFrames(this._frameBuffer, this._index, this.available, frameCallback);
64
+ write(processFrameSegment) {
65
+ const result = this._frameBuffer.enumFrameSegments(this._index, this.availableFrames, processFrameSegment);
45
66
  this._index = result.nextIndex;
46
- Atomics.add(this._usedFrameInBuffer, 0, result.frames);
47
- Atomics.add(this._totalFrames, 0, BigInt(result.frames));
48
- return result.frames;
67
+ Atomics.add(this._usedFramesInBuffer, 0, result.totalProcessedFrames);
68
+ Atomics.add(this._totalFrames, 0, BigInt(result.totalProcessedFrames));
69
+ return result.totalProcessedFrames;
49
70
  }
50
71
  }
51
72
  //# sourceMappingURL=buffer-writer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buffer-writer.js","sourceRoot":"","sources":["../../src/frame-buffer/buffer-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,gBAAgB,CAAA;AAG/D;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IACX,YAAY,CAAa;IACzB,kBAAkB,CAAa;IAC/B,YAAY,CAAgB;IACrC,MAAM,GAAW,CAAC,CAAA;IAE1B;;;;;OAKG;IACH,YAAY,WAAwB,EAAE,iBAA8B,EAAE,WAA2B;QAC/F,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;QAC/B,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAA;QAC3C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;IACjC,CAAC;IAED;;;OAGG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED;;;OAGG;IACH,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,aAA4B;QACvC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACxF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAA;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;QACxD,OAAO,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;CACF"}
1
+ {"version":3,"file":"buffer-writer.js","sourceRoot":"","sources":["../../src/frame-buffer/buffer-writer.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IACX,YAAY,CAAa;IACzB,mBAAmB,CAAa;IAChC,YAAY,CAAgB;IACrC,MAAM,GAAW,CAAC,CAAA;IAE1B;;;;;OAKG;IACH,YAAY,WAAwB,EAAE,kBAA+B,EAAE,WAA2B;QAChG,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;QAC/B,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAA;QAC7C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAA;IACjF,CAAC;IAED;;;;OAIG;IACH,IAAW,WAAW;QACpB,2DAA2D;QAC3D,4DAA4D;QAC5D,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACI,KAAK,CAAC,mBAAqE;QAChF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAA;QAC1G,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAA;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;QACrE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACtE,OAAO,MAAM,CAAC,oBAAoB,CAAA;IACpC,CAAC;CACF"}
@@ -5,7 +5,7 @@
5
5
  export declare class FrameBuffer {
6
6
  private readonly _buffer;
7
7
  private readonly _samplesPerFrame;
8
- private readonly _length;
8
+ private readonly _frameCount;
9
9
  /**
10
10
  * Creates an instance of FrameBuffer.
11
11
  * @param buffer - The Float32Array buffer to manage.
@@ -13,28 +13,39 @@ export declare class FrameBuffer {
13
13
  */
14
14
  constructor(buffer: Float32Array, samplesPerFrame: number);
15
15
  /**
16
- * Sets the frame data in the buffer.
17
- * @param index - The starting index in the buffer.
18
- * @param samples - The samples to set in the buffer.
19
- * @param sampleStart - The starting position in the samples array (default is 0).
20
- * @param sampleCount - The number of samples to set (default is the length of the samples array).
21
- * @returns A number of written frames.
22
- * @throws Error - If the number of samples per frame does not match the specified number of samples.
16
+ * Gets the count of the buffer in frames.
17
+ * @returns The count of the buffer in frames.
23
18
  */
24
- setFrames(index: number, samples: Float32Array, sampleStart?: number, sampleCount?: number): number;
19
+ get frameCount(): number;
20
+ private getFrames;
25
21
  /**
26
- * Converts the frame data to output.
27
- * This method is intended to be called from within the process method of the AudioWorkletProcessor.
28
- * It converts the interleaved frame data to the structure expected by the process method's outputs.
29
- * @param frameIndex - The index of the frame to convert.
30
- * @param frames - The number of frames to convert.
31
- * @param output - The output array to store the converted data.
32
- * @param outputOffset - The offset in the output array at which to start storing the data.
22
+ * Processes sections of a Float32Array buffer using a callback function.
23
+ * This function handles one or more segments within the ring buffer and invokes
24
+ * the provided callback for each segment. It is intended for internal use only.
25
+ *
26
+ * @param startIndex - The starting index in the buffer from where processing should begin.
27
+ * @param availableFrames - The total number of frames available to process in the buffer.
28
+ * @param processFrameSegment - The callback function invoked for each segment
29
+ * of the ring buffer during enumeration. It receives:
30
+ * 1. `buffer`: A Float32Array representing the segment to process. The buffer is an array
31
+ * of samples but is always provided in frame-sized segments.
32
+ * 2. `offset`: The cumulative number of frames processed so far, used as the starting index
33
+ * for the current segment relative to the entire data.
34
+ * The callback must return the number of frames it successfully processed.
35
+ * If the callback processes fewer frames than available in the current segment,
36
+ * processing will stop early.
37
+ *
38
+ * @returns An object containing:
39
+ * - totalProcessedFrames: The number of frames successfully processed.
40
+ * - nextIndex: The index in the buffer for the next processing cycle.
41
+ *
42
+ * @throws RangeError - If the processFrameSegment callback returns a processed length greater than the available section length.
43
+ *
44
+ * @remarks The buffer is always provided in frame-sized segments, meaning that the buffer contains complete frames.
45
+ * You must process the buffer in frame-sized chunks based on the structure of the frames.
33
46
  */
34
- convertToOutput(frameIndex: number, frames: number, output: Float32Array[], outputOffset: number): void;
35
- /**
36
- * Gets the length of the buffer in frames.
37
- * @returns The length of the buffer in frames.
38
- */
39
- get length(): number;
47
+ enumFrameSegments(startIndex: number, availableFrames: number, processFrameSegment: (buffer: Float32Array, offset: number) => number): {
48
+ totalProcessedFrames: number;
49
+ nextIndex: number;
50
+ };
40
51
  }
@@ -5,7 +5,7 @@
5
5
  export class FrameBuffer {
6
6
  _buffer;
7
7
  _samplesPerFrame;
8
- _length;
8
+ _frameCount;
9
9
  /**
10
10
  * Creates an instance of FrameBuffer.
11
11
  * @param buffer - The Float32Array buffer to manage.
@@ -14,52 +14,62 @@ export class FrameBuffer {
14
14
  constructor(buffer, samplesPerFrame) {
15
15
  this._buffer = buffer;
16
16
  this._samplesPerFrame = samplesPerFrame;
17
- this._length = Math.floor(buffer.length / samplesPerFrame);
17
+ this._frameCount = Math.floor(buffer.length / samplesPerFrame);
18
18
  }
19
19
  /**
20
- * Sets the frame data in the buffer.
21
- * @param index - The starting index in the buffer.
22
- * @param samples - The samples to set in the buffer.
23
- * @param sampleStart - The starting position in the samples array (default is 0).
24
- * @param sampleCount - The number of samples to set (default is the length of the samples array).
25
- * @returns A number of written frames.
26
- * @throws Error - If the number of samples per frame does not match the specified number of samples.
20
+ * Gets the count of the buffer in frames.
21
+ * @returns The count of the buffer in frames.
27
22
  */
28
- setFrames(index, samples, sampleStart = 0, sampleCount) {
29
- index *= this._samplesPerFrame;
30
- const sampleEnd = (sampleCount !== undefined) ? Math.min(sampleStart + sampleCount, samples.length) : samples.length;
31
- const frames = (sampleEnd - sampleStart) / this._samplesPerFrame;
32
- if (!Number.isInteger(frames)) {
33
- throw new Error(`Error: The number of samples per frame does not match the specified number of samples. Expected samples per frame: ${this._samplesPerFrame}, but got: ${sampleEnd - sampleStart}.`);
34
- }
35
- for (let sampleIndex = sampleStart; sampleIndex < sampleEnd; ++sampleIndex, ++index) {
36
- this._buffer[index] = samples[sampleIndex];
37
- }
38
- return frames;
23
+ get frameCount() {
24
+ return this._frameCount;
39
25
  }
40
- /**
41
- * Converts the frame data to output.
42
- * This method is intended to be called from within the process method of the AudioWorkletProcessor.
43
- * It converts the interleaved frame data to the structure expected by the process method's outputs.
44
- * @param frameIndex - The index of the frame to convert.
45
- * @param frames - The number of frames to convert.
46
- * @param output - The output array to store the converted data.
47
- * @param outputOffset - The offset in the output array at which to start storing the data.
48
- */
49
- convertToOutput(frameIndex, frames, output, outputOffset) {
50
- const samplesPerFrame = this._samplesPerFrame;
51
- output.forEach((outputChannel, channelNumber) => {
52
- for (let i = channelNumber, j = 0; j < frames; i += samplesPerFrame, ++j) {
53
- outputChannel[outputOffset + j] = this._buffer[frameIndex + i];
54
- }
55
- });
26
+ getFrames(index, count) {
27
+ return this._buffer.subarray(index * this._samplesPerFrame, (index + count) * this._samplesPerFrame);
56
28
  }
57
29
  /**
58
- * Gets the length of the buffer in frames.
59
- * @returns The length of the buffer in frames.
30
+ * Processes sections of a Float32Array buffer using a callback function.
31
+ * This function handles one or more segments within the ring buffer and invokes
32
+ * the provided callback for each segment. It is intended for internal use only.
33
+ *
34
+ * @param startIndex - The starting index in the buffer from where processing should begin.
35
+ * @param availableFrames - The total number of frames available to process in the buffer.
36
+ * @param processFrameSegment - The callback function invoked for each segment
37
+ * of the ring buffer during enumeration. It receives:
38
+ * 1. `buffer`: A Float32Array representing the segment to process. The buffer is an array
39
+ * of samples but is always provided in frame-sized segments.
40
+ * 2. `offset`: The cumulative number of frames processed so far, used as the starting index
41
+ * for the current segment relative to the entire data.
42
+ * The callback must return the number of frames it successfully processed.
43
+ * If the callback processes fewer frames than available in the current segment,
44
+ * processing will stop early.
45
+ *
46
+ * @returns An object containing:
47
+ * - totalProcessedFrames: The number of frames successfully processed.
48
+ * - nextIndex: The index in the buffer for the next processing cycle.
49
+ *
50
+ * @throws RangeError - If the processFrameSegment callback returns a processed length greater than the available section length.
51
+ *
52
+ * @remarks The buffer is always provided in frame-sized segments, meaning that the buffer contains complete frames.
53
+ * You must process the buffer in frame-sized chunks based on the structure of the frames.
60
54
  */
61
- get length() {
62
- return this._length;
55
+ enumFrameSegments(startIndex, availableFrames, processFrameSegment) {
56
+ let totalProcessedFrames = 0;
57
+ while (totalProcessedFrames < availableFrames) {
58
+ // Determine the length of the current section to process
59
+ const sectionFrames = Math.min(this.frameCount - startIndex, availableFrames - totalProcessedFrames);
60
+ // Process the current section using the frameCallback function
61
+ const processedFrames = processFrameSegment(this.getFrames(startIndex, sectionFrames), totalProcessedFrames);
62
+ // Ensure the processed length does not exceed the section length
63
+ if (processedFrames > sectionFrames) {
64
+ throw new RangeError(`Processed frames (${processedFrames}) exceeds section frames (${sectionFrames})`);
65
+ }
66
+ totalProcessedFrames += processedFrames;
67
+ startIndex = (startIndex + processedFrames) % this.frameCount;
68
+ if (processedFrames < sectionFrames) {
69
+ break;
70
+ }
71
+ }
72
+ return { totalProcessedFrames, nextIndex: startIndex };
63
73
  }
64
74
  }
65
75
  //# sourceMappingURL=buffer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../src/frame-buffer/buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACL,OAAO,CAAc;IACrB,gBAAgB,CAAQ;IACxB,OAAO,CAAQ;IAEhC;;;;OAIG;IACH,YAAmB,MAAoB,EAAE,eAAuB;QAC9D,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAA;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,CAAA;IAC5D,CAAC;IAED;;;;;;;;OAQG;IACI,SAAS,CAAC,KAAa,EAAE,OAAqB,EAAE,cAAsB,CAAC,EAAE,WAAoB;QAClG,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAA;QAC9B,MAAM,SAAS,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;QACpH,MAAM,MAAM,GAAG,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAA;QAChE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sHAAsH,IAAI,CAAC,gBAAgB,cAAc,SAAS,GAAG,WAAW,GAAG,CAAC,CAAA;QACtM,CAAC;QACD,KAAK,IAAI,WAAW,GAAG,WAAW,EAAE,WAAW,GAAG,SAAS,EAAE,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC;YACpF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,eAAe,CAAC,UAAkB,EAAE,MAAc,EAAE,MAAsB,EAAE,YAAoB;QACrG,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAA;QAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE;YAC9C,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC;gBACzE,aAAa,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;YAChE,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;OAGG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../src/frame-buffer/buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACL,OAAO,CAAc;IACrB,gBAAgB,CAAQ;IACxB,WAAW,CAAQ;IAEpC;;;;OAIG;IACH,YAAmB,MAAoB,EAAE,eAAuB;QAC9D,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAA;QACvC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,CAAA;IAChE,CAAC;IAED;;;OAGG;IACH,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAEO,SAAS,CAAC,KAAa,EAAE,KAAa;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAA;IACtG,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACI,iBAAiB,CAAC,UAAkB,EAAE,eAAuB,EAClE,mBAAqE;QACrE,IAAI,oBAAoB,GAAG,CAAC,CAAA;QAC5B,OAAO,oBAAoB,GAAG,eAAe,EAAE,CAAC;YAC9C,yDAAyD;YACzD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,UAAU,EAAE,eAAe,GAAG,oBAAoB,CAAC,CAAA;YACpG,+DAA+D;YAC/D,MAAM,eAAe,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,oBAAoB,CAAC,CAAA;YAC5G,iEAAiE;YACjE,IAAI,eAAe,GAAG,aAAa,EAAE,CAAC;gBACpC,MAAM,IAAI,UAAU,CAAC,qBAAqB,eAAe,6BAA6B,aAAa,GAAG,CAAC,CAAA;YACzG,CAAC;YACD,oBAAoB,IAAI,eAAe,CAAA;YACvC,UAAU,GAAG,CAAC,UAAU,GAAG,eAAe,CAAC,GAAG,IAAI,CAAC,UAAU,CAAA;YAC7D,IAAI,eAAe,GAAG,aAAa,EAAE,CAAC;gBACpC,MAAK;YACP,CAAC;QACH,CAAC;QACD,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;IACxD,CAAC;CACF"}
@@ -4,24 +4,24 @@
4
4
  * @typeParam type - The type of message. Can be 'stop' or 'underrun'.
5
5
  *
6
6
  * For 'stop' messages:
7
- * @property frames - The total frames processed when stopped.
7
+ * @property totalProcessedFrames - The total frames processed when stopped.
8
8
  *
9
9
  * For 'underrun' messages:
10
- * @property frames - The number of frames that have been underrun.
10
+ * @property underrunFrameCount - The number of frames that have been underrun.
11
11
  *
12
12
  * Example:
13
13
  * ```typescript
14
- * const message: MessageToAudioNode = { type: 'stop', frames: 1000n };
14
+ * const message: MessageToAudioNode = { type: 'stop', totalProcessedFrames: 1000n };
15
15
  * // or
16
- * const message: MessageToAudioNode = { type: 'underrun', frames: 256 };
16
+ * const message: MessageToAudioNode = { type: 'underrun', underrunFrameCount: 256 };
17
17
  * ```
18
18
  */
19
19
  export type MessageToAudioNode = {
20
20
  type: 'stop';
21
- frames: bigint;
21
+ totalProcessedFrames: bigint;
22
22
  } | {
23
23
  type: 'underrun';
24
- frames: number;
24
+ underrunFrameCount: number;
25
25
  };
26
26
  /**
27
27
  * Messages sent from the main thread to the processor.
@@ -29,14 +29,14 @@ export type MessageToAudioNode = {
29
29
  * @typeParam type - The type of message. Can be 'stop'.
30
30
  *
31
31
  * For 'stop' messages:
32
- * @property frames - The position in frames to stop at.
32
+ * @property framePosition - The position in frames to stop at.
33
33
  *
34
34
  * Example:
35
35
  * ```typescript
36
- * const message: MessageToProcessor = { type: 'stop', frames: 1000n };
36
+ * const message: MessageToProcessor = { type: 'stop', framePosition: 1000n };
37
37
  * ```
38
38
  */
39
39
  export type MessageToProcessor = {
40
40
  type: 'stop';
41
- frames: bigint;
41
+ framePosition: bigint;
42
42
  };
@@ -1,5 +1,5 @@
1
1
  import { BufferWriteStrategy } from './write-strategy/strategy';
2
- import { FrameBufferConfig } from './frame-buffer/buffer-factory';
2
+ import { FrameBufferConfig } from './frame-buffer/buffer-config';
3
3
  /**
4
4
  * Stream state
5
5
  * Represents the different states of the stream.
@@ -21,7 +21,15 @@ export declare class OutputStreamNode extends AudioWorkletNode {
21
21
  * @param bufferConfig - The configuration for the buffer.
22
22
  * @param strategy - The strategy for writing to the buffer.
23
23
  */
24
- protected constructor(baseAudioContext: BaseAudioContext, bufferConfig: FrameBufferConfig, strategy: BufferWriteStrategy);
24
+ private constructor();
25
+ /**
26
+ * Creates an instance of OutputStreamNode.
27
+ * @param audioContext - The audio context to use.
28
+ * @param info - The configuration for the buffer.
29
+ * @param strategy - The strategy for writing to the buffer.
30
+ * @returns A promise that resolves to an instance of OutputStreamNode.
31
+ */
32
+ static create(audioContext: BaseAudioContext, info: FrameBufferConfig, strategy: BufferWriteStrategy): Promise<OutputStreamNode>;
25
33
  /**
26
34
  * Start playback.
27
35
  * The node must be connected before starting playback using connect() method.
@@ -34,12 +42,12 @@ export declare class OutputStreamNode extends AudioWorkletNode {
34
42
  * Stop the node processing at a given frame position.
35
43
  * Returns a Promise that resolves when the node has completely stopped.
36
44
  * The node is disconnected once stopping is complete.
37
- * @param frames - The frame position at which to stop the processing, in frames.
38
- * If frames is 0 or if the current playback frame position has already passed the specified value,
45
+ * @param framePosition - The frame position at which to stop the processing, in frames.
46
+ * If framePosition is 0 or if the current playback frame position has already passed the specified value,
39
47
  * the node will stop immediately.
40
48
  * @returns A promise that resolves when the node has stopped.
41
49
  */
42
- stop(frames?: bigint): Promise<void>;
50
+ stop(framePosition?: bigint): Promise<void>;
43
51
  /**
44
52
  * Handles incoming messages from the audio processor.
45
53
  * @param event - The message event from the processor.
@@ -77,17 +85,3 @@ export declare class OutputStreamNode extends AudioWorkletNode {
77
85
  */
78
86
  get totalWriteFrames(): bigint;
79
87
  }
80
- /**
81
- * OutputStreamNodeFactory class
82
- * Factory class to create instances of OutputStreamNode.
83
- */
84
- export declare class OutputStreamNodeFactory extends OutputStreamNode {
85
- /**
86
- * Creates an instance of OutputStreamNodeFactory.
87
- * @param audioContext - The audio context to use.
88
- * @param info - The configuration for the buffer.
89
- * @param strategy - The strategy for writing to the buffer.
90
- * @returns A promise that resolves to an instance of OutputStreamNodeFactory.
91
- */
92
- static create(audioContext: BaseAudioContext, info: FrameBufferConfig, strategy: BufferWriteStrategy): Promise<OutputStreamNode>;
93
- }
@@ -30,6 +30,20 @@ export class OutputStreamNode extends AudioWorkletNode {
30
30
  this._totalReadFrames = bufferConfig.totalReadFrames;
31
31
  this.port.onmessage = this.handleMessage.bind(this);
32
32
  }
33
+ /**
34
+ * Creates an instance of OutputStreamNode.
35
+ * @param audioContext - The audio context to use.
36
+ * @param info - The configuration for the buffer.
37
+ * @param strategy - The strategy for writing to the buffer.
38
+ * @returns A promise that resolves to an instance of OutputStreamNode.
39
+ */
40
+ static async create(audioContext, info, strategy) {
41
+ const node = new OutputStreamNode(audioContext, info, strategy);
42
+ if (!(await strategy.onInit(node))) {
43
+ throw new Error('Failed to onInit.');
44
+ }
45
+ return node;
46
+ }
33
47
  /**
34
48
  * Start playback.
35
49
  * The node must be connected before starting playback using connect() method.
@@ -58,17 +72,17 @@ export class OutputStreamNode extends AudioWorkletNode {
58
72
  * Stop the node processing at a given frame position.
59
73
  * Returns a Promise that resolves when the node has completely stopped.
60
74
  * The node is disconnected once stopping is complete.
61
- * @param frames - The frame position at which to stop the processing, in frames.
62
- * If frames is 0 or if the current playback frame position has already passed the specified value,
75
+ * @param framePosition - The frame position at which to stop the processing, in frames.
76
+ * If framePosition is 0 or if the current playback frame position has already passed the specified value,
63
77
  * the node will stop immediately.
64
78
  * @returns A promise that resolves when the node has stopped.
65
79
  */
66
- stop(frames = BigInt(0)) {
80
+ stop(framePosition = BigInt(0)) {
67
81
  switch (this._state) {
68
82
  case 'started':
69
83
  return new Promise((resolve) => {
70
84
  this._state = 'stopping';
71
- const message = { type: 'stop', frames };
85
+ const message = { type: 'stop', framePosition: framePosition };
72
86
  this.port.postMessage(message);
73
87
  this.addEventListener(StopEvent.type, () => {
74
88
  resolve();
@@ -94,10 +108,10 @@ export class OutputStreamNode extends AudioWorkletNode {
94
108
  switch (event.data.type) {
95
109
  case 'stop':
96
110
  this.handleStopped();
97
- this.dispatchEvent(new StopEvent(event.data.frames));
111
+ this.dispatchEvent(new StopEvent(event.data.totalProcessedFrames));
98
112
  break;
99
113
  case 'underrun':
100
- this.dispatchEvent(new UnderrunEvent(event.data.frames));
114
+ this.dispatchEvent(new UnderrunEvent(event.data.underrunFrameCount));
101
115
  break;
102
116
  default:
103
117
  throw new Error(`Unexpected event value: ${event.data}`);
@@ -147,24 +161,4 @@ export class OutputStreamNode extends AudioWorkletNode {
147
161
  return Atomics.load(this._totalWriteFrames, 0);
148
162
  }
149
163
  }
150
- /**
151
- * OutputStreamNodeFactory class
152
- * Factory class to create instances of OutputStreamNode.
153
- */
154
- export class OutputStreamNodeFactory extends OutputStreamNode {
155
- /**
156
- * Creates an instance of OutputStreamNodeFactory.
157
- * @param audioContext - The audio context to use.
158
- * @param info - The configuration for the buffer.
159
- * @param strategy - The strategy for writing to the buffer.
160
- * @returns A promise that resolves to an instance of OutputStreamNodeFactory.
161
- */
162
- static async create(audioContext, info, strategy) {
163
- const node = new OutputStreamNodeFactory(audioContext, info, strategy);
164
- if (!(await strategy.onInit(node))) {
165
- throw new Error('Failed to onPrepare.');
166
- }
167
- return node;
168
- }
169
- }
170
164
  //# sourceMappingURL=output-stream-node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-stream-node.js","sourceRoot":"","sources":["../src/output-stream-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output-stream-node.js","sourceRoot":"","sources":["../src/output-stream-node.ts"],"names":[],"mappings":"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"}
@@ -12,8 +12,8 @@ const createFrameBufferReader = (options) => {
12
12
  class OutputStreamProcessor extends AudioWorkletProcessor {
13
13
  _frameReader;
14
14
  _shouldStop = false;
15
- _stopFrames;
16
- _underrunFrames = 0;
15
+ _stopFramePosition;
16
+ _underrunFrameCount = 0;
17
17
  /**
18
18
  * Creates an instance of OutputStreamProcessor.
19
19
  * @param options - The options for the processor, including shared buffers.
@@ -31,12 +31,12 @@ class OutputStreamProcessor extends AudioWorkletProcessor {
31
31
  if (event.data.type !== 'stop') {
32
32
  throw new Error(`Unexpected message type: ${event.data.type}`);
33
33
  }
34
- const frames = event.data.frames;
35
- if (frames <= 0) {
34
+ const framePosition = event.data.framePosition;
35
+ if (framePosition <= 0) {
36
36
  this._shouldStop = true;
37
37
  }
38
38
  else {
39
- this._stopFrames = frames;
39
+ this._stopFramePosition = framePosition;
40
40
  }
41
41
  }
42
42
  /**
@@ -44,25 +44,25 @@ class OutputStreamProcessor extends AudioWorkletProcessor {
44
44
  * If underrunFrames is provided and not zero, it adds to the current underrun frame count.
45
45
  * If underrunFrames is 0, it indicates that the underrun state has been resolved,
46
46
  * and the total underrun frame count is sent to the main thread before being reset.
47
- * @param underrunFrames - The number of underrun frames to add (default is 0).
47
+ * @param underrunFrameCount - The number of underrun frames to add (default is 0).
48
48
  */
49
- updateUnderrun(underrunFrames = 0) {
50
- if (underrunFrames !== 0) {
51
- this._underrunFrames += underrunFrames;
49
+ updateUnderrun(underrunFrameCount = 0) {
50
+ if (underrunFrameCount !== 0) {
51
+ this._underrunFrameCount += underrunFrameCount;
52
52
  return;
53
53
  }
54
- if (this._underrunFrames === 0) {
54
+ if (this._underrunFrameCount === 0) {
55
55
  return;
56
56
  }
57
- this.port.postMessage({ type: 'underrun', frames: this._underrunFrames });
58
- this._underrunFrames = 0;
57
+ this.port.postMessage({ type: 'underrun', underrunFrameCount: this._underrunFrameCount });
58
+ this._underrunFrameCount = 0;
59
59
  }
60
60
  /**
61
61
  * Checks the stop condition.
62
62
  * @param totalFrames - The total number of frames processed so far.
63
63
  */
64
64
  checkStopCondition(totalFrames) {
65
- if (this._stopFrames !== undefined && totalFrames >= this._stopFrames) {
65
+ if (this._stopFramePosition !== undefined && totalFrames >= this._stopFramePosition) {
66
66
  this._shouldStop = true;
67
67
  }
68
68
  }
@@ -74,16 +74,23 @@ class OutputStreamProcessor extends AudioWorkletProcessor {
74
74
  */
75
75
  process(_inputs, outputs) {
76
76
  const output = outputs[0];
77
- const readFrames = this._frameReader.read((frame, offset) => {
78
- const frames = Math.min(frame.frames, output[0].length - offset);
79
- frame.buffer.convertToOutput(frame.index, frames, output, offset);
80
- return frames;
77
+ const samplesPerFrame = output.length;
78
+ const readFrames = this._frameReader.read((buffer, offset) => {
79
+ const bufferFrameCount = buffer.length / samplesPerFrame;
80
+ const frameCount = Math.min(bufferFrameCount, output[0].length - offset);
81
+ // Deinterleaves interleaved audio frame data and writes it to the output.
82
+ output.forEach((outputChannel, channelIndex) => {
83
+ for (let i = channelIndex, j = 0; j < frameCount; i += samplesPerFrame, ++j) {
84
+ outputChannel[offset + j] = buffer[i];
85
+ }
86
+ });
87
+ return frameCount;
81
88
  });
82
89
  const totalFrames = this._frameReader.totalFrames;
83
90
  this.checkStopCondition(totalFrames);
84
91
  if (this._shouldStop) {
85
92
  this.updateUnderrun();
86
- this.port.postMessage({ type: 'stop', frames: totalFrames });
93
+ this.port.postMessage({ type: 'stop', totalProcessedFrames: totalFrames });
87
94
  this.port.close();
88
95
  return false;
89
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"output-stream-processor.js","sourceRoot":"","sources":["../src/output-stream-processor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output-stream-processor.js","sourceRoot":"","sources":["../src/output-stream-processor.ts"],"names":[],"mappings":"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"}
@@ -79,6 +79,16 @@ export declare class StreamNodeFactory {
79
79
  * @throws Error - If validation fails.
80
80
  */
81
81
  private static validateTimedBufferNodeParams;
82
+ /**
83
+ * Applies a default sample rate to the given parameters if the sampleRate is undefined.
84
+ * This function creates a new TimedBufferNodeParams object with the specified sampleRate,
85
+ * while keeping other properties unchanged.
86
+ *
87
+ * @param params - The original parameters for the TimedBufferNode.
88
+ * @param defaultSampleRate - The default sample rate to use if params.sampleRate is undefined.
89
+ * @returns A new TimedBufferNodeParams object with the sample rate applied.
90
+ */
91
+ private static applySampleRateToParams;
82
92
  /**
83
93
  * Get the AudioContext associated with this factory.
84
94
  * @returns The AudioContext instance.