timed-audio-buffer-source-node-audio-worklet 1.0.16 → 2.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 (38) hide show
  1. package/build/es2019/factories/convert-to-context-frame.d.ts +4 -0
  2. package/build/es2019/factories/convert-to-context-frame.d.ts.map +1 -0
  3. package/build/es2019/factories/convert-to-context-frame.js +7 -0
  4. package/build/es2019/factories/convert-to-context-frame.js.map +1 -0
  5. package/build/es2019/factories/performance.d.ts +2 -0
  6. package/build/es2019/factories/performance.d.ts.map +1 -0
  7. package/build/es2019/factories/performance.js +2 -0
  8. package/build/es2019/factories/performance.js.map +1 -0
  9. package/build/es2019/factories/schedule-audio-buffer-source-node.d.ts +5 -0
  10. package/build/es2019/factories/schedule-audio-buffer-source-node.d.ts.map +1 -0
  11. package/build/es2019/factories/schedule-audio-buffer-source-node.js +12 -0
  12. package/build/es2019/factories/schedule-audio-buffer-source-node.js.map +1 -0
  13. package/build/es2019/factories/subscribe-to-timing-object.d.ts +5 -0
  14. package/build/es2019/factories/subscribe-to-timing-object.d.ts.map +1 -0
  15. package/build/es2019/factories/subscribe-to-timing-object.js +27 -0
  16. package/build/es2019/factories/subscribe-to-timing-object.js.map +1 -0
  17. package/build/es2019/interfaces/timed-audio-buffer-source-node-audio-worklet-node.d.ts +2 -0
  18. package/build/es2019/interfaces/timed-audio-buffer-source-node-audio-worklet-node.d.ts.map +1 -1
  19. package/build/es2019/module.d.ts +2 -2
  20. package/build/es2019/module.d.ts.map +1 -1
  21. package/build/es2019/module.js +32 -7
  22. package/build/es2019/module.js.map +1 -1
  23. package/build/es2019/types/native-timed-audio-buffer-source-node-audio-worklet-node.d.ts +4 -1
  24. package/build/es2019/types/native-timed-audio-buffer-source-node-audio-worklet-node.d.ts.map +1 -1
  25. package/build/es2019/worklet/worklet.d.ts +1 -1
  26. package/build/es2019/worklet/worklet.d.ts.map +1 -1
  27. package/build/es2019/worklet/worklet.js +1 -1
  28. package/build/es2019/worklet/worklet.js.map +1 -1
  29. package/build/es5/bundle.js +105 -17
  30. package/package.json +15 -15
  31. package/src/factories/convert-to-context-frame.ts +11 -0
  32. package/src/factories/performance.ts +2 -0
  33. package/src/factories/schedule-audio-buffer-source-node.ts +36 -0
  34. package/src/factories/subscribe-to-timing-object.ts +49 -0
  35. package/src/interfaces/timed-audio-buffer-source-node-audio-worklet-node.ts +4 -1
  36. package/src/module.ts +43 -6
  37. package/src/types/native-timed-audio-buffer-source-node-audio-worklet-node.ts +4 -1
  38. package/src/worklet/worklet.ts +1 -1
@@ -0,0 +1,4 @@
1
+ import { TContext, TNativeContext } from 'standardized-audio-context';
2
+ import type { createPerformance } from './performance';
3
+ export declare const createConvertToContextFrame: (performance: ReturnType<typeof createPerformance>) => (context: TContext | TNativeContext, timestamp: number) => number;
4
+ //# sourceMappingURL=convert-to-context-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-to-context-frame.d.ts","sourceRoot":"","sources":["../../../src/factories/convert-to-context-frame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,eAAO,MAAM,2BAA2B,gBACtB,WAAW,wBAAwB,CAAC,eAAe,QAAQ,GAAG,cAAc,aAAa,MAAM,WAM5G,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const createConvertToContextFrame = (performance) => (context, timestamp) => {
2
+ if (performance === null) {
3
+ throw new Error('Performance is not available.');
4
+ }
5
+ return Math.round((context.currentTime - performance.now() / 1000 + timestamp) * context.sampleRate);
6
+ };
7
+ //# sourceMappingURL=convert-to-context-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-to-context-frame.js","sourceRoot":"","sources":["../../../src/factories/convert-to-context-frame.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,2BAA2B,GACpC,CAAC,WAAiD,EAAE,EAAE,CAAC,CAAC,OAAkC,EAAE,SAAiB,EAAE,EAAE;IAC7G,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACzG,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const createPerformance: () => Performance | null;
2
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../../src/factories/performance.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,0BACkF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const createPerformance = () => typeof window === 'undefined' ? null : typeof window.performance === 'undefined' ? null : window.performance;
2
+ //# sourceMappingURL=performance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.js","sourceRoot":"","sources":["../../../src/factories/performance.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAClC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { IAudioBufferSourceNode, IAudioWorkletNode, TContext, TNativeAudioBufferSourceNode, TNativeAudioWorkletNode, TNativeContext } from 'standardized-audio-context';
2
+ import { ITimingObject } from 'timing-object';
3
+ import type { createConvertToContextFrame } from './convert-to-context-frame';
4
+ export declare const createScheduleAudioBufferSourceNode: (convertToContextFrame: ReturnType<typeof createConvertToContextFrame>) => <T extends TContext | TNativeContext>(audioWorkletNode: T extends TContext ? IAudioWorkletNode<T> : AudioWorkletNode, context: T, createAudioBufferSourceNode: T extends TContext ? (context: TContext) => IAudioBufferSourceNode<TContext> : (context: TNativeContext) => TNativeAudioBufferSourceNode, timingObject: ITimingObject) => Promise<void>;
5
+ //# sourceMappingURL=schedule-audio-buffer-source-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-audio-buffer-source-node.d.ts","sourceRoot":"","sources":["../../../src/factories/schedule-audio-buffer-source-node.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,QAAQ,EACR,4BAA4B,EAC5B,uBAAuB,EACvB,cAAc,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAE9E,eAAO,MAAM,mCAAmC,0BACpB,WAAW,kCAAkC,CAAC,mMAKlD,QAAQ,KAAK,uBAAuB,QAAQ,CAAC,aAC7C,cAAc,KAAK,4BAA4B,gBACjD,aAAa,KAC5B,QAAQ,IAAI,CAed,CAAC"}
@@ -0,0 +1,12 @@
1
+ export const createScheduleAudioBufferSourceNode = (convertToContextFrame) => (audioWorkletNode, context, createAudioBufferSourceNode, timingObject) => {
2
+ const audioBuffer = new AudioBuffer({ length: 2, sampleRate: context.sampleRate });
3
+ const audioBufferSourceNode = createAudioBufferSourceNode(context);
4
+ const { position, timestamp } = timingObject.query();
5
+ audioBuffer.copyToChannel(new Float32Array([position, convertToContextFrame(context, timestamp)]), 0);
6
+ audioBufferSourceNode.buffer = audioBuffer;
7
+ const promise = new Promise((resolve) => audioBufferSourceNode.addEventListener('ended', () => resolve(), { once: true }));
8
+ audioBufferSourceNode.connect(audioWorkletNode);
9
+ audioBufferSourceNode.start();
10
+ return promise;
11
+ };
12
+ //# sourceMappingURL=schedule-audio-buffer-source-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-audio-buffer-source-node.js","sourceRoot":"","sources":["../../../src/factories/schedule-audio-buffer-source-node.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,mCAAmC,GAC5C,CAAC,qBAAqE,EAAE,EAAE,CAC1E,CACI,gBAAqF,EACrF,OAAU,EACV,2BAE+D,EAC/D,YAA2B,EACd,EAAE;IACf,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACnF,MAAM,qBAAqB,GAAG,2BAA2B,CAAM,OAAO,CAAC,CAAC;IACxE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC;IAErD,WAAW,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,CAAC,QAAQ,EAAE,qBAAqB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEtG,qBAAqB,CAAC,MAAM,GAAG,WAAW,CAAC;IAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEjI,qBAAqB,CAAC,OAAO,CAAM,gBAAgB,CAAC,CAAC;IACrD,qBAAqB,CAAC,KAAK,EAAE,CAAC;IAE9B,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { IAudioBufferSourceNode, IAudioWorkletNode, TContext, TNativeAudioBufferSourceNode, TNativeAudioWorkletNode, TNativeContext } from 'standardized-audio-context';
2
+ import { ITimingObject } from 'timing-object';
3
+ import type { createScheduleAudioBufferSourceNode } from './schedule-audio-buffer-source-node';
4
+ export declare const createSubscribeToTimingObject: (scheduleAudioBufferSourceNode: ReturnType<typeof createScheduleAudioBufferSourceNode>) => <T extends TContext | TNativeContext>(audioWorkletNode: T extends TContext ? IAudioWorkletNode<T> : AudioWorkletNode, context: T, createAudioBufferSourceNode: T extends TContext ? (context: TContext) => IAudioBufferSourceNode<TContext> : (context: TNativeContext) => TNativeAudioBufferSourceNode, timingObject: ITimingObject) => () => void;
5
+ //# sourceMappingURL=subscribe-to-timing-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-to-timing-object.d.ts","sourceRoot":"","sources":["../../../src/factories/subscribe-to-timing-object.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,QAAQ,EACR,4BAA4B,EAC5B,uBAAuB,EACvB,cAAc,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,qCAAqC,CAAC;AAE/F,eAAO,MAAM,6BAA6B,kCACN,WAAW,0CAA0C,CAAC,mMAKlE,QAAQ,KAAK,uBAAuB,QAAQ,CAAC,aAC7C,cAAc,KAAK,4BAA4B,gBACjD,aAAa,eA6B9B,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const createSubscribeToTimingObject = (scheduleAudioBufferSourceNode) => (audioWorkletNode, context, createAudioBufferSourceNode, timingObject) => {
2
+ let hasPendingUpdate = false;
3
+ let isSendingUpdate = false;
4
+ const scheduleUpdate = () => {
5
+ hasPendingUpdate = false;
6
+ scheduleAudioBufferSourceNode(audioWorkletNode, context, createAudioBufferSourceNode, timingObject).then(() => {
7
+ if (hasPendingUpdate) {
8
+ scheduleUpdate();
9
+ }
10
+ else {
11
+ isSendingUpdate = false;
12
+ }
13
+ });
14
+ };
15
+ const listener = () => {
16
+ if (isSendingUpdate) {
17
+ hasPendingUpdate = true;
18
+ }
19
+ else {
20
+ isSendingUpdate = true;
21
+ scheduleUpdate();
22
+ }
23
+ };
24
+ timingObject.addEventListener('change', listener);
25
+ return () => timingObject.removeEventListener('change', listener);
26
+ };
27
+ //# sourceMappingURL=subscribe-to-timing-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-to-timing-object.js","sourceRoot":"","sources":["../../../src/factories/subscribe-to-timing-object.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,6BAA6B,GACtC,CAAC,6BAAqF,EAAE,EAAE,CAC1F,CACI,gBAAqF,EACrF,OAAU,EACV,2BAE+D,EAC/D,YAA2B,EAC7B,EAAE;IACA,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,MAAM,cAAc,GAAG,GAAG,EAAE;QACxB,gBAAgB,GAAG,KAAK,CAAC;QAEzB,6BAA6B,CAAC,gBAAgB,EAAE,OAAO,EAAE,2BAA2B,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YAC1G,IAAI,gBAAgB,EAAE,CAAC;gBACnB,cAAc,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACJ,eAAe,GAAG,KAAK,CAAC;YAC5B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,GAAG,EAAE;QAClB,IAAI,eAAe,EAAE,CAAC;YAClB,gBAAgB,GAAG,IAAI,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,eAAe,GAAG,IAAI,CAAC;YAEvB,cAAc,EAAE,CAAC;QACrB,CAAC;IACL,CAAC,CAAC;IAEF,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAElD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACtE,CAAC,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { IAudioWorkletNode, TContext } from 'standardized-audio-context';
2
+ import { ITimingObject } from 'timing-object';
2
3
  export interface ITimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext> extends IAudioWorkletNode<T> {
4
+ timingObject: null | ITimingObject;
3
5
  }
4
6
  //# sourceMappingURL=timed-audio-buffer-source-node-audio-worklet-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timed-audio-buffer-source-node-audio-worklet-node.d.ts","sourceRoot":"","sources":["../../../src/interfaces/timed-audio-buffer-source-node-audio-worklet-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEzE,MAAM,WAAW,2CAA2C,CAAC,CAAC,SAAS,QAAQ,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;CAAG"}
1
+ {"version":3,"file":"timed-audio-buffer-source-node-audio-worklet-node.d.ts","sourceRoot":"","sources":["../../../src/interfaces/timed-audio-buffer-source-node-audio-worklet-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,2CAA2C,CAAC,CAAC,SAAS,QAAQ,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IACzG,YAAY,EAAE,IAAI,GAAG,aAAa,CAAC;CACtC"}
@@ -1,8 +1,8 @@
1
- import { TAudioWorkletNodeConstructor, TContext, TNativeAudioWorkletNodeConstructor, TNativeContext } from 'standardized-audio-context';
1
+ import { IAudioBufferSourceNode, TAudioWorkletNodeConstructor, TContext, TNativeAudioBufferSourceNode, TNativeAudioWorkletNodeConstructor, TNativeContext } from 'standardized-audio-context';
2
2
  import { ITimedAudioBufferSourceNodeAudioWorkletNode } from './interfaces';
3
3
  import { TAnyTimedAudioBufferSourceNodeAudioWorkletNodeOptions, TNativeTimedAudioBufferSourceNodeAudioWorkletNode } from './types';
4
4
  export * from './interfaces/index';
5
5
  export * from './types/index';
6
6
  export declare const addTimedAudioBufferSourceNodeAudioWorkletModule: (addAudioWorkletModule: (url: string) => Promise<void>) => Promise<void>;
7
- export declare function createTimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext | TNativeContext>(audioWorkletNodeConstructor: T extends TContext ? TAudioWorkletNodeConstructor : TNativeAudioWorkletNodeConstructor, context: T, options?: Partial<TAnyTimedAudioBufferSourceNodeAudioWorkletNodeOptions<T>>): T extends TContext ? ITimedAudioBufferSourceNodeAudioWorkletNode<T> : TNativeTimedAudioBufferSourceNodeAudioWorkletNode;
7
+ export declare function createTimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext | TNativeContext>(audioWorkletNodeConstructor: T extends TContext ? TAudioWorkletNodeConstructor : TNativeAudioWorkletNodeConstructor, context: T, createAudioBufferSourceNode: T extends TContext ? (context: TContext) => IAudioBufferSourceNode<TContext> : (context: TNativeContext) => TNativeAudioBufferSourceNode, options?: Partial<TAnyTimedAudioBufferSourceNodeAudioWorkletNodeOptions<T>>): T extends TContext ? ITimedAudioBufferSourceNodeAudioWorkletNode<T> : TNativeTimedAudioBufferSourceNodeAudioWorkletNode;
8
8
  //# sourceMappingURL=module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,4BAA4B,EAC5B,QAAQ,EAER,kCAAkC,EAClC,cAAc,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,2CAA2C,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,qDAAqD,EAAE,iDAAiD,EAAE,MAAM,SAAS,CAAC;AAOnI,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAI9B,eAAO,MAAM,+CAA+C,gCAAuC,MAAM,KAAK,QAAQ,IAAI,CAAC,kBAQ1H,CAAC;AAEF,wBAAgB,gDAAgD,CAAC,CAAC,SAAS,QAAQ,GAAG,cAAc,EAChG,2BAA2B,EAAE,CAAC,SAAS,QAAQ,GAAG,4BAA4B,GAAG,kCAAkC,EACnH,OAAO,EAAE,CAAC,EACV,OAAO,GAAE,OAAO,CAAC,qDAAqD,CAAC,CAAC,CAAC,CAAM,GAChF,CAAC,SAAS,QAAQ,GAAG,2CAA2C,CAAC,CAAC,CAAC,GAAG,iDAAiD,CAoCzH"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EAEtB,4BAA4B,EAC5B,QAAQ,EACR,4BAA4B,EAE5B,kCAAkC,EAClC,cAAc,EACjB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,2CAA2C,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,qDAAqD,EAAE,iDAAiD,EAAE,MAAM,SAAS,CAAC;AAOnI,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAI9B,eAAO,MAAM,+CAA+C,gCAAuC,MAAM,KAAK,QAAQ,IAAI,CAAC,kBAQ1H,CAAC;AAKF,wBAAgB,gDAAgD,CAAC,CAAC,SAAS,QAAQ,GAAG,cAAc,EAChG,2BAA2B,EAAE,CAAC,SAAS,QAAQ,GAAG,4BAA4B,GAAG,kCAAkC,EACnH,OAAO,EAAE,CAAC,EACV,2BAA2B,EAAE,CAAC,SAAS,QAAQ,GACzC,CAAC,OAAO,EAAE,QAAQ,KAAK,sBAAsB,CAAC,QAAQ,CAAC,GACvD,CAAC,OAAO,EAAE,cAAc,KAAK,4BAA4B,EAC/D,OAAO,GAAE,OAAO,CAAC,qDAAqD,CAAC,CAAC,CAAC,CAAM,GAChF,CAAC,SAAS,QAAQ,GAAG,2CAA2C,CAAC,CAAC,CAAC,GAAG,iDAAiD,CA8DzH"}
@@ -1,4 +1,7 @@
1
- import { AudioBuffer } from 'standardized-audio-context';
1
+ import { createConvertToContextFrame } from './factories/convert-to-context-frame';
2
+ import { createPerformance } from './factories/performance';
3
+ import { createScheduleAudioBufferSourceNode } from './factories/schedule-audio-buffer-source-node';
4
+ import { createSubscribeToTimingObject } from './factories/subscribe-to-timing-object';
2
5
  import { worklet } from './worklet/worklet';
3
6
  /*
4
7
  * @todo Explicitly referencing the barrel file seems to be necessary when enabling the
@@ -16,30 +19,52 @@ export const addTimedAudioBufferSourceNodeAudioWorkletModule = async (addAudioWo
16
19
  URL.revokeObjectURL(url);
17
20
  }
18
21
  };
19
- export function createTimedAudioBufferSourceNodeAudioWorkletNode(audioWorkletNodeConstructor, context, options = {}) {
22
+ const convertToContextFrame = createConvertToContextFrame(createPerformance());
23
+ const subscribeToTimingObject = createSubscribeToTimingObject(createScheduleAudioBufferSourceNode(convertToContextFrame));
24
+ export function createTimedAudioBufferSourceNodeAudioWorkletNode(audioWorkletNodeConstructor, context, createAudioBufferSourceNode, options = {}) {
20
25
  var _a, _b;
21
- const { buffer = null, timingObject = null } = options;
26
+ const { buffer = null } = options;
27
+ if (buffer instanceof AudioBuffer && buffer.sampleRate !== context.sampleRate) {
28
+ throw new TypeError('The AudioBuffer must have the same sampleRate as the AudioContext.');
29
+ }
30
+ let { timingObject = null } = options;
22
31
  const { position = 0, timestamp = 0 } = (_a = timingObject === null || timingObject === void 0 ? void 0 : timingObject.query()) !== null && _a !== void 0 ? _a : {};
23
32
  const audioWorkletNode = new audioWorkletNodeConstructor(context, 'timed-audio-buffer-source-node-audio-worklet-processor', {
24
- ...options,
25
- numberOfInputs: 0,
33
+ numberOfInputs: 1,
26
34
  numberOfOutputs: 1,
27
35
  outputChannelCount: [(_b = buffer === null || buffer === void 0 ? void 0 : buffer.numberOfChannels) !== null && _b !== void 0 ? _b : 1],
28
- pocessorOptions: {
36
+ processorOptions: {
29
37
  buffer: buffer instanceof AudioBuffer
30
38
  ? Array.from({ length: buffer.numberOfChannels }, (_, channel) => buffer.getChannelData(channel))
31
39
  : null,
32
40
  position,
33
- timestamp
41
+ timestamp: convertToContextFrame(context, timestamp)
34
42
  }
35
43
  });
44
+ let removeListener = null;
36
45
  Object.defineProperties(audioWorkletNode, {
37
46
  port: {
38
47
  get() {
39
48
  throw new Error("The port of a TimedAudioBufferSourceNodeAudioWorkletNode can't be accessed.");
40
49
  }
50
+ },
51
+ timingObject: {
52
+ get: () => timingObject,
53
+ set: (value) => {
54
+ removeListener === null || removeListener === void 0 ? void 0 : removeListener();
55
+ removeListener = null;
56
+ if (value === null) {
57
+ timingObject = value;
58
+ }
59
+ else {
60
+ throw new TypeError('A TimingObject can only be set in the constructor.');
61
+ }
62
+ }
41
63
  }
42
64
  });
65
+ if (timingObject !== null) {
66
+ removeListener = subscribeToTimingObject(audioWorkletNode, context, createAudioBufferSourceNode, timingObject);
67
+ }
43
68
  return audioWorkletNode;
44
69
  }
45
70
  //# sourceMappingURL=module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EAOd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAE9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,uCAAuC,EAAE,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,+CAA+C,GAAG,KAAK,EAAE,qBAAqD,EAAE,EAAE;IAC3H,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,CAAC;QACD,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACP,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,UAAU,gDAAgD,CAC5D,2BAAmH,EACnH,OAAU,EACV,UAA6E,EAAE;;IAO/E,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACvD,MAAM,EAAE,QAAQ,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE,mCAAI,EAAE,CAAC;IACpE,MAAM,gBAAgB,GAAyB,IAAU,2BAA4B,CACjF,OAAO,EACP,wDAAwD,EACxD;QACI,GAAG,OAAO;QACV,cAAc,EAAE,CAAC;QACjB,eAAe,EAAE,CAAC;QAClB,kBAAkB,EAAE,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,mCAAI,CAAC,CAAC;QACnD,eAAe,EAAE;YACb,MAAM,EACF,MAAM,YAAY,WAAW;gBACzB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;gBACjG,CAAC,CAAC,IAAI;YACd,QAAQ;YACR,SAAS;SACZ;KACJ,CACJ,CAAC;IAEF,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE;QACtC,IAAI,EAAE;YACF,GAAG;gBACC,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;YACnG,CAAC;SACJ;KACJ,CAAC,CAAC;IAEH,OAAuD,gBAAgB,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAC;AAGvF,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAE9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,uCAAuC,EAAE,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,+CAA+C,GAAG,KAAK,EAAE,qBAAqD,EAAE,EAAE;IAC3H,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,CAAC;QACD,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACP,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,2BAA2B,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAC/E,MAAM,uBAAuB,GAAG,6BAA6B,CAAC,mCAAmC,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAE1H,MAAM,UAAU,gDAAgD,CAC5D,2BAAmH,EACnH,OAAU,EACV,2BAE+D,EAC/D,UAA6E,EAAE;;IAO/E,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAElC,IAAI,MAAM,YAAY,WAAW,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;QAC5E,MAAM,IAAI,SAAS,CAAC,oEAAoE,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEtC,MAAM,EAAE,QAAQ,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE,mCAAI,EAAE,CAAC;IACpE,MAAM,gBAAgB,GAAyB,IAAU,2BAA4B,CACjF,OAAO,EACP,wDAAwD,EACxD;QACI,cAAc,EAAE,CAAC;QACjB,eAAe,EAAE,CAAC;QAClB,kBAAkB,EAAE,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,mCAAI,CAAC,CAAC;QACnD,gBAAgB,EAAE;YACd,MAAM,EACF,MAAM,YAAY,WAAW;gBACzB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;gBACjG,CAAC,CAAC,IAAI;YACd,QAAQ;YACR,SAAS,EAAE,qBAAqB,CAAC,OAAO,EAAE,SAAS,CAAC;SACvD;KACJ,CACJ,CAAC;IAEF,IAAI,cAAc,GAAwB,IAAI,CAAC;IAE/C,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE;QACtC,IAAI,EAAE;YACF,GAAG;gBACC,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;YACnG,CAAC;SACJ;QACD,YAAY,EAAE;YACV,GAAG,EAAE,GAAG,EAAE,CAAC,YAAY;YACvB,GAAG,EAAE,CAAC,KAAqE,EAAE,EAAE;gBAC3E,cAAc,aAAd,cAAc,uBAAd,cAAc,EAAI,CAAC;gBAEnB,cAAc,GAAG,IAAI,CAAC;gBAEtB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACjB,YAAY,GAAG,KAAK,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACJ,MAAM,IAAI,SAAS,CAAC,oDAAoD,CAAC,CAAC;gBAC9E,CAAC;YACL,CAAC;SACJ;KACJ,CAAC,CAAC;IAEH,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QACxB,cAAc,GAAG,uBAAuB,CAAC,gBAAgB,EAAE,OAAO,EAAE,2BAA2B,EAAE,YAAY,CAAC,CAAC;IACnH,CAAC;IAED,OAAuD,gBAAgB,CAAC;AAC5E,CAAC"}
@@ -1,3 +1,6 @@
1
1
  import { TNativeAudioWorkletNode } from 'standardized-audio-context';
2
- export type TNativeTimedAudioBufferSourceNodeAudioWorkletNode = TNativeAudioWorkletNode;
2
+ import { ITimingObject } from 'timing-object';
3
+ export type TNativeTimedAudioBufferSourceNodeAudioWorkletNode = TNativeAudioWorkletNode & {
4
+ timingObject: null | ITimingObject;
5
+ };
3
6
  //# sourceMappingURL=native-timed-audio-buffer-source-node-audio-worklet-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"native-timed-audio-buffer-source-node-audio-worklet-node.d.ts","sourceRoot":"","sources":["../../../src/types/native-timed-audio-buffer-source-node-audio-worklet-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,MAAM,iDAAiD,GAAG,uBAAuB,CAAC"}
1
+ {"version":3,"file":"native-timed-audio-buffer-source-node-audio-worklet-node.d.ts","sourceRoot":"","sources":["../../../src/types/native-timed-audio-buffer-source-node-audio-worklet-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,iDAAiD,GAAG,uBAAuB,GAAG;IACtF,YAAY,EAAE,IAAI,GAAG,aAAa,CAAC;CACtC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const worklet = "(()=>{\"use strict\";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const u=\"object\"==typeof n&&null!==n&&\"buffer\"in n?n.buffer:null;if(!(null===u||Array.isArray(u)&&u.every((e=>e instanceof Float32Array))))throw new Error(\"The buffer needs to be either null or an array with where each element is a Float32Array.\");if(0!==t)throw new Error(\"The numberOfInputs must be 0.\");if(1!==r)throw new Error(\"The numberOfOutputs must be 1.\");const i=null!==(s=null==u?void 0:u.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||i!==o[0])throw new Error(\"The outputChannelCount must match the number of channels of the buffer.\");const f=\"object\"==typeof n&&null!==n&&\"position\"in n?n.position:0;if(\"number\"!=typeof f)throw new Error('The position needs to be of type \"number\".');const l=\"object\"==typeof n&&null!==n&&\"timestamp\"in n?n.timestamp:0;if(\"number\"!=typeof l)throw new Error('The timestamp needs to be of type \"number\".');super(),this._buffer=u,this._position=f,this._timestamp=l}process(e,t){let[r]=t;if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],o=r[t];for(let t=0;t<128;t+=1){const r=this._position+currentFrame-this._timestamp+t;r>=0&&r<e.length&&(o[t]=e[r])}}}return!0}}e.parameterDescriptors=[],registerProcessor(\"timed-audio-buffer-source-node-audio-worklet-processor\",e)})();";
1
+ export declare const worklet = "(()=>{\"use strict\";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const i=\"object\"==typeof n&&null!==n&&\"buffer\"in n?n.buffer:null;if(!(null===i||Array.isArray(i)&&i.every((e=>e instanceof Float32Array))))throw new Error(\"The buffer needs to be either null or an array with where each element is a Float32Array.\");if(1!==t)throw new Error(\"The numberOfInputs must be 1.\");if(1!==r)throw new Error(\"The numberOfOutputs must be 1.\");const u=null!==(s=null==i?void 0:i.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||u!==o[0])throw new Error(\"The outputChannelCount must match the number of channels of the buffer.\");const f=\"object\"==typeof n&&null!==n&&\"position\"in n?n.position:0;if(\"number\"!=typeof f)throw new Error('The position needs to be of type \"number\".');const h=\"object\"==typeof n&&null!==n&&\"timestamp\"in n?n.timestamp:0;if(\"number\"!=typeof h)throw new Error('The timestamp needs to be of type \"number\".');super(),this._buffer=i,this._position=f,this._timestamp=h}process(e,t){let[r]=e,[o]=t;if(r.length>0){const[e]=r;e.length>1&&(this._position=Math.round(e[0]),this._timestamp=Math.round(e[1]))}if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],r=o[t];for(let t=0;t<128;t+=1){const o=this._position+currentFrame-this._timestamp+t;o>=0&&o<e.length&&(r[t]=e[o])}}}return!0}}e.parameterDescriptors=[],registerProcessor(\"timed-audio-buffer-source-node-audio-worklet-processor\",e)})();";
2
2
  //# sourceMappingURL=worklet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worklet.d.ts","sourceRoot":"","sources":["../../../src/worklet/worklet.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,07CAA05C,CAAC"}
1
+ {"version":3,"file":"worklet.d.ts","sourceRoot":"","sources":["../../../src/worklet/worklet.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,yiDAAygD,CAAC"}
@@ -1,3 +1,3 @@
1
1
  // This is the minified and stringified code of the timed-audio-buffer-source-node-audio-worklet-processor package.
2
- export const worklet = `(()=>{"use strict";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const u="object"==typeof n&&null!==n&&"buffer"in n?n.buffer:null;if(!(null===u||Array.isArray(u)&&u.every((e=>e instanceof Float32Array))))throw new Error("The buffer needs to be either null or an array with where each element is a Float32Array.");if(0!==t)throw new Error("The numberOfInputs must be 0.");if(1!==r)throw new Error("The numberOfOutputs must be 1.");const i=null!==(s=null==u?void 0:u.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||i!==o[0])throw new Error("The outputChannelCount must match the number of channels of the buffer.");const f="object"==typeof n&&null!==n&&"position"in n?n.position:0;if("number"!=typeof f)throw new Error('The position needs to be of type "number".');const l="object"==typeof n&&null!==n&&"timestamp"in n?n.timestamp:0;if("number"!=typeof l)throw new Error('The timestamp needs to be of type "number".');super(),this._buffer=u,this._position=f,this._timestamp=l}process(e,t){let[r]=t;if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],o=r[t];for(let t=0;t<128;t+=1){const r=this._position+currentFrame-this._timestamp+t;r>=0&&r<e.length&&(o[t]=e[r])}}}return!0}}e.parameterDescriptors=[],registerProcessor("timed-audio-buffer-source-node-audio-worklet-processor",e)})();`; // tslint:disable-line:max-line-length
2
+ export const worklet = `(()=>{"use strict";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const i="object"==typeof n&&null!==n&&"buffer"in n?n.buffer:null;if(!(null===i||Array.isArray(i)&&i.every((e=>e instanceof Float32Array))))throw new Error("The buffer needs to be either null or an array with where each element is a Float32Array.");if(1!==t)throw new Error("The numberOfInputs must be 1.");if(1!==r)throw new Error("The numberOfOutputs must be 1.");const u=null!==(s=null==i?void 0:i.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||u!==o[0])throw new Error("The outputChannelCount must match the number of channels of the buffer.");const f="object"==typeof n&&null!==n&&"position"in n?n.position:0;if("number"!=typeof f)throw new Error('The position needs to be of type "number".');const h="object"==typeof n&&null!==n&&"timestamp"in n?n.timestamp:0;if("number"!=typeof h)throw new Error('The timestamp needs to be of type "number".');super(),this._buffer=i,this._position=f,this._timestamp=h}process(e,t){let[r]=e,[o]=t;if(r.length>0){const[e]=r;e.length>1&&(this._position=Math.round(e[0]),this._timestamp=Math.round(e[1]))}if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],r=o[t];for(let t=0;t<128;t+=1){const o=this._position+currentFrame-this._timestamp+t;o>=0&&o<e.length&&(r[t]=e[o])}}}return!0}}e.parameterDescriptors=[],registerProcessor("timed-audio-buffer-source-node-audio-worklet-processor",e)})();`; // tslint:disable-line:max-line-length
3
3
  //# sourceMappingURL=worklet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worklet.js","sourceRoot":"","sources":["../../../src/worklet/worklet.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,MAAM,CAAC,MAAM,OAAO,GAAG,u5CAAu5C,CAAC,CAAC,sCAAsC"}
1
+ {"version":3,"file":"worklet.js","sourceRoot":"","sources":["../../../src/worklet/worklet.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,MAAM,CAAC,MAAM,OAAO,GAAG,sgDAAsgD,CAAC,CAAC,sCAAsC"}
@@ -1,14 +1,79 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/defineProperty'), require('@babel/runtime/helpers/asyncToGenerator'), require('@babel/runtime/regenerator'), require('standardized-audio-context')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/defineProperty', '@babel/runtime/helpers/asyncToGenerator', '@babel/runtime/regenerator', 'standardized-audio-context'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.timedAudioBufferSourceNodeAudioWorklet = {}, global._defineProperty, global._asyncToGenerator, global._regeneratorRuntime, global.standardizedAudioContext));
5
- })(this, (function (exports, _defineProperty, _asyncToGenerator, _regeneratorRuntime, standardizedAudioContext) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/asyncToGenerator'), require('@babel/runtime/regenerator')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/asyncToGenerator', '@babel/runtime/regenerator'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.timedAudioBufferSourceNodeAudioWorklet = {}, global._asyncToGenerator, global._regeneratorRuntime));
5
+ })(this, (function (exports, _asyncToGenerator, _regeneratorRuntime) { 'use strict';
6
+
7
+ var createConvertToContextFrame = function createConvertToContextFrame(performance) {
8
+ return function (context, timestamp) {
9
+ if (performance === null) {
10
+ throw new Error('Performance is not available.');
11
+ }
12
+ return Math.round((context.currentTime - performance.now() / 1000 + timestamp) * context.sampleRate);
13
+ };
14
+ };
15
+
16
+ var createPerformance = function createPerformance() {
17
+ return typeof window === 'undefined' ? null : typeof window.performance === 'undefined' ? null : window.performance;
18
+ };
19
+
20
+ var createScheduleAudioBufferSourceNode = function createScheduleAudioBufferSourceNode(convertToContextFrame) {
21
+ return function (audioWorkletNode, context, createAudioBufferSourceNode, timingObject) {
22
+ var audioBuffer = new AudioBuffer({
23
+ length: 2,
24
+ sampleRate: context.sampleRate
25
+ });
26
+ var audioBufferSourceNode = createAudioBufferSourceNode(context);
27
+ var _timingObject$query = timingObject.query(),
28
+ position = _timingObject$query.position,
29
+ timestamp = _timingObject$query.timestamp;
30
+ audioBuffer.copyToChannel(new Float32Array([position, convertToContextFrame(context, timestamp)]), 0);
31
+ audioBufferSourceNode.buffer = audioBuffer;
32
+ var promise = new Promise(function (resolve) {
33
+ return audioBufferSourceNode.addEventListener('ended', function () {
34
+ return resolve();
35
+ }, {
36
+ once: true
37
+ });
38
+ });
39
+ audioBufferSourceNode.connect(audioWorkletNode);
40
+ audioBufferSourceNode.start();
41
+ return promise;
42
+ };
43
+ };
44
+
45
+ var createSubscribeToTimingObject = function createSubscribeToTimingObject(scheduleAudioBufferSourceNode) {
46
+ return function (audioWorkletNode, context, createAudioBufferSourceNode, timingObject) {
47
+ var hasPendingUpdate = false;
48
+ var isSendingUpdate = false;
49
+ var scheduleUpdate = function scheduleUpdate() {
50
+ hasPendingUpdate = false;
51
+ scheduleAudioBufferSourceNode(audioWorkletNode, context, createAudioBufferSourceNode, timingObject).then(function () {
52
+ if (hasPendingUpdate) {
53
+ scheduleUpdate();
54
+ } else {
55
+ isSendingUpdate = false;
56
+ }
57
+ });
58
+ };
59
+ var listener = function listener() {
60
+ if (isSendingUpdate) {
61
+ hasPendingUpdate = true;
62
+ } else {
63
+ isSendingUpdate = true;
64
+ scheduleUpdate();
65
+ }
66
+ };
67
+ timingObject.addEventListener('change', listener);
68
+ return function () {
69
+ return timingObject.removeEventListener('change', listener);
70
+ };
71
+ };
72
+ };
6
73
 
7
74
  // This is the minified and stringified code of the timed-audio-buffer-source-node-audio-worklet-processor package.
8
- var worklet = "(()=>{var e={31:function(e,t,r){!function(e,t,r,o,n,u,s,p){\"use strict\";function i(e){var t=l();return function(){var r,o=s(e);if(t){var n=s(this).constructor;r=Reflect.construct(o,arguments,n)}else r=o.apply(this,arguments);return u(this,r)}}function l(){if(\"undefined\"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if(\"function\"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}var f=function(u){n(p,u);var s=i(p);function p(e){var o,n,u=e.numberOfInputs,i=e.numberOfOutputs,l=e.outputChannelCount,f=e.processorOptions;r(this,p);var a=\"object\"===t(f)&&null!==f&&\"buffer\"in f?f.buffer:null;if(!(null===a||Array.isArray(a)&&a.every((function(e){return e instanceof Float32Array}))))throw new Error(\"The buffer needs to be either null or an array with where each element is a Float32Array.\");if(0!==u)throw new Error(\"The numberOfInputs must be 0.\");if(1!==i)throw new Error(\"The numberOfOutputs must be 1.\");var c=null!==(n=null==a?void 0:a.length)&&void 0!==n?n:1;if(void 0===l||1!==l.length||c!==l[0])throw new Error(\"The outputChannelCount must match the number of channels of the buffer.\");var x=\"object\"===t(f)&&null!==f&&\"position\"in f?f.position:0;if(\"number\"!=typeof x)throw new Error('The position needs to be of type \"number\".');var d=\"object\"===t(f)&&null!==f&&\"timestamp\"in f?f.timestamp:0;if(\"number\"!=typeof d)throw new Error('The timestamp needs to be of type \"number\".');return(o=s.call(this))._buffer=a,o._position=x,o._timestamp=d,o}return o(p,[{key:\"process\",value:function(t,r){var o=e(r,1)[0];if(null!==this._buffer)for(var n=this._buffer.length,u=0;u<n;u+=1)for(var s=this._buffer[u],p=o[u],i=0;i<128;i+=1){var l=this._position+currentFrame-this._timestamp+i;l>=0&&l<s.length&&(p[i]=s[l])}return!0}}]),p}(p(AudioWorkletProcessor));f.parameterDescriptors=[],registerProcessor(\"timed-audio-buffer-source-node-audio-worklet-processor\",f)}(r(424),r(698),r(690),r(728),r(655),r(993),r(808),r(496))},897:e=>{e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,o=new Array(t);r<t;r++)o[r]=e[r];return o},e.exports.__esModule=!0,e.exports.default=e.exports},372:e=>{e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},115:e=>{e.exports=function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e},e.exports.__esModule=!0,e.exports.default=e.exports},690:e=>{e.exports=function(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")},e.exports.__esModule=!0,e.exports.default=e.exports},515:(e,t,r)=>{var o=r(15),n=r(617);function u(t,r,s){return n()?(e.exports=u=Reflect.construct.bind(),e.exports.__esModule=!0,e.exports.default=e.exports):(e.exports=u=function(e,t,r){var n=[null];n.push.apply(n,t);var u=new(Function.bind.apply(e,n));return r&&o(u,r.prototype),u},e.exports.__esModule=!0,e.exports.default=e.exports),u.apply(null,arguments)}e.exports=u,e.exports.__esModule=!0,e.exports.default=e.exports},728:(e,t,r)=>{var o=r(62);function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n&&(n.writable=!0),Object.defineProperty(e,o(n.key),n)}}e.exports=function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,\"prototype\",{writable:!1}),e},e.exports.__esModule=!0,e.exports.default=e.exports},808:e=>{function t(r){return e.exports=t=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},e.exports.__esModule=!0,e.exports.default=e.exports,t(r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},655:(e,t,r)=>{var o=r(15);e.exports=function(e,t){if(\"function\"!=typeof t&&null!==t)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),t&&o(e,t)},e.exports.__esModule=!0,e.exports.default=e.exports},35:e=>{e.exports=function(e){try{return-1!==Function.toString.call(e).indexOf(\"[native code]\")}catch(t){return\"function\"==typeof e}},e.exports.__esModule=!0,e.exports.default=e.exports},617:e=>{e.exports=function(){if(\"undefined\"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if(\"function\"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}},e.exports.__esModule=!0,e.exports.default=e.exports},872:e=>{e.exports=function(e,t){var r=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=r){var o,n,u,s,p=[],i=!0,l=!1;try{if(u=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;i=!1}else for(;!(i=(o=u.call(r)).done)&&(p.push(o.value),p.length!==t);i=!0);}catch(e){l=!0,n=e}finally{try{if(!i&&null!=r.return&&(s=r.return(),Object(s)!==s))return}finally{if(l)throw n}}return p}},e.exports.__esModule=!0,e.exports.default=e.exports},218:e=>{e.exports=function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")},e.exports.__esModule=!0,e.exports.default=e.exports},993:(e,t,r)=>{var o=r(698).default,n=r(115);e.exports=function(e,t){if(t&&(\"object\"===o(t)||\"function\"==typeof t))return t;if(void 0!==t)throw new TypeError(\"Derived constructors may only return object or undefined\");return n(e)},e.exports.__esModule=!0,e.exports.default=e.exports},15:e=>{function t(r,o){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(r,o)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},424:(e,t,r)=>{var o=r(372),n=r(872),u=r(116),s=r(218);e.exports=function(e,t){return o(e)||n(e,t)||u(e,t)||s()},e.exports.__esModule=!0,e.exports.default=e.exports},36:(e,t,r)=>{var o=r(698).default;e.exports=function(e,t){if(\"object\"!==o(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||\"default\");if(\"object\"!==o(n))return n;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===t?String:Number)(e)},e.exports.__esModule=!0,e.exports.default=e.exports},62:(e,t,r)=>{var o=r(698).default,n=r(36);e.exports=function(e){var t=n(e,\"string\");return\"symbol\"===o(t)?t:String(t)},e.exports.__esModule=!0,e.exports.default=e.exports},698:e=>{function t(r){return e.exports=t=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},116:(e,t,r)=>{var o=r(897);e.exports=function(e,t){if(e){if(\"string\"==typeof e)return o(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return\"Object\"===r&&e.constructor&&(r=e.constructor.name),\"Map\"===r||\"Set\"===r?Array.from(e):\"Arguments\"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(e,t):void 0}},e.exports.__esModule=!0,e.exports.default=e.exports},496:(e,t,r)=>{var o=r(808),n=r(15),u=r(35),s=r(515);function p(t){var r=\"function\"==typeof Map?new Map:void 0;return e.exports=p=function(e){if(null===e||!u(e))return e;if(\"function\"!=typeof e)throw new TypeError(\"Super expression must either be null or a function\");if(void 0!==r){if(r.has(e))return r.get(e);r.set(e,t)}function t(){return s(e,arguments,o(this).constructor)}return t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),n(t,e)},e.exports.__esModule=!0,e.exports.default=e.exports,p(t)}e.exports=p,e.exports.__esModule=!0,e.exports.default=e.exports}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var u=t[o]={exports:{}};return e[o].call(u.exports,u,u.exports,r),u.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{\"use strict\";r(31)})()})();"; // tslint:disable-line:max-line-length
75
+ var worklet = "(()=>{var e={31:function(e,t,r){!function(e,t,r,o,n,u,s,p){\"use strict\";function i(e){var t=f();return function(){var r,o=s(e);if(t){var n=s(this).constructor;r=Reflect.construct(o,arguments,n)}else r=o.apply(this,arguments);return u(this,r)}}function f(){if(\"undefined\"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if(\"function\"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}var l=function(u){n(p,u);var s=i(p);function p(e){var o,n,u=e.numberOfInputs,i=e.numberOfOutputs,f=e.outputChannelCount,l=e.processorOptions;r(this,p);var a=\"object\"===t(l)&&null!==l&&\"buffer\"in l?l.buffer:null;if(!(null===a||Array.isArray(a)&&a.every((function(e){return e instanceof Float32Array}))))throw new Error(\"The buffer needs to be either null or an array with where each element is a Float32Array.\");if(1!==u)throw new Error(\"The numberOfInputs must be 1.\");if(1!==i)throw new Error(\"The numberOfOutputs must be 1.\");var c=null!==(n=null==a?void 0:a.length)&&void 0!==n?n:1;if(void 0===f||1!==f.length||c!==f[0])throw new Error(\"The outputChannelCount must match the number of channels of the buffer.\");var x=\"object\"===t(l)&&null!==l&&\"position\"in l?l.position:0;if(\"number\"!=typeof x)throw new Error('The position needs to be of type \"number\".');var d=\"object\"===t(l)&&null!==l&&\"timestamp\"in l?l.timestamp:0;if(\"number\"!=typeof d)throw new Error('The timestamp needs to be of type \"number\".');return(o=s.call(this))._buffer=a,o._position=x,o._timestamp=d,o}return o(p,[{key:\"process\",value:function(t,r){var o=e(t,1)[0],n=e(r,1)[0];if(o.length>0){var u=e(o,1)[0];u.length>1&&(this._position=Math.round(u[0]),this._timestamp=Math.round(u[1]))}if(null!==this._buffer)for(var s=this._buffer.length,p=0;p<s;p+=1)for(var i=this._buffer[p],f=n[p],l=0;l<128;l+=1){var a=this._position+currentFrame-this._timestamp+l;a>=0&&a<i.length&&(f[l]=i[a])}return!0}}]),p}(p(AudioWorkletProcessor));l.parameterDescriptors=[],registerProcessor(\"timed-audio-buffer-source-node-audio-worklet-processor\",l)}(r(424),r(698),r(690),r(728),r(655),r(993),r(808),r(496))},897:e=>{e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,o=new Array(t);r<t;r++)o[r]=e[r];return o},e.exports.__esModule=!0,e.exports.default=e.exports},372:e=>{e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},115:e=>{e.exports=function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e},e.exports.__esModule=!0,e.exports.default=e.exports},690:e=>{e.exports=function(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")},e.exports.__esModule=!0,e.exports.default=e.exports},515:(e,t,r)=>{var o=r(15),n=r(617);function u(t,r,s){return n()?(e.exports=u=Reflect.construct.bind(),e.exports.__esModule=!0,e.exports.default=e.exports):(e.exports=u=function(e,t,r){var n=[null];n.push.apply(n,t);var u=new(Function.bind.apply(e,n));return r&&o(u,r.prototype),u},e.exports.__esModule=!0,e.exports.default=e.exports),u.apply(null,arguments)}e.exports=u,e.exports.__esModule=!0,e.exports.default=e.exports},728:(e,t,r)=>{var o=r(62);function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n&&(n.writable=!0),Object.defineProperty(e,o(n.key),n)}}e.exports=function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,\"prototype\",{writable:!1}),e},e.exports.__esModule=!0,e.exports.default=e.exports},808:e=>{function t(r){return e.exports=t=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},e.exports.__esModule=!0,e.exports.default=e.exports,t(r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},655:(e,t,r)=>{var o=r(15);e.exports=function(e,t){if(\"function\"!=typeof t&&null!==t)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),t&&o(e,t)},e.exports.__esModule=!0,e.exports.default=e.exports},35:e=>{e.exports=function(e){try{return-1!==Function.toString.call(e).indexOf(\"[native code]\")}catch(t){return\"function\"==typeof e}},e.exports.__esModule=!0,e.exports.default=e.exports},617:e=>{e.exports=function(){if(\"undefined\"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if(\"function\"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}},e.exports.__esModule=!0,e.exports.default=e.exports},872:e=>{e.exports=function(e,t){var r=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=r){var o,n,u,s,p=[],i=!0,f=!1;try{if(u=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;i=!1}else for(;!(i=(o=u.call(r)).done)&&(p.push(o.value),p.length!==t);i=!0);}catch(e){f=!0,n=e}finally{try{if(!i&&null!=r.return&&(s=r.return(),Object(s)!==s))return}finally{if(f)throw n}}return p}},e.exports.__esModule=!0,e.exports.default=e.exports},218:e=>{e.exports=function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")},e.exports.__esModule=!0,e.exports.default=e.exports},993:(e,t,r)=>{var o=r(698).default,n=r(115);e.exports=function(e,t){if(t&&(\"object\"===o(t)||\"function\"==typeof t))return t;if(void 0!==t)throw new TypeError(\"Derived constructors may only return object or undefined\");return n(e)},e.exports.__esModule=!0,e.exports.default=e.exports},15:e=>{function t(r,o){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(r,o)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},424:(e,t,r)=>{var o=r(372),n=r(872),u=r(116),s=r(218);e.exports=function(e,t){return o(e)||n(e,t)||u(e,t)||s()},e.exports.__esModule=!0,e.exports.default=e.exports},36:(e,t,r)=>{var o=r(698).default;e.exports=function(e,t){if(\"object\"!=o(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||\"default\");if(\"object\"!=o(n))return n;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===t?String:Number)(e)},e.exports.__esModule=!0,e.exports.default=e.exports},62:(e,t,r)=>{var o=r(698).default,n=r(36);e.exports=function(e){var t=n(e,\"string\");return\"symbol\"==o(t)?t:String(t)},e.exports.__esModule=!0,e.exports.default=e.exports},698:e=>{function t(r){return e.exports=t=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},116:(e,t,r)=>{var o=r(897);e.exports=function(e,t){if(e){if(\"string\"==typeof e)return o(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return\"Object\"===r&&e.constructor&&(r=e.constructor.name),\"Map\"===r||\"Set\"===r?Array.from(e):\"Arguments\"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(e,t):void 0}},e.exports.__esModule=!0,e.exports.default=e.exports},496:(e,t,r)=>{var o=r(808),n=r(15),u=r(35),s=r(515);function p(t){var r=\"function\"==typeof Map?new Map:void 0;return e.exports=p=function(e){if(null===e||!u(e))return e;if(\"function\"!=typeof e)throw new TypeError(\"Super expression must either be null or a function\");if(void 0!==r){if(r.has(e))return r.get(e);r.set(e,t)}function t(){return s(e,arguments,o(this).constructor)}return t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),n(t,e)},e.exports.__esModule=!0,e.exports.default=e.exports,p(t)}e.exports=p,e.exports.__esModule=!0,e.exports.default=e.exports}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var u=t[o]={exports:{}};return e[o].call(u.exports,u,u.exports,r),u.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{\"use strict\";r(31)})()})();"; // tslint:disable-line:max-line-length
9
76
 
10
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
77
  var blob = new Blob([worklet], {
13
78
  type: 'application/javascript; charset=utf-8'
14
79
  });
@@ -36,39 +101,62 @@
36
101
  return _ref.apply(this, arguments);
37
102
  };
38
103
  }();
39
- function createTimedAudioBufferSourceNodeAudioWorkletNode(audioWorkletNodeConstructor, context) {
40
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
104
+ var convertToContextFrame = createConvertToContextFrame(createPerformance());
105
+ var subscribeToTimingObject = createSubscribeToTimingObject(createScheduleAudioBufferSourceNode(convertToContextFrame));
106
+ function createTimedAudioBufferSourceNodeAudioWorkletNode(audioWorkletNodeConstructor, context, createAudioBufferSourceNode) {
107
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
41
108
  var _a, _b;
42
109
  var _options$buffer = options.buffer,
43
- buffer = _options$buffer === void 0 ? null : _options$buffer,
44
- _options$timingObject = options.timingObject,
110
+ buffer = _options$buffer === void 0 ? null : _options$buffer;
111
+ if (buffer instanceof AudioBuffer && buffer.sampleRate !== context.sampleRate) {
112
+ throw new TypeError('The AudioBuffer must have the same sampleRate as the AudioContext.');
113
+ }
114
+ var _options$timingObject = options.timingObject,
45
115
  timingObject = _options$timingObject === void 0 ? null : _options$timingObject;
46
116
  var _ref2 = (_a = timingObject === null || timingObject === void 0 ? void 0 : timingObject.query()) !== null && _a !== void 0 ? _a : {},
47
117
  _ref2$position = _ref2.position,
48
118
  position = _ref2$position === void 0 ? 0 : _ref2$position,
49
119
  _ref2$timestamp = _ref2.timestamp,
50
120
  timestamp = _ref2$timestamp === void 0 ? 0 : _ref2$timestamp;
51
- var audioWorkletNode = new audioWorkletNodeConstructor(context, 'timed-audio-buffer-source-node-audio-worklet-processor', _objectSpread(_objectSpread({}, options), {}, {
52
- numberOfInputs: 0,
121
+ var audioWorkletNode = new audioWorkletNodeConstructor(context, 'timed-audio-buffer-source-node-audio-worklet-processor', {
122
+ numberOfInputs: 1,
53
123
  numberOfOutputs: 1,
54
124
  outputChannelCount: [(_b = buffer === null || buffer === void 0 ? void 0 : buffer.numberOfChannels) !== null && _b !== void 0 ? _b : 1],
55
- pocessorOptions: {
56
- buffer: buffer instanceof standardizedAudioContext.AudioBuffer ? Array.from({
125
+ processorOptions: {
126
+ buffer: buffer instanceof AudioBuffer ? Array.from({
57
127
  length: buffer.numberOfChannels
58
128
  }, function (_, channel) {
59
129
  return buffer.getChannelData(channel);
60
130
  }) : null,
61
131
  position: position,
62
- timestamp: timestamp
132
+ timestamp: convertToContextFrame(context, timestamp)
63
133
  }
64
- }));
134
+ });
135
+ var removeListener = null;
65
136
  Object.defineProperties(audioWorkletNode, {
66
137
  port: {
67
138
  get: function get() {
68
139
  throw new Error("The port of a TimedAudioBufferSourceNodeAudioWorkletNode can't be accessed.");
69
140
  }
141
+ },
142
+ timingObject: {
143
+ get: function get() {
144
+ return timingObject;
145
+ },
146
+ set: function set(value) {
147
+ removeListener === null || removeListener === void 0 ? void 0 : removeListener();
148
+ removeListener = null;
149
+ if (value === null) {
150
+ timingObject = value;
151
+ } else {
152
+ throw new TypeError('A TimingObject can only be set in the constructor.');
153
+ }
154
+ }
70
155
  }
71
156
  });
157
+ if (timingObject !== null) {
158
+ removeListener = subscribeToTimingObject(audioWorkletNode, context, createAudioBufferSourceNode, timingObject);
159
+ }
72
160
  return audioWorkletNode;
73
161
  }
74
162
 
package/package.json CHANGED
@@ -9,18 +9,18 @@
9
9
  }
10
10
  },
11
11
  "dependencies": {
12
- "@babel/runtime": "^7.23.4",
13
- "standardized-audio-context": "^25.3.59",
14
- "timed-audio-buffer-source-node-audio-worklet-processor": "^1.0.12",
15
- "timing-object": "^3.1.68",
12
+ "@babel/runtime": "^7.23.6",
13
+ "standardized-audio-context": "^25.3.60",
14
+ "timed-audio-buffer-source-node-audio-worklet-processor": "^2.0.0",
15
+ "timing-object": "^3.1.70",
16
16
  "tslib": "^2.6.2"
17
17
  },
18
18
  "description": "This module provides a loader for the TimedAudioBufferSourceNodeAudioWorkletProcessor and the corresponding TimedAudioBufferSourceNodeAudioWorkletNode.",
19
19
  "devDependencies": {
20
- "@babel/core": "^7.23.3",
20
+ "@babel/core": "^7.23.6",
21
21
  "@babel/plugin-external-helpers": "^7.23.3",
22
- "@babel/plugin-transform-runtime": "^7.23.4",
23
- "@babel/preset-env": "^7.23.3",
22
+ "@babel/plugin-transform-runtime": "^7.23.6",
23
+ "@babel/preset-env": "^7.23.6",
24
24
  "@commitlint/cli": "^17.8.0",
25
25
  "@commitlint/config-angular": "^17.8.0",
26
26
  "@rollup/plugin-babel": "^6.0.4",
@@ -29,8 +29,8 @@
29
29
  "chai": "^4.3.10",
30
30
  "commitizen": "^4.3.0",
31
31
  "cz-conventional-changelog": "^3.3.0",
32
- "eslint": "^8.54.0",
33
- "eslint-config-holy-grail": "^57.2.25",
32
+ "eslint": "^8.56.0",
33
+ "eslint-config-holy-grail": "^57.2.26",
34
34
  "grunt": "^1.6.1",
35
35
  "grunt-cli": "^1.4.3",
36
36
  "grunt-sh": "^0.2.1",
@@ -41,15 +41,15 @@
41
41
  "karma-mocha": "^2.0.1",
42
42
  "karma-sauce-launcher": "^4.3.6",
43
43
  "karma-sinon-chai": "^2.0.2",
44
- "karma-webkit-launcher": "^2.1.0",
44
+ "karma-webkit-launcher": "^2.4.0",
45
45
  "karma-webpack": "^5.0.0",
46
- "lint-staged": "^15.1.0",
46
+ "lint-staged": "^15.2.0",
47
47
  "load-grunt-config": "^4.0.1",
48
48
  "memfs": "^4.6.0",
49
49
  "mocha": "^10.2.0",
50
- "prettier": "^3.1.0",
50
+ "prettier": "^3.1.1",
51
51
  "rimraf": "^5.0.5",
52
- "rollup": "^4.5.2",
52
+ "rollup": "^4.9.1",
53
53
  "sinon": "^17.0.1",
54
54
  "sinon-chai": "^3.7.0",
55
55
  "terser-webpack-plugin": "^5.3.9",
@@ -57,7 +57,7 @@
57
57
  "tsconfig-holy-grail": "^14.0.8",
58
58
  "tslint": "^6.1.3",
59
59
  "tslint-config-holy-grail": "^55.0.5",
60
- "typescript": "^5.3.2",
60
+ "typescript": "^5.3.3",
61
61
  "webpack": "^5.89.0",
62
62
  "webpack-cli": "^5.1.4"
63
63
  },
@@ -86,5 +86,5 @@
86
86
  "test": "grunt lint && grunt test"
87
87
  },
88
88
  "types": "build/es2019/module.d.ts",
89
- "version": "1.0.16"
89
+ "version": "2.0.0"
90
90
  }
@@ -0,0 +1,11 @@
1
+ import { TContext, TNativeContext } from 'standardized-audio-context';
2
+ import type { createPerformance } from './performance';
3
+
4
+ export const createConvertToContextFrame =
5
+ (performance: ReturnType<typeof createPerformance>) => (context: TContext | TNativeContext, timestamp: number) => {
6
+ if (performance === null) {
7
+ throw new Error('Performance is not available.');
8
+ }
9
+
10
+ return Math.round((context.currentTime - performance.now() / 1000 + timestamp) * context.sampleRate);
11
+ };
@@ -0,0 +1,2 @@
1
+ export const createPerformance = () =>
2
+ typeof window === 'undefined' ? null : typeof window.performance === 'undefined' ? null : window.performance;
@@ -0,0 +1,36 @@
1
+ import {
2
+ IAudioBufferSourceNode,
3
+ IAudioWorkletNode,
4
+ TContext,
5
+ TNativeAudioBufferSourceNode,
6
+ TNativeAudioWorkletNode,
7
+ TNativeContext
8
+ } from 'standardized-audio-context';
9
+ import { ITimingObject } from 'timing-object';
10
+ import type { createConvertToContextFrame } from './convert-to-context-frame';
11
+
12
+ export const createScheduleAudioBufferSourceNode =
13
+ (convertToContextFrame: ReturnType<typeof createConvertToContextFrame>) =>
14
+ <T extends TContext | TNativeContext>(
15
+ audioWorkletNode: T extends TContext ? IAudioWorkletNode<T> : TNativeAudioWorkletNode,
16
+ context: T,
17
+ createAudioBufferSourceNode: T extends TContext
18
+ ? (context: TContext) => IAudioBufferSourceNode<TContext>
19
+ : (context: TNativeContext) => TNativeAudioBufferSourceNode,
20
+ timingObject: ITimingObject
21
+ ): Promise<void> => {
22
+ const audioBuffer = new AudioBuffer({ length: 2, sampleRate: context.sampleRate });
23
+ const audioBufferSourceNode = createAudioBufferSourceNode(<any>context);
24
+ const { position, timestamp } = timingObject.query();
25
+
26
+ audioBuffer.copyToChannel(new Float32Array([position, convertToContextFrame(context, timestamp)]), 0);
27
+
28
+ audioBufferSourceNode.buffer = audioBuffer;
29
+
30
+ const promise = new Promise<void>((resolve) => audioBufferSourceNode.addEventListener('ended', () => resolve(), { once: true }));
31
+
32
+ audioBufferSourceNode.connect(<any>audioWorkletNode);
33
+ audioBufferSourceNode.start();
34
+
35
+ return promise;
36
+ };
@@ -0,0 +1,49 @@
1
+ import {
2
+ IAudioBufferSourceNode,
3
+ IAudioWorkletNode,
4
+ TContext,
5
+ TNativeAudioBufferSourceNode,
6
+ TNativeAudioWorkletNode,
7
+ TNativeContext
8
+ } from 'standardized-audio-context';
9
+ import { ITimingObject } from 'timing-object';
10
+ import type { createScheduleAudioBufferSourceNode } from './schedule-audio-buffer-source-node';
11
+
12
+ export const createSubscribeToTimingObject =
13
+ (scheduleAudioBufferSourceNode: ReturnType<typeof createScheduleAudioBufferSourceNode>) =>
14
+ <T extends TContext | TNativeContext>(
15
+ audioWorkletNode: T extends TContext ? IAudioWorkletNode<T> : TNativeAudioWorkletNode,
16
+ context: T,
17
+ createAudioBufferSourceNode: T extends TContext
18
+ ? (context: TContext) => IAudioBufferSourceNode<TContext>
19
+ : (context: TNativeContext) => TNativeAudioBufferSourceNode,
20
+ timingObject: ITimingObject
21
+ ) => {
22
+ let hasPendingUpdate = false;
23
+ let isSendingUpdate = false;
24
+
25
+ const scheduleUpdate = () => {
26
+ hasPendingUpdate = false;
27
+
28
+ scheduleAudioBufferSourceNode(audioWorkletNode, context, createAudioBufferSourceNode, timingObject).then(() => {
29
+ if (hasPendingUpdate) {
30
+ scheduleUpdate();
31
+ } else {
32
+ isSendingUpdate = false;
33
+ }
34
+ });
35
+ };
36
+ const listener = () => {
37
+ if (isSendingUpdate) {
38
+ hasPendingUpdate = true;
39
+ } else {
40
+ isSendingUpdate = true;
41
+
42
+ scheduleUpdate();
43
+ }
44
+ };
45
+
46
+ timingObject.addEventListener('change', listener);
47
+
48
+ return () => timingObject.removeEventListener('change', listener);
49
+ };
@@ -1,3 +1,6 @@
1
1
  import { IAudioWorkletNode, TContext } from 'standardized-audio-context';
2
+ import { ITimingObject } from 'timing-object';
2
3
 
3
- export interface ITimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext> extends IAudioWorkletNode<T> {}
4
+ export interface ITimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext> extends IAudioWorkletNode<T> {
5
+ timingObject: null | ITimingObject;
6
+ }
package/src/module.ts CHANGED
@@ -1,12 +1,17 @@
1
1
  import {
2
- AudioBuffer,
2
+ IAudioBufferSourceNode,
3
3
  IAudioWorkletNode,
4
4
  TAudioWorkletNodeConstructor,
5
5
  TContext,
6
+ TNativeAudioBufferSourceNode,
6
7
  TNativeAudioWorkletNode,
7
8
  TNativeAudioWorkletNodeConstructor,
8
9
  TNativeContext
9
10
  } from 'standardized-audio-context';
11
+ import { createConvertToContextFrame } from './factories/convert-to-context-frame';
12
+ import { createPerformance } from './factories/performance';
13
+ import { createScheduleAudioBufferSourceNode } from './factories/schedule-audio-buffer-source-node';
14
+ import { createSubscribeToTimingObject } from './factories/subscribe-to-timing-object';
10
15
  import { ITimedAudioBufferSourceNodeAudioWorkletNode } from './interfaces';
11
16
  import { TAnyTimedAudioBufferSourceNodeAudioWorkletNodeOptions, TNativeTimedAudioBufferSourceNodeAudioWorkletNode } from './types';
12
17
  import { worklet } from './worklet/worklet';
@@ -30,9 +35,15 @@ export const addTimedAudioBufferSourceNodeAudioWorkletModule = async (addAudioWo
30
35
  }
31
36
  };
32
37
 
38
+ const convertToContextFrame = createConvertToContextFrame(createPerformance());
39
+ const subscribeToTimingObject = createSubscribeToTimingObject(createScheduleAudioBufferSourceNode(convertToContextFrame));
40
+
33
41
  export function createTimedAudioBufferSourceNodeAudioWorkletNode<T extends TContext | TNativeContext>(
34
42
  audioWorkletNodeConstructor: T extends TContext ? TAudioWorkletNodeConstructor : TNativeAudioWorkletNodeConstructor,
35
43
  context: T,
44
+ createAudioBufferSourceNode: T extends TContext
45
+ ? (context: TContext) => IAudioBufferSourceNode<TContext>
46
+ : (context: TNativeContext) => TNativeAudioBufferSourceNode,
36
47
  options: Partial<TAnyTimedAudioBufferSourceNodeAudioWorkletNodeOptions<T>> = {}
37
48
  ): T extends TContext ? ITimedAudioBufferSourceNodeAudioWorkletNode<T> : TNativeTimedAudioBufferSourceNodeAudioWorkletNode {
38
49
  type TAnyAudioWorkletNode = T extends TContext ? IAudioWorkletNode<T> : TNativeAudioWorkletNode;
@@ -40,34 +51,60 @@ export function createTimedAudioBufferSourceNodeAudioWorkletNode<T extends TCont
40
51
  ? ITimedAudioBufferSourceNodeAudioWorkletNode<T>
41
52
  : TNativeTimedAudioBufferSourceNodeAudioWorkletNode;
42
53
 
43
- const { buffer = null, timingObject = null } = options;
54
+ const { buffer = null } = options;
55
+
56
+ if (buffer instanceof AudioBuffer && buffer.sampleRate !== context.sampleRate) {
57
+ throw new TypeError('The AudioBuffer must have the same sampleRate as the AudioContext.');
58
+ }
59
+
60
+ let { timingObject = null } = options;
61
+
44
62
  const { position = 0, timestamp = 0 } = timingObject?.query() ?? {};
45
63
  const audioWorkletNode: TAnyAudioWorkletNode = new (<any>audioWorkletNodeConstructor)(
46
64
  context,
47
65
  'timed-audio-buffer-source-node-audio-worklet-processor',
48
66
  {
49
- ...options,
50
- numberOfInputs: 0,
67
+ numberOfInputs: 1,
51
68
  numberOfOutputs: 1,
52
69
  outputChannelCount: [buffer?.numberOfChannels ?? 1],
53
- pocessorOptions: {
70
+ processorOptions: {
54
71
  buffer:
55
72
  buffer instanceof AudioBuffer
56
73
  ? Array.from({ length: buffer.numberOfChannels }, (_, channel) => buffer.getChannelData(channel))
57
74
  : null,
58
75
  position,
59
- timestamp
76
+ timestamp: convertToContextFrame(context, timestamp)
60
77
  }
61
78
  }
62
79
  );
63
80
 
81
+ let removeListener: null | (() => void) = null;
82
+
64
83
  Object.defineProperties(audioWorkletNode, {
65
84
  port: {
66
85
  get(): TAnyTimedAudioBufferSourceNodeAudioWorkletNode['port'] {
67
86
  throw new Error("The port of a TimedAudioBufferSourceNodeAudioWorkletNode can't be accessed.");
68
87
  }
88
+ },
89
+ timingObject: {
90
+ get: () => timingObject,
91
+ set: (value: TAnyTimedAudioBufferSourceNodeAudioWorkletNode['timingObject']) => {
92
+ removeListener?.();
93
+
94
+ removeListener = null;
95
+
96
+ if (value === null) {
97
+ timingObject = value;
98
+ } else {
99
+ throw new TypeError('A TimingObject can only be set in the constructor.');
100
+ }
101
+ }
69
102
  }
70
103
  });
71
104
 
105
+ if (timingObject !== null) {
106
+ removeListener = subscribeToTimingObject(audioWorkletNode, context, createAudioBufferSourceNode, timingObject);
107
+ }
108
+
72
109
  return <TAnyTimedAudioBufferSourceNodeAudioWorkletNode>audioWorkletNode;
73
110
  }
@@ -1,3 +1,6 @@
1
1
  import { TNativeAudioWorkletNode } from 'standardized-audio-context';
2
+ import { ITimingObject } from 'timing-object';
2
3
 
3
- export type TNativeTimedAudioBufferSourceNodeAudioWorkletNode = TNativeAudioWorkletNode;
4
+ export type TNativeTimedAudioBufferSourceNodeAudioWorkletNode = TNativeAudioWorkletNode & {
5
+ timingObject: null | ITimingObject;
6
+ };
@@ -1,2 +1,2 @@
1
1
  // This is the minified and stringified code of the timed-audio-buffer-source-node-audio-worklet-processor package.
2
- export const worklet = `(()=>{"use strict";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const u="object"==typeof n&&null!==n&&"buffer"in n?n.buffer:null;if(!(null===u||Array.isArray(u)&&u.every((e=>e instanceof Float32Array))))throw new Error("The buffer needs to be either null or an array with where each element is a Float32Array.");if(0!==t)throw new Error("The numberOfInputs must be 0.");if(1!==r)throw new Error("The numberOfOutputs must be 1.");const i=null!==(s=null==u?void 0:u.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||i!==o[0])throw new Error("The outputChannelCount must match the number of channels of the buffer.");const f="object"==typeof n&&null!==n&&"position"in n?n.position:0;if("number"!=typeof f)throw new Error('The position needs to be of type "number".');const l="object"==typeof n&&null!==n&&"timestamp"in n?n.timestamp:0;if("number"!=typeof l)throw new Error('The timestamp needs to be of type "number".');super(),this._buffer=u,this._position=f,this._timestamp=l}process(e,t){let[r]=t;if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],o=r[t];for(let t=0;t<128;t+=1){const r=this._position+currentFrame-this._timestamp+t;r>=0&&r<e.length&&(o[t]=e[r])}}}return!0}}e.parameterDescriptors=[],registerProcessor("timed-audio-buffer-source-node-audio-worklet-processor",e)})();`; // tslint:disable-line:max-line-length
2
+ export const worklet = `(()=>{"use strict";class e extends AudioWorkletProcessor{constructor(e){let{numberOfInputs:t,numberOfOutputs:r,outputChannelCount:o,processorOptions:n}=e;var s;const i="object"==typeof n&&null!==n&&"buffer"in n?n.buffer:null;if(!(null===i||Array.isArray(i)&&i.every((e=>e instanceof Float32Array))))throw new Error("The buffer needs to be either null or an array with where each element is a Float32Array.");if(1!==t)throw new Error("The numberOfInputs must be 1.");if(1!==r)throw new Error("The numberOfOutputs must be 1.");const u=null!==(s=null==i?void 0:i.length)&&void 0!==s?s:1;if(void 0===o||1!==o.length||u!==o[0])throw new Error("The outputChannelCount must match the number of channels of the buffer.");const f="object"==typeof n&&null!==n&&"position"in n?n.position:0;if("number"!=typeof f)throw new Error('The position needs to be of type "number".');const h="object"==typeof n&&null!==n&&"timestamp"in n?n.timestamp:0;if("number"!=typeof h)throw new Error('The timestamp needs to be of type "number".');super(),this._buffer=i,this._position=f,this._timestamp=h}process(e,t){let[r]=e,[o]=t;if(r.length>0){const[e]=r;e.length>1&&(this._position=Math.round(e[0]),this._timestamp=Math.round(e[1]))}if(null!==this._buffer){const e=this._buffer.length;for(let t=0;t<e;t+=1){const e=this._buffer[t],r=o[t];for(let t=0;t<128;t+=1){const o=this._position+currentFrame-this._timestamp+t;o>=0&&o<e.length&&(r[t]=e[o])}}}return!0}}e.parameterDescriptors=[],registerProcessor("timed-audio-buffer-source-node-audio-worklet-processor",e)})();`; // tslint:disable-line:max-line-length