@ain1084/audio-worklet-stream 1.0.5 → 2.0.1

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 (75) hide show
  1. package/README.md +11 -13
  2. package/dist/filler-frame-buffer-context.d.ts +30 -0
  3. package/dist/{frame-buffer/buffer-config.js → filler-frame-buffer-context.js} +5 -21
  4. package/dist/filler-frame-buffer-context.js.map +1 -0
  5. package/dist/{frame-buffer/buffer-filler.d.ts → frame-buffer-filler.d.ts} +2 -2
  6. package/dist/frame-buffer-filler.js +2 -0
  7. package/dist/frame-buffer-filler.js.map +1 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/output-stream-node.d.ts +4 -4
  10. package/dist/output-stream-node.js +9 -9
  11. package/dist/output-stream-node.js.map +1 -1
  12. package/dist/output-stream-processor.js +4 -4
  13. package/dist/output-stream-processor.js.map +1 -1
  14. package/dist/stream-node-factory.d.ts +4 -4
  15. package/dist/stream-node-factory.js +9 -8
  16. package/dist/stream-node-factory.js.map +1 -1
  17. package/dist/write-strategy/manual-strategy.d.ts +3 -4
  18. package/dist/write-strategy/manual-strategy.js +4 -4
  19. package/dist/write-strategy/manual-strategy.js.map +1 -1
  20. package/dist/write-strategy/timed-strategy.d.ts +4 -4
  21. package/dist/write-strategy/timed-strategy.js +5 -5
  22. package/dist/write-strategy/timed-strategy.js.map +1 -1
  23. package/dist/write-strategy/worker/message.d.ts +3 -3
  24. package/dist/write-strategy/worker/worker.d.ts +2 -2
  25. package/dist/write-strategy/worker/worker.js +8 -8
  26. package/dist/write-strategy/worker/worker.js.map +1 -1
  27. package/dist/write-strategy/worker-strategy.d.ts +3 -3
  28. package/dist/write-strategy/worker-strategy.js +6 -6
  29. package/dist/write-strategy/worker-strategy.js.map +1 -1
  30. package/package.json +10 -10
  31. package/src/{frame-buffer/buffer-config.ts → filler-frame-buffer-context.ts} +6 -50
  32. package/src/{frame-buffer/buffer-filler.ts → frame-buffer-filler.ts} +2 -2
  33. package/src/index.ts +2 -2
  34. package/src/output-stream-node.ts +10 -10
  35. package/src/output-stream-processor.ts +5 -6
  36. package/src/stream-node-factory.ts +12 -12
  37. package/src/write-strategy/manual-strategy.ts +4 -5
  38. package/src/write-strategy/timed-strategy.ts +7 -7
  39. package/src/write-strategy/worker/message.ts +3 -3
  40. package/src/write-strategy/worker/worker.ts +10 -10
  41. package/src/write-strategy/worker-strategy.ts +9 -9
  42. package/dist/frame-buffer/buffer-config.d.ts +0 -60
  43. package/dist/frame-buffer/buffer-config.js.map +0 -1
  44. package/dist/frame-buffer/buffer-factory.d.ts +0 -76
  45. package/dist/frame-buffer/buffer-factory.js +0 -55
  46. package/dist/frame-buffer/buffer-factory.js.map +0 -1
  47. package/dist/frame-buffer/buffer-filler.js +0 -2
  48. package/dist/frame-buffer/buffer-filler.js.map +0 -1
  49. package/dist/frame-buffer/buffer-reader.d.ts +0 -60
  50. package/dist/frame-buffer/buffer-reader.js +0 -77
  51. package/dist/frame-buffer/buffer-reader.js.map +0 -1
  52. package/dist/frame-buffer/buffer-utils.d.ts +0 -34
  53. package/dist/frame-buffer/buffer-utils.js +0 -34
  54. package/dist/frame-buffer/buffer-utils.js.map +0 -1
  55. package/dist/frame-buffer/buffer-writer.d.ts +0 -60
  56. package/dist/frame-buffer/buffer-writer.js +0 -77
  57. package/dist/frame-buffer/buffer-writer.js.map +0 -1
  58. package/dist/frame-buffer/buffer.d.ts +0 -51
  59. package/dist/frame-buffer/buffer.js +0 -75
  60. package/dist/frame-buffer/buffer.js.map +0 -1
  61. package/dist/write-strategy/manual.d.ts +0 -36
  62. package/dist/write-strategy/manual.js +0 -43
  63. package/dist/write-strategy/manual.js.map +0 -1
  64. package/dist/write-strategy/timed.d.ts +0 -36
  65. package/dist/write-strategy/timed.js +0 -92
  66. package/dist/write-strategy/timed.js.map +0 -1
  67. package/dist/write-strategy/worker/strategy.d.ts +0 -34
  68. package/dist/write-strategy/worker/strategy.js +0 -125
  69. package/dist/write-strategy/worker/strategy.js.map +0 -1
  70. package/dist/write-strategy/worker/worker-strategy.d.ts +0 -34
  71. package/dist/write-strategy/worker/worker-strategy.js +0 -125
  72. package/dist/write-strategy/worker/worker-strategy.js.map +0 -1
  73. package/src/frame-buffer/buffer-reader.ts +0 -82
  74. package/src/frame-buffer/buffer-writer.ts +0 -82
  75. package/src/frame-buffer/buffer.ts +0 -79
@@ -4,7 +4,7 @@
4
4
  */
5
5
  class Context {
6
6
  _node;
7
- _config;
7
+ _bufferContext;
8
8
  _fillerParam;
9
9
  _worker;
10
10
  /**
@@ -13,7 +13,7 @@ class Context {
13
13
  */
14
14
  constructor(params) {
15
15
  this._node = params.node;
16
- this._config = params.config;
16
+ this._bufferContext = params.context;
17
17
  this._worker = new params.workerConstructor();
18
18
  this._fillerParam = params.fillerParam;
19
19
  this._worker.onmessage = this.handleWorkerMessage.bind(this);
@@ -45,7 +45,7 @@ class Context {
45
45
  return new Promise((resolve) => {
46
46
  const message = {
47
47
  type: 'init',
48
- config: this._config,
48
+ config: this._bufferContext,
49
49
  fillerParams: this._fillerParam,
50
50
  };
51
51
  this._worker.postMessage(message);
@@ -84,12 +84,12 @@ export class WorkerBufferWriteStrategy {
84
84
  _context = null;
85
85
  /**
86
86
  * Creates an instance of WorkerBufferWriteStrategy.
87
- * @param config - The configuration for the filler frame buffer.
87
+ * @param bufferContext - The context for the filler frame buffer.
88
88
  * @param workerConstructor - The constructor for the Worker.
89
89
  * @param fillerParam - The parameters for the FrameBufferFiller.
90
90
  */
91
- constructor(config, workerConstructor, fillerParam) {
92
- this._createPlayContext = (node) => Context.create({ node, config, workerConstructor, fillerParam });
91
+ constructor(bufferContext, workerConstructor, fillerParam) {
92
+ this._createPlayContext = (node) => Context.create({ node, context: bufferContext, workerConstructor, fillerParam });
93
93
  }
94
94
  /**
95
95
  * Initializes the strategy.
@@ -1 +1 @@
1
- {"version":3,"file":"worker-strategy.js","sourceRoot":"","sources":["../../src/write-strategy/worker-strategy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-strategy.js","sourceRoot":"","sources":["../../src/write-strategy/worker-strategy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ain1084/audio-worklet-stream",
3
- "version": "1.0.5",
3
+ "version": "2.0.1",
4
4
  "module": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -39,18 +39,18 @@
39
39
  "docs": "typedoc"
40
40
  },
41
41
  "devDependencies": {
42
- "@stylistic/eslint-plugin": "^2.9.0",
43
- "@types/audioworklet": "^0.0.62",
44
- "@types/node": "^22.8.4",
45
- "@typescript-eslint/parser": "^8.12.2",
46
- "eslint": "^9.13.0",
47
- "globals": "^15.11.0",
48
- "typedoc": "^0.26.10",
42
+ "@stylistic/eslint-plugin": "^2.10.1",
43
+ "@types/audioworklet": "^0.0.64",
44
+ "@types/node": "^22.9.0",
45
+ "@typescript-eslint/parser": "^8.13.0",
46
+ "eslint": "^9.14.0",
47
+ "globals": "^15.12.0",
48
+ "typedoc": "^0.26.11",
49
49
  "typescript": "^5.6.3",
50
- "typescript-eslint": "^8.12.2",
50
+ "typescript-eslint": "^8.13.0",
51
51
  "vite": "^5.4.10"
52
52
  },
53
53
  "dependencies": {
54
- "@ain1084/array-buffer-partitioner": "^0.0.3"
54
+ "@ain1084/audio-frame-buffer": "^0.2.0"
55
55
  }
56
56
  }
@@ -1,4 +1,4 @@
1
- import { createArrayBufferViews } from '@ain1084/array-buffer-partitioner'
1
+ import { type FrameBufferContext, createFrameBufferContext } from '@ain1084/audio-frame-buffer'
2
2
 
3
3
  /**
4
4
  * The default number of chunks in the frame buffer when
@@ -21,16 +21,6 @@ const DEFAULT_FRAME_BUFFER_CHUNKS = 5
21
21
  */
22
22
  const AUDIO_WORKLET_BLOCK_SIZE = 128
23
23
 
24
- /**
25
- * Parameters for creating a FrameBuffer.
26
- * @property frameBufferSize - The size of the frame buffer.
27
- * @property channelCount - The number of audio channels.
28
- */
29
- export type FrameBufferParams = Readonly<{
30
- frameBufferSize: number
31
- channelCount: number
32
- }>
33
-
34
24
  /**
35
25
  * Parameters for creating a FillerFrameBuffer.
36
26
  * @property channelCount - The number of audio channels.
@@ -45,69 +35,35 @@ export type FillerFrameBufferParams = Readonly<{
45
35
  frameBufferChunks?: number
46
36
  }>
47
37
 
48
- /**
49
- * Configuration for a FrameBuffer.
50
- * This configuration is returned by the createFrameBufferConfig function.
51
- * @property sampleBuffer - The shared buffer for audio data frames.
52
- * @property samplesPerFrame - The number of samples per frame.
53
- * @property usedFramesInBuffer - The usage count of the frames in the buffer.
54
- * @property totalReadFrames - The total frames read from the buffer.
55
- * @property totalWriteFrames - The total frames written to the buffer.
56
- */
57
- export type FrameBufferConfig = Readonly<{
58
- sampleBuffer: Float32Array
59
- samplesPerFrame: number
60
- usedFramesInBuffer: Uint32Array
61
- totalReadFrames: BigUint64Array
62
- totalWriteFrames: BigUint64Array
63
- }>
64
-
65
38
  /**
66
39
  * Configuration for a FillerFrameBuffer.
67
40
  * This configuration is returned by the createFillerFrameBufferConfig function.
68
41
  * @property sampleRate - The sample rate of the audio context.
69
42
  * @property fillInterval - The interval in milliseconds for filling the buffer.
70
43
  */
71
- export type FillerFrameBufferConfig = FrameBufferConfig & Readonly<{
44
+ export type FillerFrameBufferContext = FrameBufferContext & Readonly<{
72
45
  sampleRate: number
73
46
  fillInterval: number
74
47
  }>
75
48
 
76
- /**
77
- * Creates a FrameBufferConfig instance.
78
- * @param params - The parameters for the FrameBuffer.
79
- * @returns A new instance of FrameBufferConfig.
80
- */
81
- export const createFrameBufferConfig = (params: FrameBufferParams): FrameBufferConfig => {
82
- return {
83
- ...createArrayBufferViews(SharedArrayBuffer, {
84
- sampleBuffer: [Float32Array, params.frameBufferSize * params.channelCount],
85
- usedFramesInBuffer: [Uint32Array, 1],
86
- totalReadFrames: [BigUint64Array, 1],
87
- totalWriteFrames: [BigUint64Array, 1],
88
- }),
89
- samplesPerFrame: params.channelCount,
90
- }
91
- }
92
-
93
49
  /**
94
50
  * Creates a FillerFrameBufferConfig instance.
95
51
  * @param params - The parameters for the FillerFrameBuffer.
96
52
  * @returns A new instance of FillerFrameBufferConfig.
97
53
  */
98
- export const createFillerFrameBufferConfig = (params: FillerFrameBufferParams): FillerFrameBufferConfig => {
54
+ export const createFillerFrameBufferContext = (params: FillerFrameBufferParams): FillerFrameBufferContext => {
99
55
  const sampleRate = params.sampleRate
100
56
  // Check if 'sampleRate' is a positive integer
101
57
  if (sampleRate === undefined || (!Number.isInteger(sampleRate) || sampleRate <= 0)) {
102
58
  throw new Error('Invalid sampleRate: must be a positive integer.')
103
59
  }
104
60
  const intervalMillisecond = params.fillInterval ?? DEFAULT_FILL_INTERVAL_MS
105
- const frameBufferSize = Math.floor(
61
+ const frameCount = Math.floor(
106
62
  sampleRate * intervalMillisecond / 1000 + (AUDIO_WORKLET_BLOCK_SIZE - 1),
107
63
  ) & ~(AUDIO_WORKLET_BLOCK_SIZE - 1)
108
64
  const frameBufferChunkCount = params.frameBufferChunks ?? DEFAULT_FRAME_BUFFER_CHUNKS
109
- const config = createFrameBufferConfig(
110
- { frameBufferSize: frameBufferSize * frameBufferChunkCount, channelCount: params.channelCount })
65
+ const config = createFrameBufferContext(
66
+ { frameCount: frameCount * frameBufferChunkCount, channelCount: params.channelCount })
111
67
  return {
112
68
  ...config,
113
69
  sampleRate,
@@ -1,4 +1,4 @@
1
- import type { FrameBufferWriter } from './buffer-writer'
1
+ import type { FrameBufferWriter } from '@ain1084/audio-frame-buffer'
2
2
 
3
3
  /**
4
4
  * FrameBufferFiller interface
@@ -7,7 +7,7 @@ import type { FrameBufferWriter } from './buffer-writer'
7
7
  export interface FrameBufferFiller {
8
8
  /**
9
9
  * Fill the buffer with audio frames using the provided writer.
10
- * @param writer - An instance of FrameBufferWriter used to write audio frames to the buffer.
10
+ * @param writer - An instance of {@link https://ain1084.github.io/audio-frame-buffer/classes/FrameBufferWriter.html | FrameBufferWriter} used to write audio frames to the buffer.
11
11
  * @returns A boolean indicating whether to continue playback.
12
12
  */
13
13
  fill(writer: FrameBufferWriter): boolean
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { StopEvent, UnderrunEvent } from './events'
2
2
  export type { OutputStreamNode } from './output-stream-node'
3
- export type { FrameBufferWriter } from './frame-buffer/buffer-writer'
4
- export type { FrameBufferFiller } from './frame-buffer/buffer-filler'
3
+ export type { FrameBufferWriter } from '@ain1084/audio-frame-buffer'
4
+ export type { FrameBufferFiller } from './frame-buffer-filler'
5
5
  export { StreamNodeFactory,
6
6
  type ManualBufferNodeParams,
7
7
  type TimedBufferNodeParams,
@@ -2,7 +2,7 @@ import type { MessageToProcessor, MessageToAudioNode } from './output-message'
2
2
  import { PROCESSOR_NAME } from './constants'
3
3
  import { StopEvent, UnderrunEvent } from './events'
4
4
  import { BufferWriteStrategy } from './write-strategy/strategy'
5
- import { FrameBufferConfig } from './frame-buffer/buffer-config'
5
+ import { FrameBufferContext } from '@ain1084/audio-frame-buffer'
6
6
 
7
7
  /**
8
8
  * Stream state
@@ -32,21 +32,21 @@ export class OutputStreamNode extends AudioWorkletNode {
32
32
  /**
33
33
  * Creates an instance of OutputStreamNode.
34
34
  * @param baseAudioContext - The audio context to use.
35
- * @param bufferConfig - The configuration for the buffer.
35
+ * @param bufferContext - The context for the audio frame buffer.
36
36
  * @param strategy - The strategy for writing to the buffer.
37
37
  */
38
38
  private constructor(
39
39
  baseAudioContext: BaseAudioContext,
40
- bufferConfig: FrameBufferConfig,
40
+ bufferContext: FrameBufferContext,
41
41
  strategy: BufferWriteStrategy,
42
42
  ) {
43
43
  super(baseAudioContext, PROCESSOR_NAME, {
44
- outputChannelCount: [bufferConfig.samplesPerFrame],
45
- processorOptions: bufferConfig,
44
+ outputChannelCount: [bufferContext.samplesPerFrame],
45
+ processorOptions: bufferContext,
46
46
  })
47
47
  this._strategy = strategy
48
- this._totalWriteFrames = bufferConfig.totalWriteFrames
49
- this._totalReadFrames = bufferConfig.totalReadFrames
48
+ this._totalWriteFrames = bufferContext.totalWriteFrames
49
+ this._totalReadFrames = bufferContext.totalReadFrames
50
50
  this.port.onmessage = this.handleMessage.bind(this)
51
51
  }
52
52
 
@@ -54,12 +54,12 @@ export class OutputStreamNode extends AudioWorkletNode {
54
54
  * @internal
55
55
  * Creates an instance of OutputStreamNode.
56
56
  * @param audioContext - The audio context to use.
57
- * @param config - The configuration for the buffer.
57
+ * @param context - The context for the audio frame buffer.
58
58
  * @param strategy - The strategy for writing to the buffer.
59
59
  * @returns A promise that resolves to an instance of OutputStreamNode.
60
60
  */
61
- public static async create(audioContext: BaseAudioContext, config: FrameBufferConfig, strategy: BufferWriteStrategy): Promise<OutputStreamNode> {
62
- const node = new OutputStreamNode(audioContext, config, strategy)
61
+ public static async create(audioContext: BaseAudioContext, context: FrameBufferContext, strategy: BufferWriteStrategy): Promise<OutputStreamNode> {
62
+ const node = new OutputStreamNode(audioContext, context, strategy)
63
63
  if (!(await strategy.onInit(node))) {
64
64
  throw new Error('Failed to onInit.')
65
65
  }
@@ -1,7 +1,6 @@
1
- import { FrameBufferReader } from './frame-buffer/buffer-reader'
1
+ import { FrameBufferReader, type FrameBufferContext } from '@ain1084/audio-frame-buffer'
2
2
  import { PROCESSOR_NAME } from './constants'
3
3
  import type { MessageToAudioNode, MessageToProcessor } from './output-message'
4
- import type { FrameBufferConfig } from './frame-buffer/buffer-config'
5
4
 
6
5
  /**
7
6
  * OutputStreamProcessor class
@@ -20,7 +19,7 @@ class OutputStreamProcessor extends AudioWorkletProcessor {
20
19
  */
21
20
  constructor(options: AudioWorkletNodeOptions) {
22
21
  super()
23
- this._frameReader = new FrameBufferReader(options.processorOptions as FrameBufferConfig)
22
+ this._frameReader = new FrameBufferReader(options.processorOptions as FrameBufferContext)
24
23
  this.port.onmessage = this.handleMessage.bind(this)
25
24
  }
26
25
 
@@ -79,13 +78,13 @@ class OutputStreamProcessor extends AudioWorkletProcessor {
79
78
  process(_inputs: Float32Array[][], outputs: Float32Array[][]): boolean {
80
79
  const output = outputs[0]
81
80
  const samplesPerFrame = output.length
82
- const readFrames = this._frameReader.read((buffer, offset) => {
83
- const bufferFrameCount = buffer.length / samplesPerFrame
81
+ const readFrames = this._frameReader.read((segment, offset) => {
82
+ const bufferFrameCount = segment.frameCount
84
83
  const frameCount = Math.min(bufferFrameCount, output[0].length - offset)
85
84
  // Deinterleaves interleaved audio frame data and writes it to the output.
86
85
  output.forEach((outputChannel, channelIndex) => {
87
86
  for (let i = channelIndex, j = 0; j < frameCount; i += samplesPerFrame, ++j) {
88
- outputChannel[offset + j] = buffer[i]
87
+ outputChannel[offset + j] = segment.samples[i]
89
88
  }
90
89
  })
91
90
  return frameCount
@@ -1,10 +1,10 @@
1
1
  import processor from './output-stream-processor?worker&url'
2
2
  import { ManualBufferWriteStrategy } from './write-strategy/manual-strategy'
3
- import { createFillerFrameBufferConfig, createFrameBufferConfig } from './frame-buffer/buffer-config'
3
+ import { createFillerFrameBufferContext } from './filler-frame-buffer-context'
4
4
  import type { OutputStreamNode } from './output-stream-node'
5
5
  import { TimedBufferWriteStrategy } from './write-strategy/timed-strategy'
6
- import type { FrameBufferFiller } from './frame-buffer/buffer-filler'
7
- import { FrameBufferWriter } from './frame-buffer/buffer-writer'
6
+ import type { FrameBufferFiller } from './frame-buffer-filler'
7
+ import { FrameBufferWriter, createFrameBufferContext } from '@ain1084/audio-frame-buffer'
8
8
  import { WorkerBufferWriteStrategy } from './write-strategy/worker-strategy'
9
9
 
10
10
  /**
@@ -14,8 +14,8 @@ import { WorkerBufferWriteStrategy } from './write-strategy/worker-strategy'
14
14
  export type ManualBufferNodeParams = {
15
15
  /** The number of audio channels. */
16
16
  readonly channelCount: number
17
- /** The size of the frame buffer in frames. */
18
- readonly frameBufferSize: number
17
+ /** The count of the frame buffer in frames. */
18
+ readonly frameCount: number
19
19
  }
20
20
 
21
21
  /**
@@ -97,12 +97,12 @@ export class StreamNodeFactory {
97
97
  if (params.channelCount <= 0 || !Number.isInteger(params.channelCount)) {
98
98
  throw new Error('Invalid channelCount: must be a positive integer.')
99
99
  }
100
- if (params.frameBufferSize <= 0 || !Number.isInteger(params.frameBufferSize)) {
101
- throw new Error('Invalid frameBufferSize: must be a positive integer.')
100
+ if (params.frameCount <= 0 || !Number.isInteger(params.frameCount)) {
101
+ throw new Error('Invalid frameCount: must be a positive integer.')
102
102
  }
103
- const config = createFrameBufferConfig({ ...params })
104
- const strategy = new ManualBufferWriteStrategy(config)
105
- return [await this._outputStreamNodeFactory.create(this.audioContext, config, strategy), strategy.writer]
103
+ const context = createFrameBufferContext({ ...params })
104
+ const strategy = new ManualBufferWriteStrategy(context)
105
+ return [await this._outputStreamNodeFactory.create(this.audioContext, context, strategy), strategy.writer]
106
106
  }
107
107
 
108
108
  /**
@@ -119,7 +119,7 @@ export class StreamNodeFactory {
119
119
  }
120
120
  StreamNodeFactory.validateTimedBufferNodeParams(params)
121
121
  const paramsWithSampleRate = StreamNodeFactory.applySampleRateToParams(params, this._audioContext.sampleRate)
122
- const config = createFillerFrameBufferConfig(paramsWithSampleRate)
122
+ const config = createFillerFrameBufferContext(paramsWithSampleRate)
123
123
  return this._outputStreamNodeFactory.create(this.audioContext, config,
124
124
  new TimedBufferWriteStrategy(config, frameFiller))
125
125
  }
@@ -135,7 +135,7 @@ export class StreamNodeFactory {
135
135
  ): Promise<OutputStreamNode> {
136
136
  StreamNodeFactory.validateTimedBufferNodeParams(params)
137
137
  const paramsWithSampleRate = StreamNodeFactory.applySampleRateToParams(params, this._audioContext.sampleRate)
138
- const config = createFillerFrameBufferConfig(paramsWithSampleRate)
138
+ const config = createFillerFrameBufferContext(paramsWithSampleRate)
139
139
  return this._outputStreamNodeFactory.create(this._audioContext, config,
140
140
  new WorkerBufferWriteStrategy<FillerParams>(config, worker, params.fillerParams))
141
141
  }
@@ -1,6 +1,5 @@
1
1
  import type { BufferWriteStrategy } from './strategy'
2
- import type { FrameBufferConfig } from '../frame-buffer/buffer-config'
3
- import { FrameBufferWriter } from '../frame-buffer/buffer-writer'
2
+ import { type FrameBufferContext, FrameBufferWriter } from '@ain1084/audio-frame-buffer'
4
3
 
5
4
  /**
6
5
  * ManualBufferWriteStrategy class
@@ -11,10 +10,10 @@ export class ManualBufferWriteStrategy implements BufferWriteStrategy {
11
10
 
12
11
  /**
13
12
  * Creates an instance of ManualBufferWriteStrategy.
14
- * @param config - The configuration for the frame buffer.
13
+ * @param bufferContext - The configuration for the frame buffer.
15
14
  */
16
- constructor(config: FrameBufferConfig) {
17
- this._writer = new FrameBufferWriter(config)
15
+ constructor(bufferContext: FrameBufferContext) {
16
+ this._writer = new FrameBufferWriter(bufferContext)
18
17
  }
19
18
 
20
19
  /**
@@ -1,7 +1,7 @@
1
1
  import type { BufferWriteStrategy } from './strategy'
2
- import type { FillerFrameBufferConfig } from '../frame-buffer/buffer-config'
3
- import { FrameBufferWriter } from '../frame-buffer/buffer-writer'
4
- import type { FrameBufferFiller } from '../frame-buffer/buffer-filler'
2
+ import type { FillerFrameBufferContext } from '../filler-frame-buffer-context'
3
+ import { FrameBufferWriter } from '@ain1084/audio-frame-buffer'
4
+ import type { FrameBufferFiller } from '../frame-buffer-filler'
5
5
  import type { OutputStreamNode } from '../output-stream-node'
6
6
 
7
7
  /**
@@ -59,13 +59,13 @@ export class TimedBufferWriteStrategy implements BufferWriteStrategy {
59
59
 
60
60
  /**
61
61
  * Creates an instance of TimedBufferWriteStrategy.
62
- * @param config - The configuration for the filler frame buffer.
62
+ * @param bufferContext - The configuration for the filler frame buffer.
63
63
  * @param filler - The FrameBufferFiller instance.
64
64
  */
65
- constructor(config: FillerFrameBufferConfig, filler: FrameBufferFiller) {
66
- this._writer = new FrameBufferWriter(config)
65
+ constructor(bufferContext: FillerFrameBufferContext, filler: FrameBufferFiller) {
66
+ this._writer = new FrameBufferWriter(bufferContext)
67
67
  this._filler = filler
68
- this._interval = config.fillInterval
68
+ this._interval = bufferContext.fillInterval
69
69
  this._isContinuePlayback = this._filler.fill(this._writer)
70
70
  }
71
71
 
@@ -1,4 +1,4 @@
1
- import type { FillerFrameBufferConfig } from '../../frame-buffer/buffer-config'
1
+ import type { FillerFrameBufferContext } from '../../filler-frame-buffer-context'
2
2
 
3
3
  /**
4
4
  * Message sent from the main thread to the worker.
@@ -6,7 +6,7 @@ import type { FillerFrameBufferConfig } from '../../frame-buffer/buffer-config'
6
6
  * @typeParam FillerParams - The type of the parameters for the FrameBufferFiller.
7
7
  *
8
8
  * For 'init' messages:
9
- * @property config - The configuration for the filler frame buffer.
9
+ * @property context - The context for the filler frame buffer.
10
10
  * @property fillerParams - The parameters for the FrameBufferFiller.
11
11
  *
12
12
  * For 'start' messages:
@@ -23,7 +23,7 @@ import type { FillerFrameBufferConfig } from '../../frame-buffer/buffer-config'
23
23
  * ```
24
24
  */
25
25
  export type MessageToWorker<FillerParams> =
26
- | { type: 'init', config: FillerFrameBufferConfig, fillerParams: FillerParams }
26
+ | { type: 'init', config: FillerFrameBufferContext, fillerParams: FillerParams }
27
27
  | { type: 'start' }
28
28
  | { type: 'stop' }
29
29
 
@@ -1,6 +1,6 @@
1
- import type { FillerFrameBufferConfig } from '../../frame-buffer/buffer-config'
2
- import type { FrameBufferFiller } from '../../frame-buffer/buffer-filler'
3
- import { FrameBufferWriter } from '../../frame-buffer/buffer-writer'
1
+ import type { FillerFrameBufferContext } from '../../filler-frame-buffer-context'
2
+ import type { FrameBufferFiller } from '../../frame-buffer-filler'
3
+ import { FrameBufferWriter } from '@ain1084/audio-frame-buffer'
4
4
  import { MessageToStrategy, MessageToWorker } from './message'
5
5
 
6
6
  /**
@@ -16,13 +16,13 @@ class Context {
16
16
 
17
17
  /**
18
18
  * Creates an instance ofContext.
19
- * @param config - The configuration for the filler frame buffer.
19
+ * @param context - The configuration for the filler frame buffer.
20
20
  * @param frameBufferFiller - The FrameBufferFiller instance.
21
21
  */
22
- constructor(config: FillerFrameBufferConfig, frameBufferFiller: FrameBufferFiller) {
23
- this._frameBufferWriter = new FrameBufferWriter(config)
22
+ constructor(context: FillerFrameBufferContext, frameBufferFiller: FrameBufferFiller) {
23
+ this._frameBufferWriter = new FrameBufferWriter(context)
24
24
  this._frameBufferFiller = frameBufferFiller
25
- this._fillInterval = config.fillInterval
25
+ this._fillInterval = context.fillInterval
26
26
  this._isContinuePlayback = this.fillBuffer()
27
27
  }
28
28
 
@@ -117,15 +117,15 @@ export class BufferFillWorker<FillerParams> {
117
117
 
118
118
  /**
119
119
  * Initializes the worker context.
120
- * @param config - The configuration for the filler frame buffer.
120
+ * @param bufferContext - The configuration for the filler frame buffer.
121
121
  * @param params - The parameters for the FrameBufferFiller.
122
122
  */
123
- private async init(config: FillerFrameBufferConfig, params: FillerParams) {
123
+ private async init(bufferContext: FillerFrameBufferContext, params: FillerParams) {
124
124
  if (this._context) {
125
125
  throw new Error('Error: Context is already created.')
126
126
  }
127
127
  await this._init?.()
128
- this._context = new Context(config, new this._frameBufferFillerGenerator(params))
128
+ this._context = new Context(bufferContext, new this._frameBufferFillerGenerator(params))
129
129
  self.postMessage({ type: 'init-done' } as MessageToStrategy)
130
130
  }
131
131
 
@@ -1,18 +1,18 @@
1
1
  import type { BufferWriteStrategy } from './strategy'
2
- import type { FillerFrameBufferConfig } from '../frame-buffer/buffer-config'
2
+ import type { FillerFrameBufferContext } from '../filler-frame-buffer-context'
3
3
  import type { MessageToStrategy, MessageToWorker } from './worker/message'
4
4
  import type { OutputStreamNode } from '../output-stream-node'
5
5
 
6
6
  /**
7
7
  * Parameters for creating a PlayContext.
8
8
  * @property node - The OutputStreamNode instance.
9
- * @property config - The FillerFrameBufferConfig instance.
9
+ * @property context - The FillerFrameBufferContext instance.
10
10
  * @property workerConstructor - The constructor for the Worker.
11
11
  * @property fillerParam - The parameters for the FrameBufferFiller.
12
12
  */
13
13
  type PlayerContextParams<FillerParams> = Readonly<{
14
14
  node: OutputStreamNode
15
- config: FillerFrameBufferConfig
15
+ context: FillerFrameBufferContext
16
16
  workerConstructor: new () => Worker
17
17
  fillerParam: FillerParams
18
18
  }>
@@ -23,7 +23,7 @@ type PlayerContextParams<FillerParams> = Readonly<{
23
23
  */
24
24
  class Context<FillerParams> {
25
25
  private readonly _node: OutputStreamNode
26
- private readonly _config: FillerFrameBufferConfig
26
+ private readonly _bufferContext: FillerFrameBufferContext
27
27
  private readonly _fillerParam: FillerParams
28
28
  private readonly _worker: Worker
29
29
 
@@ -33,7 +33,7 @@ class Context<FillerParams> {
33
33
  */
34
34
  private constructor(params: PlayerContextParams<FillerParams>) {
35
35
  this._node = params.node
36
- this._config = params.config
36
+ this._bufferContext = params.context
37
37
  this._worker = new params.workerConstructor()
38
38
  this._fillerParam = params.fillerParam
39
39
  this._worker.onmessage = this.handleWorkerMessage.bind(this)
@@ -68,7 +68,7 @@ class Context<FillerParams> {
68
68
  return new Promise<void>((resolve) => {
69
69
  const message: MessageToWorker<FillerParams> = {
70
70
  type: 'init',
71
- config: this._config,
71
+ config: this._bufferContext,
72
72
  fillerParams: this._fillerParam,
73
73
  }
74
74
  this._worker.postMessage(message)
@@ -111,12 +111,12 @@ export class WorkerBufferWriteStrategy<FillerParam> implements BufferWriteStrate
111
111
 
112
112
  /**
113
113
  * Creates an instance of WorkerBufferWriteStrategy.
114
- * @param config - The configuration for the filler frame buffer.
114
+ * @param bufferContext - The context for the filler frame buffer.
115
115
  * @param workerConstructor - The constructor for the Worker.
116
116
  * @param fillerParam - The parameters for the FrameBufferFiller.
117
117
  */
118
- constructor(config: FillerFrameBufferConfig, workerConstructor: new () => Worker, fillerParam: FillerParam) {
119
- this._createPlayContext = (node: OutputStreamNode) => Context.create<FillerParam>({ node, config, workerConstructor, fillerParam })
118
+ constructor(bufferContext: FillerFrameBufferContext, workerConstructor: new () => Worker, fillerParam: FillerParam) {
119
+ this._createPlayContext = (node: OutputStreamNode) => Context.create<FillerParam>({ node, context: bufferContext, workerConstructor, fillerParam })
120
120
  }
121
121
 
122
122
  /**
@@ -1,60 +0,0 @@
1
- /**
2
- * Parameters for creating a FrameBuffer.
3
- * @property frameBufferSize - The size of the frame buffer.
4
- * @property channelCount - The number of audio channels.
5
- */
6
- export type FrameBufferParams = Readonly<{
7
- frameBufferSize: number;
8
- channelCount: number;
9
- }>;
10
- /**
11
- * Parameters for creating a FillerFrameBuffer.
12
- * @property channelCount - The number of audio channels.
13
- * @property fillInterval - The interval in milliseconds for filling the buffer.
14
- * @property sampleRate - The sample rate of the audio context.
15
- * @property frameBufferChunks - The number of chunks in the frame buffer.
16
- */
17
- export type FillerFrameBufferParams = Readonly<{
18
- channelCount: number;
19
- fillInterval?: number;
20
- sampleRate?: number;
21
- frameBufferChunks?: number;
22
- }>;
23
- /**
24
- * Configuration for a FrameBuffer.
25
- * This configuration is returned by the createFrameBufferConfig function.
26
- * @property sampleBuffer - The shared buffer for audio data frames.
27
- * @property samplesPerFrame - The number of samples per frame.
28
- * @property usedFramesInBuffer - The usage count of the frames in the buffer.
29
- * @property totalReadFrames - The total frames read from the buffer.
30
- * @property totalWriteFrames - The total frames written to the buffer.
31
- */
32
- export type FrameBufferConfig = Readonly<{
33
- sampleBuffer: Float32Array;
34
- samplesPerFrame: number;
35
- usedFramesInBuffer: Uint32Array;
36
- totalReadFrames: BigUint64Array;
37
- totalWriteFrames: BigUint64Array;
38
- }>;
39
- /**
40
- * Configuration for a FillerFrameBuffer.
41
- * This configuration is returned by the createFillerFrameBufferConfig function.
42
- * @property sampleRate - The sample rate of the audio context.
43
- * @property fillInterval - The interval in milliseconds for filling the buffer.
44
- */
45
- export type FillerFrameBufferConfig = FrameBufferConfig & Readonly<{
46
- sampleRate: number;
47
- fillInterval: number;
48
- }>;
49
- /**
50
- * Creates a FrameBufferConfig instance.
51
- * @param params - The parameters for the FrameBuffer.
52
- * @returns A new instance of FrameBufferConfig.
53
- */
54
- export declare const createFrameBufferConfig: (params: FrameBufferParams) => FrameBufferConfig;
55
- /**
56
- * Creates a FillerFrameBufferConfig instance.
57
- * @param params - The parameters for the FillerFrameBuffer.
58
- * @returns A new instance of FillerFrameBufferConfig.
59
- */
60
- export declare const createFillerFrameBufferConfig: (params: FillerFrameBufferParams) => FillerFrameBufferConfig;
@@ -1 +0,0 @@
1
- {"version":3,"file":"buffer-config.js","sourceRoot":"","sources":["../../src/frame-buffer/buffer-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAE1E;;;;GAIG;AACH,MAAM,wBAAwB,GAAG,EAAE,CAAA;AAEnC;;;;GAIG;AACH,MAAM,2BAA2B,GAAG,CAAC,CAAA;AAErC;;;;GAIG;AACH,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAsDpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAyB,EAAqB,EAAE;IACtF,OAAO;QACL,GAAG,sBAAsB,CAAC,iBAAiB,EAAE;YAC3C,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC;YAC1E,kBAAkB,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YACpC,eAAe,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;YACpC,gBAAgB,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;SACtC,CAAC;QACF,eAAe,EAAE,MAAM,CAAC,YAAY;KACrC,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,MAA+B,EAA2B,EAAE;IACxG,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;IACpC,8CAA8C;IAC9C,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IACpE,CAAC;IACD,MAAM,mBAAmB,GAAG,MAAM,CAAC,YAAY,IAAI,wBAAwB,CAAA;IAC3E,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAChC,UAAU,GAAG,mBAAmB,GAAG,IAAI,GAAG,CAAC,wBAAwB,GAAG,CAAC,CAAC,CACzE,GAAG,CAAC,CAAC,wBAAwB,GAAG,CAAC,CAAC,CAAA;IACnC,MAAM,qBAAqB,GAAG,MAAM,CAAC,iBAAiB,IAAI,2BAA2B,CAAA;IACrF,MAAM,MAAM,GAAG,uBAAuB,CACpC,EAAE,eAAe,EAAE,eAAe,GAAG,qBAAqB,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;IAClG,OAAO;QACL,GAAG,MAAM;QACT,UAAU;QACV,YAAY,EAAE,mBAAmB;KAClC,CAAA;AACH,CAAC,CAAA"}