waa-play 0.2.0 → 0.2.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.
- package/README.md +41 -89
- package/dist/adapters.cjs +6 -6
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- package/dist/adapters.js +1 -1
- package/dist/buffer.cjs +5 -5
- package/dist/buffer.d.cts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -1
- package/dist/{chunk-T74FBKTY.js → chunk-2FGUFHZM.js} +2 -2
- package/dist/chunk-2FGUFHZM.js.map +1 -0
- package/dist/{chunk-CPAT75WD.cjs → chunk-3VTU5OX5.cjs} +2 -2
- package/dist/chunk-3VTU5OX5.cjs.map +1 -0
- package/dist/{chunk-2DL7CAEP.js → chunk-7JUVBZ6B.js} +2 -2
- package/dist/chunk-7JUVBZ6B.js.map +1 -0
- package/dist/{chunk-D5CD5KQZ.cjs → chunk-BRS7LZVH.cjs} +2 -2
- package/dist/chunk-BRS7LZVH.cjs.map +1 -0
- package/dist/{chunk-QWNV2BZ5.cjs → chunk-F6WXD3XW.cjs} +2 -2
- package/dist/chunk-F6WXD3XW.cjs.map +1 -0
- package/dist/{chunk-C2ASIYN5.js → chunk-FESPIMZM.js} +3 -7
- package/dist/chunk-FESPIMZM.js.map +1 -0
- package/dist/{chunk-GYH2JSCY.js → chunk-FY273Z3I.js} +2 -2
- package/dist/chunk-FY273Z3I.js.map +1 -0
- package/dist/{chunk-SIMLANWE.cjs → chunk-G37HMZEX.cjs} +1028 -955
- package/dist/chunk-G37HMZEX.cjs.map +1 -0
- package/dist/{chunk-2FFORBOP.js → chunk-GDBOHOGF.js} +1027 -955
- package/dist/chunk-GDBOHOGF.js.map +1 -0
- package/dist/{chunk-5J7S6QV3.cjs → chunk-HIF3UAF3.cjs} +2 -2
- package/dist/chunk-HIF3UAF3.cjs.map +1 -0
- package/dist/{chunk-CRODJ4KS.js → chunk-HTN52U23.js} +13 -6
- package/dist/chunk-HTN52U23.js.map +1 -0
- package/dist/{chunk-X4IFO7U7.js → chunk-HYRDCTBO.js} +143 -116
- package/dist/chunk-HYRDCTBO.js.map +1 -0
- package/dist/{chunk-VKT7YCWK.js → chunk-JIHPQAEA.js} +6 -3
- package/dist/chunk-JIHPQAEA.js.map +1 -0
- package/dist/chunk-KVKW7W66.cjs +148 -0
- package/dist/chunk-KVKW7W66.cjs.map +1 -0
- package/dist/{chunk-4LNVRSTM.cjs → chunk-OIY6I4TU.cjs} +3 -7
- package/dist/chunk-OIY6I4TU.cjs.map +1 -0
- package/dist/{chunk-7S5KWTZ6.cjs → chunk-OZN5X4N6.cjs} +6 -3
- package/dist/chunk-OZN5X4N6.cjs.map +1 -0
- package/dist/{chunk-CJJC6ASU.js → chunk-PL4J3NR7.js} +2 -2
- package/dist/chunk-PL4J3NR7.js.map +1 -0
- package/dist/{chunk-IMNRPYBM.js → chunk-QFJQU7TQ.js} +10 -10
- package/dist/chunk-QFJQU7TQ.js.map +1 -0
- package/dist/{chunk-M5PDY5EZ.cjs → chunk-QGZGERGK.cjs} +2 -2
- package/dist/chunk-QGZGERGK.cjs.map +1 -0
- package/dist/{chunk-QFFQQMU4.cjs → chunk-VOSIA3GF.cjs} +13 -6
- package/dist/chunk-VOSIA3GF.cjs.map +1 -0
- package/dist/{chunk-CTUCTTIE.cjs → chunk-VY4UMZMJ.cjs} +145 -118
- package/dist/chunk-VY4UMZMJ.cjs.map +1 -0
- package/dist/{chunk-LETS7FKB.js → chunk-YFK7ETCF.js} +2 -2
- package/dist/chunk-YFK7ETCF.js.map +1 -0
- package/dist/context.d.cts +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/emitter.cjs +2 -2
- package/dist/emitter.js +1 -1
- package/dist/engine-7DCOERRN.js +4 -0
- package/dist/{engine-TYI7OX7O.js.map → engine-7DCOERRN.js.map} +1 -1
- package/dist/engine-ALWPAIX6.cjs +17 -0
- package/dist/{engine-QUMYW73L.cjs.map → engine-ALWPAIX6.cjs.map} +1 -1
- package/dist/fade.cjs +5 -5
- package/dist/fade.d.cts +1 -1
- package/dist/fade.d.ts +1 -1
- package/dist/fade.js +1 -1
- package/dist/index.cjs +44 -44
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +10 -10
- package/dist/nodes.cjs +11 -11
- package/dist/nodes.js +1 -1
- package/dist/play.cjs +3 -3
- package/dist/play.d.cts +1 -1
- package/dist/play.d.ts +1 -1
- package/dist/play.js +2 -2
- package/dist/player.cjs +11 -11
- package/dist/player.d.cts +1 -1
- package/dist/player.d.ts +1 -1
- package/dist/player.js +10 -10
- package/dist/scheduler.cjs +3 -3
- package/dist/scheduler.d.cts +1 -1
- package/dist/scheduler.d.ts +1 -1
- package/dist/scheduler.js +1 -1
- package/dist/stretcher.cjs +3 -3
- package/dist/stretcher.d.cts +4 -4
- package/dist/stretcher.d.ts +4 -4
- package/dist/stretcher.js +2 -2
- package/dist/synth.cjs +4 -4
- package/dist/synth.js +1 -1
- package/dist/{types-DUrbEbPl.d.cts → types-BYC6m7Q0.d.cts} +6 -6
- package/dist/{types-DUrbEbPl.d.ts → types-BYC6m7Q0.d.ts} +6 -6
- package/dist/waveform.cjs +4 -4
- package/dist/waveform.d.cts +1 -1
- package/dist/waveform.d.ts +1 -1
- package/dist/waveform.js +1 -1
- package/package.json +12 -5
- package/dist/chunk-2DL7CAEP.js.map +0 -1
- package/dist/chunk-2FFORBOP.js.map +0 -1
- package/dist/chunk-4LNVRSTM.cjs.map +0 -1
- package/dist/chunk-5J7S6QV3.cjs.map +0 -1
- package/dist/chunk-7S5KWTZ6.cjs.map +0 -1
- package/dist/chunk-C2ASIYN5.js.map +0 -1
- package/dist/chunk-CJJC6ASU.js.map +0 -1
- package/dist/chunk-CPAT75WD.cjs.map +0 -1
- package/dist/chunk-CRODJ4KS.js.map +0 -1
- package/dist/chunk-CTUCTTIE.cjs.map +0 -1
- package/dist/chunk-D5CD5KQZ.cjs.map +0 -1
- package/dist/chunk-GYH2JSCY.js.map +0 -1
- package/dist/chunk-IMNRPYBM.js.map +0 -1
- package/dist/chunk-LETS7FKB.js.map +0 -1
- package/dist/chunk-M5PDY5EZ.cjs.map +0 -1
- package/dist/chunk-QFFQQMU4.cjs.map +0 -1
- package/dist/chunk-QWNV2BZ5.cjs.map +0 -1
- package/dist/chunk-SIMLANWE.cjs.map +0 -1
- package/dist/chunk-T74FBKTY.js.map +0 -1
- package/dist/chunk-VKT7YCWK.js.map +0 -1
- package/dist/chunk-X4IFO7U7.js.map +0 -1
- package/dist/chunk-XZBMBZA3.cjs +0 -148
- package/dist/chunk-XZBMBZA3.cjs.map +0 -1
- package/dist/engine-QUMYW73L.cjs +0 -13
- package/dist/engine-TYI7OX7O.js +0 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/player.ts"],"names":["createContext","resumeContext","ensureRunning","now","loadBuffer","loadBufferFromBlob","loadBuffers","getBufferInfo","play","createGain","createAnalyser","createFilter","createPanner","createCompressor","rampGain","getFrequencyData","getFrequencyDataByte","chain","disconnectChain","extractPeaks","extractPeakPairs","extractRMS","fadeIn","fadeOut","crossfade","autoFade","createScheduler","createClock","createSineBuffer","createNoiseBuffer","createClickBuffer","getSnapshot","subscribeSnapshot","onFrame","whenEnded","whenPosition"],"mappings":"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","file":"chunk-KVKW7W66.cjs","sourcesContent":["import { getSnapshot, onFrame, subscribeSnapshot, whenEnded, whenPosition } from \"./adapters.js\";\nimport { getBufferInfo, loadBuffer, loadBufferFromBlob, loadBuffers } from \"./buffer.js\";\nimport { createContext, ensureRunning, now, resumeContext } from \"./context.js\";\nimport { autoFade, crossfade, fadeIn, fadeOut } from \"./fade.js\";\nimport {\n chain,\n createAnalyser as createAnalyserNode,\n createCompressor as createCompressorNode,\n createFilter as createFilterNode,\n createGain as createGainNode,\n createPanner as createPannerNode,\n disconnectChain,\n getFrequencyData,\n getFrequencyDataByte,\n rampGain,\n} from \"./nodes.js\";\nimport { play } from \"./play.js\";\nimport type { Clock, Scheduler } from \"./scheduler.js\";\nimport { createClock, createScheduler } from \"./scheduler.js\";\nimport { createClickBuffer, createNoiseBuffer, createSineBuffer } from \"./synth.js\";\n\nimport type {\n AutoFadeOptions,\n BufferInfo,\n ClockOptions,\n CreateContextOptions,\n CrossfadeOptions,\n ExtractPeaksOptions,\n FadeOptions,\n LoadBufferOptions,\n PeakPair,\n Playback,\n PlaybackSnapshot,\n PlayOptions,\n SchedulerOptions,\n} from \"./types.js\";\nimport { extractPeakPairs, extractPeaks, extractRMS } from \"./waveform.js\";\n\nexport interface WaaPlayerOptions extends CreateContextOptions {}\n\nexport class WaaPlayer {\n readonly ctx: AudioContext;\n private readonly _ownsContext: boolean;\n\n constructor(ctxOrOptions?: AudioContext | WaaPlayerOptions) {\n if (ctxOrOptions && typeof (ctxOrOptions as AudioContext).createGain === \"function\") {\n this.ctx = ctxOrOptions as AudioContext;\n this._ownsContext = false;\n } else {\n this.ctx = createContext(ctxOrOptions as WaaPlayerOptions | undefined);\n this._ownsContext = true;\n }\n }\n\n // --- Context ---\n\n resume(): Promise<void> {\n return resumeContext(this.ctx);\n }\n\n ensureRunning(): Promise<void> {\n return ensureRunning(this.ctx);\n }\n\n now(): number {\n return now(this.ctx);\n }\n\n // --- Buffer ---\n\n load(url: string, options?: LoadBufferOptions): Promise<AudioBuffer> {\n return loadBuffer(this.ctx, url, options);\n }\n\n loadFromBlob(blob: Blob): Promise<AudioBuffer> {\n return loadBufferFromBlob(this.ctx, blob);\n }\n\n loadAll(map: Record<string, string>): Promise<Map<string, AudioBuffer>> {\n return loadBuffers(this.ctx, map);\n }\n\n getBufferInfo(buffer: AudioBuffer): BufferInfo {\n return getBufferInfo(buffer);\n }\n\n // --- Play ---\n\n play(buffer: AudioBuffer, options?: PlayOptions): Playback {\n return play(this.ctx, buffer, options);\n }\n\n // --- Nodes ---\n\n createGain(initialValue?: number): GainNode {\n return createGainNode(this.ctx, initialValue);\n }\n\n createAnalyser(options?: { fftSize?: number; smoothingTimeConstant?: number }): AnalyserNode {\n return createAnalyserNode(this.ctx, options);\n }\n\n createFilter(options?: {\n type?: BiquadFilterType;\n frequency?: number;\n Q?: number;\n gain?: number;\n }): BiquadFilterNode {\n return createFilterNode(this.ctx, options);\n }\n\n createPanner(pan?: number): StereoPannerNode {\n return createPannerNode(this.ctx, pan);\n }\n\n createCompressor(options?: {\n threshold?: number;\n knee?: number;\n ratio?: number;\n attack?: number;\n release?: number;\n }): DynamicsCompressorNode {\n return createCompressorNode(this.ctx, options);\n }\n\n rampGain(gain: GainNode, target: number, duration: number): void {\n rampGain(gain, target, duration);\n }\n\n getFrequencyData(analyser: AnalyserNode): Float32Array {\n return getFrequencyData(analyser);\n }\n\n getFrequencyDataByte(analyser: AnalyserNode): Uint8Array {\n return getFrequencyDataByte(analyser);\n }\n\n chain(...nodes: AudioNode[]): void {\n chain(...nodes);\n }\n\n disconnectChain(...nodes: AudioNode[]): void {\n disconnectChain(...nodes);\n }\n\n // --- Waveform ---\n\n extractPeaks(buffer: AudioBuffer, options?: ExtractPeaksOptions): number[] {\n return extractPeaks(buffer, options);\n }\n\n extractPeakPairs(buffer: AudioBuffer, options?: ExtractPeaksOptions): PeakPair[] {\n return extractPeakPairs(buffer, options);\n }\n\n extractRMS(buffer: AudioBuffer, options?: ExtractPeaksOptions & { channel?: number }): number[] {\n return extractRMS(buffer, options);\n }\n\n // --- Fade ---\n\n fadeIn(gain: GainNode, target: number, options?: FadeOptions): void {\n fadeIn(gain, target, options);\n }\n\n fadeOut(gain: GainNode, options?: FadeOptions): void {\n fadeOut(gain, options);\n }\n\n crossfade(gainA: GainNode, gainB: GainNode, options?: CrossfadeOptions): void {\n crossfade(gainA, gainB, options);\n }\n\n autoFade(playback: Playback, gain: GainNode, options?: AutoFadeOptions): () => void {\n return autoFade(playback, gain, options);\n }\n\n // --- Scheduler ---\n\n createScheduler(options?: SchedulerOptions): Scheduler {\n return createScheduler(this.ctx, options);\n }\n\n createClock(options?: ClockOptions): Clock {\n return createClock(this.ctx, options);\n }\n\n // --- Synth ---\n\n createSineBuffer(frequency: number, duration: number): AudioBuffer {\n return createSineBuffer(this.ctx, frequency, duration);\n }\n\n createNoiseBuffer(duration: number): AudioBuffer {\n return createNoiseBuffer(this.ctx, duration);\n }\n\n createClickBuffer(frequency: number, duration: number): AudioBuffer {\n return createClickBuffer(this.ctx, frequency, duration);\n }\n\n // --- Adapters ---\n\n getSnapshot(playback: Playback): PlaybackSnapshot {\n return getSnapshot(playback);\n }\n\n subscribeSnapshot(playback: Playback, callback: () => void): () => void {\n return subscribeSnapshot(playback, callback);\n }\n\n onFrame(playback: Playback, callback: (snapshot: PlaybackSnapshot) => void): () => void {\n return onFrame(playback, callback);\n }\n\n whenEnded(playback: Playback): Promise<void> {\n return whenEnded(playback);\n }\n\n whenPosition(playback: Playback, position: number): Promise<void> {\n return whenPosition(playback, position);\n }\n\n // --- Lifecycle ---\n\n dispose(): void {\n if (this._ownsContext) {\n this.ctx.close();\n }\n }\n}\n"]}
|
|
@@ -9,10 +9,7 @@ function applyRamp(node, from, to, duration, curve) {
|
|
|
9
9
|
param.setValueAtTime(from, now);
|
|
10
10
|
switch (curve) {
|
|
11
11
|
case "exponential":
|
|
12
|
-
param.exponentialRampToValueAtTime(
|
|
13
|
-
Math.max(to, EXP_MIN),
|
|
14
|
-
now + duration
|
|
15
|
-
);
|
|
12
|
+
param.exponentialRampToValueAtTime(Math.max(to, EXP_MIN), now + duration);
|
|
16
13
|
break;
|
|
17
14
|
case "equal-power": {
|
|
18
15
|
const steps = Math.max(Math.ceil(duration * 100), 2);
|
|
@@ -25,7 +22,6 @@ function applyRamp(node, from, to, duration, curve) {
|
|
|
25
22
|
param.setValueCurveAtTime(values, now, duration);
|
|
26
23
|
break;
|
|
27
24
|
}
|
|
28
|
-
case "linear":
|
|
29
25
|
default:
|
|
30
26
|
param.linearRampToValueAtTime(to, now + duration);
|
|
31
27
|
break;
|
|
@@ -68,5 +64,5 @@ exports.autoFade = autoFade;
|
|
|
68
64
|
exports.crossfade = crossfade;
|
|
69
65
|
exports.fadeIn = fadeIn;
|
|
70
66
|
exports.fadeOut = fadeOut;
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
67
|
+
//# sourceMappingURL=chunk-OIY6I4TU.cjs.map
|
|
68
|
+
//# sourceMappingURL=chunk-OIY6I4TU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/fade.ts"],"names":[],"mappings":"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","file":"chunk-OIY6I4TU.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// M7: Fade utilities\n// ---------------------------------------------------------------------------\n\nimport type {\n AutoFadeOptions,\n CrossfadeOptions,\n FadeCurve,\n FadeOptions,\n Playback,\n} from \"./types.js\";\n\n/** Minimum value used for exponential ramps (cannot ramp to/from 0). */\nconst EXP_MIN = 0.0001;\n\nfunction applyRamp(\n node: GainNode,\n from: number,\n to: number,\n duration: number,\n curve: FadeCurve,\n): void {\n const param = node.gain;\n const now = node.context.currentTime;\n param.cancelScheduledValues(now);\n param.setValueAtTime(from, now);\n\n switch (curve) {\n case \"exponential\":\n param.exponentialRampToValueAtTime(Math.max(to, EXP_MIN), now + duration);\n break;\n case \"equal-power\": {\n // Approximate equal-power with a setValueCurveAtTime.\n const steps = Math.max(Math.ceil(duration * 100), 2);\n const values = new Float32Array(steps);\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const gain = from + (to - from) * Math.sin((t * Math.PI) / 2);\n values[i] = gain;\n }\n param.setValueCurveAtTime(values, now, duration);\n break;\n }\n default:\n param.linearRampToValueAtTime(to, now + duration);\n break;\n }\n}\n\n/**\n * Fade a `GainNode` in from 0 to `target`.\n */\nexport function fadeIn(gain: GainNode, target: number, options?: FadeOptions): void {\n const { duration = 1, curve = \"linear\" } = options ?? {};\n applyRamp(gain, 0, target, duration, curve);\n}\n\n/**\n * Fade a `GainNode` out to 0.\n */\nexport function fadeOut(gain: GainNode, options?: FadeOptions): void {\n const { duration = 1, curve = \"linear\" } = options ?? {};\n applyRamp(gain, gain.gain.value, 0, duration, curve);\n}\n\n/**\n * Crossfade between two `GainNode`s.\n */\nexport function crossfade(gainA: GainNode, gainB: GainNode, options?: CrossfadeOptions): void {\n const { duration = 1, curve = \"linear\" } = options ?? {};\n applyRamp(gainA, gainA.gain.value, 0, duration, curve);\n applyRamp(gainB, 0, gainA.gain.value || 1, duration, curve);\n}\n\n/**\n * Automatically apply fade-in at start and/or fade-out near end of a Playback.\n * Returns a cleanup function.\n */\nexport function autoFade(\n playback: Playback,\n gain: GainNode,\n options?: AutoFadeOptions,\n): () => void {\n const {\n fadeIn: fadeInDuration = 0,\n fadeOut: fadeOutDuration = 0,\n curve = \"linear\",\n } = options ?? {};\n\n const duration = playback.getDuration();\n let fadeOutScheduled = false;\n\n // Apply fade-in immediately if playing from the start.\n if (fadeInDuration > 0) {\n applyRamp(gain, 0, 1, fadeInDuration, curve);\n }\n\n const unsub = playback.on(\"timeupdate\", ({ position }) => {\n if (fadeOutDuration > 0 && !fadeOutScheduled && position >= duration - fadeOutDuration) {\n fadeOutScheduled = true;\n applyRamp(gain, gain.gain.value, 0, fadeOutDuration, curve);\n }\n });\n\n return unsub;\n}\n"]}
|
|
@@ -8,7 +8,7 @@ function computeSnapshot(playback) {
|
|
|
8
8
|
const position = playback.getCurrentTime();
|
|
9
9
|
const duration = playback.getDuration();
|
|
10
10
|
const progress = playback.getProgress();
|
|
11
|
-
const getter = playback
|
|
11
|
+
const getter = playback._getStretcherSnapshot;
|
|
12
12
|
let stretcher;
|
|
13
13
|
if (typeof getter === "function") {
|
|
14
14
|
stretcher = getter();
|
|
@@ -74,6 +74,9 @@ function whenEnded(playback) {
|
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
function whenPosition(playback, position) {
|
|
77
|
+
if (playback.getCurrentTime() >= position) {
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
}
|
|
77
80
|
return new Promise((resolve) => {
|
|
78
81
|
const unsub = playback.on("timeupdate", ({ position: current }) => {
|
|
79
82
|
if (current >= position) {
|
|
@@ -89,5 +92,5 @@ exports.onFrame = onFrame;
|
|
|
89
92
|
exports.subscribeSnapshot = subscribeSnapshot;
|
|
90
93
|
exports.whenEnded = whenEnded;
|
|
91
94
|
exports.whenPosition = whenPosition;
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-OZN5X4N6.cjs.map
|
|
96
|
+
//# sourceMappingURL=chunk-OZN5X4N6.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters.ts"],"names":[],"mappings":"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","file":"chunk-OZN5X4N6.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// M10: Framework adapters\n// ---------------------------------------------------------------------------\n\nimport type { Playback, PlaybackSnapshot } from \"./types.js\";\n\nconst snapshotCache = new WeakMap<Playback, PlaybackSnapshot>();\nconst subscriberCount = new WeakMap<Playback, number>();\n\nfunction computeSnapshot(playback: Playback): PlaybackSnapshot {\n const state = playback.getState();\n const position = playback.getCurrentTime();\n const duration = playback.getDuration();\n const progress = playback.getProgress();\n\n const getter = (playback as unknown as Record<string, unknown>)._getStretcherSnapshot;\n let stretcher: PlaybackSnapshot[\"stretcher\"];\n if (typeof getter === \"function\") {\n stretcher = (getter as () => PlaybackSnapshot[\"stretcher\"])();\n }\n\n const snap: PlaybackSnapshot = { state, position, duration, progress };\n if (stretcher) {\n snap.stretcher = stretcher;\n }\n return snap;\n}\n\n/**\n * Get an immutable snapshot of the current playback state.\n * Designed for use with React's `useSyncExternalStore` or similar patterns.\n *\n * Always returns a referentially stable (cached) object. The cache is updated\n * by `subscribeSnapshot` (on playback events) and `onFrame` (every animation\n * frame), so `getSnapshot` itself never computes a fresh snapshot — it only\n * reads or initialises the cache. This guarantees the reference-equality\n * contract required by `useSyncExternalStore`.\n */\nexport function getSnapshot(playback: Playback): PlaybackSnapshot {\n const cached = snapshotCache.get(playback);\n if (cached) return cached;\n\n const snap = computeSnapshot(playback);\n snapshotCache.set(playback, snap);\n return snap;\n}\n\n/**\n * Subscribe to playback state changes, calling `callback` with a fresh\n * snapshot whenever the state updates.\n *\n * Returns an unsubscribe function. Works as the `subscribe` parameter for\n * React's `useSyncExternalStore`.\n *\n * ```ts\n * // React example:\n * import { useCallback } from \"react\";\n * const subscribe = useCallback(\n * (cb: () => void) => subscribeSnapshot(playback, cb),\n * [playback],\n * );\n * const snap = useCallback(\n * () => getSnapshot(playback),\n * [playback],\n * );\n * const snapshot = useSyncExternalStore(subscribe, snap, snap);\n * ```\n */\nexport function subscribeSnapshot(playback: Playback, callback: () => void): () => void {\n const count = (subscriberCount.get(playback) ?? 0) + 1;\n subscriberCount.set(playback, count);\n\n // Eagerly compute the initial snapshot so getSnapshot() has a\n // stable reference before the first event fires.\n snapshotCache.set(playback, computeSnapshot(playback));\n\n const notify = () => {\n // Pre-compute and cache the snapshot BEFORE notifying the\n // subscriber. This ensures getSnapshot() returns the same\n // reference during React's render and post-commit check.\n snapshotCache.set(playback, computeSnapshot(playback));\n callback();\n };\n\n const unsubs: Array<() => void> = [];\n unsubs.push(playback.on(\"statechange\", notify));\n unsubs.push(playback.on(\"timeupdate\", notify));\n unsubs.push(playback.on(\"seek\", notify));\n unsubs.push(playback.on(\"ended\", notify));\n\n return () => {\n for (const unsub of unsubs) unsub();\n const c = (subscriberCount.get(playback) ?? 1) - 1;\n if (c <= 0) {\n subscriberCount.delete(playback);\n } else {\n subscriberCount.set(playback, c);\n }\n };\n}\n\n/**\n * Call `callback` on every animation frame with the current playback snapshot.\n * Useful for smooth UI animations (waveform cursors, progress bars, etc.).\n *\n * Returns a `stop` function that cancels the loop.\n */\nexport function onFrame(\n playback: Playback,\n callback: (snapshot: PlaybackSnapshot) => void,\n): () => void {\n let rafId: number | null = null;\n\n function tick() {\n const snap = computeSnapshot(playback);\n snapshotCache.set(playback, snap);\n callback(snap);\n rafId = requestAnimationFrame(tick);\n }\n\n rafId = requestAnimationFrame(tick);\n\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n };\n}\n\n/**\n * Return a `Promise` that resolves when the playback reaches the `\"stopped\"`\n * state via the `ended` event (natural end, not manual stop).\n */\nexport function whenEnded(playback: Playback): Promise<void> {\n return new Promise<void>((resolve) => {\n const unsub = playback.on(\"ended\", () => {\n unsub();\n resolve();\n });\n });\n}\n\n/**\n * Return a `Promise` that resolves when the playback position reaches or\n * exceeds `position` seconds.\n */\nexport function whenPosition(playback: Playback, position: number): Promise<void> {\n if (playback.getCurrentTime() >= position) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n const unsub = playback.on(\"timeupdate\", ({ position: current }) => {\n if (current >= position) {\n unsub();\n resolve();\n }\n });\n });\n}\n"]}
|
|
@@ -69,5 +69,5 @@ function disconnectChain(...nodes) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export { chain, createAnalyser, createCompressor, createFilter, createGain, createPanner, disconnectChain, getFrequencyData, getFrequencyDataByte, rampGain };
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
73
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
//# sourceMappingURL=chunk-PL4J3NR7.js.map
|
|
73
|
+
//# sourceMappingURL=chunk-PL4J3NR7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nodes.ts"],"names":[],"mappings":"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","file":"chunk-PL4J3NR7.js","sourcesContent":["// ---------------------------------------------------------------------------\n// M5: Audio node factory & graph utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Create a `GainNode` with an optional initial value.\n */\nexport function createGain(ctx: AudioContext, initialValue?: number): GainNode {\n const gain = ctx.createGain();\n if (initialValue !== undefined) {\n gain.gain.value = initialValue;\n }\n return gain;\n}\n\n/**\n * Smoothly ramp a `GainNode` to a target value over `duration` seconds using\n * `linearRampToValueAtTime`. This avoids audible clicks when changing volume.\n */\nexport function rampGain(gain: GainNode, target: number, duration: number): void {\n const now = gain.context.currentTime;\n gain.gain.cancelScheduledValues(now);\n gain.gain.setValueAtTime(gain.gain.value, now);\n gain.gain.linearRampToValueAtTime(target, now + duration);\n}\n\n/**\n * Create an `AnalyserNode`.\n */\nexport function createAnalyser(\n ctx: AudioContext,\n options?: { fftSize?: number; smoothingTimeConstant?: number },\n): AnalyserNode {\n const analyser = ctx.createAnalyser();\n if (options?.fftSize !== undefined) analyser.fftSize = options.fftSize;\n if (options?.smoothingTimeConstant !== undefined) {\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n }\n return analyser;\n}\n\n/**\n * Get the current frequency data from an `AnalyserNode` as `Float32Array`.\n */\nexport function getFrequencyData(analyser: AnalyserNode): Float32Array {\n const data = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(data);\n return data;\n}\n\n/**\n * Get the current frequency data from an `AnalyserNode` as `Uint8Array`.\n */\nexport function getFrequencyDataByte(analyser: AnalyserNode): Uint8Array {\n const data = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(data);\n return data;\n}\n\n/**\n * Create a `BiquadFilterNode`.\n */\nexport function createFilter(\n ctx: AudioContext,\n options?: {\n type?: BiquadFilterType;\n frequency?: number;\n Q?: number;\n gain?: number;\n },\n): BiquadFilterNode {\n const filter = ctx.createBiquadFilter();\n if (options?.type !== undefined) filter.type = options.type;\n if (options?.frequency !== undefined) filter.frequency.value = options.frequency;\n if (options?.Q !== undefined) filter.Q.value = options.Q;\n if (options?.gain !== undefined) filter.gain.value = options.gain;\n return filter;\n}\n\n/**\n * Create a `StereoPannerNode`.\n */\nexport function createPanner(ctx: AudioContext, pan?: number): StereoPannerNode {\n const panner = ctx.createStereoPanner();\n if (pan !== undefined) {\n panner.pan.value = pan;\n }\n return panner;\n}\n\n/**\n * Create a `DynamicsCompressorNode`.\n */\nexport function createCompressor(\n ctx: AudioContext,\n options?: {\n threshold?: number;\n knee?: number;\n ratio?: number;\n attack?: number;\n release?: number;\n },\n): DynamicsCompressorNode {\n const comp = ctx.createDynamicsCompressor();\n if (options?.threshold !== undefined) comp.threshold.value = options.threshold;\n if (options?.knee !== undefined) comp.knee.value = options.knee;\n if (options?.ratio !== undefined) comp.ratio.value = options.ratio;\n if (options?.attack !== undefined) comp.attack.value = options.attack;\n if (options?.release !== undefined) comp.release.value = options.release;\n return comp;\n}\n\n/**\n * Connect a series of `AudioNode`s in order (serial chain).\n *\n * ```ts\n * chain(source, gain, analyser, ctx.destination);\n * ```\n */\nexport function chain(...nodes: AudioNode[]): void {\n for (let i = 0; i < nodes.length - 1; i++) {\n nodes[i]!.connect(nodes[i + 1]!);\n }\n}\n\n/**\n * Disconnect a series of `AudioNode`s that were previously chained.\n */\nexport function disconnectChain(...nodes: AudioNode[]): void {\n for (const node of nodes) {\n try {\n node.disconnect();\n } catch {\n // Already disconnected — safe to ignore.\n }\n }\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { createScheduler, createClock } from './chunk-
|
|
2
|
-
import { createSineBuffer, createNoiseBuffer, createClickBuffer } from './chunk-
|
|
3
|
-
import { getSnapshot, subscribeSnapshot, onFrame, whenEnded, whenPosition } from './chunk-
|
|
1
|
+
import { createScheduler, createClock } from './chunk-7JUVBZ6B.js';
|
|
2
|
+
import { createSineBuffer, createNoiseBuffer, createClickBuffer } from './chunk-YFK7ETCF.js';
|
|
3
|
+
import { getSnapshot, subscribeSnapshot, onFrame, whenEnded, whenPosition } from './chunk-JIHPQAEA.js';
|
|
4
4
|
import { createContext, resumeContext, ensureRunning, now } from './chunk-37CPPRLV.js';
|
|
5
|
-
import { loadBuffer, loadBufferFromBlob, loadBuffers, getBufferInfo } from './chunk-
|
|
6
|
-
import { play } from './chunk-
|
|
7
|
-
import { createGain, createAnalyser, createFilter, createPanner, createCompressor, rampGain, getFrequencyData, getFrequencyDataByte, chain, disconnectChain } from './chunk-
|
|
8
|
-
import { extractPeaks, extractPeakPairs, extractRMS } from './chunk-
|
|
9
|
-
import { fadeIn, fadeOut, crossfade, autoFade } from './chunk-
|
|
5
|
+
import { loadBuffer, loadBufferFromBlob, loadBuffers, getBufferInfo } from './chunk-2FGUFHZM.js';
|
|
6
|
+
import { play } from './chunk-HYRDCTBO.js';
|
|
7
|
+
import { createGain, createAnalyser, createFilter, createPanner, createCompressor, rampGain, getFrequencyData, getFrequencyDataByte, chain, disconnectChain } from './chunk-PL4J3NR7.js';
|
|
8
|
+
import { extractPeaks, extractPeakPairs, extractRMS } from './chunk-HTN52U23.js';
|
|
9
|
+
import { fadeIn, fadeOut, crossfade, autoFade } from './chunk-FESPIMZM.js';
|
|
10
10
|
|
|
11
11
|
// src/player.ts
|
|
12
12
|
var WaaPlayer = class {
|
|
@@ -142,5 +142,5 @@ var WaaPlayer = class {
|
|
|
142
142
|
};
|
|
143
143
|
|
|
144
144
|
export { WaaPlayer };
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
146
|
-
//# sourceMappingURL=chunk-
|
|
145
|
+
//# sourceMappingURL=chunk-QFJQU7TQ.js.map
|
|
146
|
+
//# sourceMappingURL=chunk-QFJQU7TQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/player.ts"],"names":[],"mappings":"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","file":"chunk-QFJQU7TQ.js","sourcesContent":["import { getSnapshot, onFrame, subscribeSnapshot, whenEnded, whenPosition } from \"./adapters.js\";\nimport { getBufferInfo, loadBuffer, loadBufferFromBlob, loadBuffers } from \"./buffer.js\";\nimport { createContext, ensureRunning, now, resumeContext } from \"./context.js\";\nimport { autoFade, crossfade, fadeIn, fadeOut } from \"./fade.js\";\nimport {\n chain,\n createAnalyser as createAnalyserNode,\n createCompressor as createCompressorNode,\n createFilter as createFilterNode,\n createGain as createGainNode,\n createPanner as createPannerNode,\n disconnectChain,\n getFrequencyData,\n getFrequencyDataByte,\n rampGain,\n} from \"./nodes.js\";\nimport { play } from \"./play.js\";\nimport type { Clock, Scheduler } from \"./scheduler.js\";\nimport { createClock, createScheduler } from \"./scheduler.js\";\nimport { createClickBuffer, createNoiseBuffer, createSineBuffer } from \"./synth.js\";\n\nimport type {\n AutoFadeOptions,\n BufferInfo,\n ClockOptions,\n CreateContextOptions,\n CrossfadeOptions,\n ExtractPeaksOptions,\n FadeOptions,\n LoadBufferOptions,\n PeakPair,\n Playback,\n PlaybackSnapshot,\n PlayOptions,\n SchedulerOptions,\n} from \"./types.js\";\nimport { extractPeakPairs, extractPeaks, extractRMS } from \"./waveform.js\";\n\nexport interface WaaPlayerOptions extends CreateContextOptions {}\n\nexport class WaaPlayer {\n readonly ctx: AudioContext;\n private readonly _ownsContext: boolean;\n\n constructor(ctxOrOptions?: AudioContext | WaaPlayerOptions) {\n if (ctxOrOptions && typeof (ctxOrOptions as AudioContext).createGain === \"function\") {\n this.ctx = ctxOrOptions as AudioContext;\n this._ownsContext = false;\n } else {\n this.ctx = createContext(ctxOrOptions as WaaPlayerOptions | undefined);\n this._ownsContext = true;\n }\n }\n\n // --- Context ---\n\n resume(): Promise<void> {\n return resumeContext(this.ctx);\n }\n\n ensureRunning(): Promise<void> {\n return ensureRunning(this.ctx);\n }\n\n now(): number {\n return now(this.ctx);\n }\n\n // --- Buffer ---\n\n load(url: string, options?: LoadBufferOptions): Promise<AudioBuffer> {\n return loadBuffer(this.ctx, url, options);\n }\n\n loadFromBlob(blob: Blob): Promise<AudioBuffer> {\n return loadBufferFromBlob(this.ctx, blob);\n }\n\n loadAll(map: Record<string, string>): Promise<Map<string, AudioBuffer>> {\n return loadBuffers(this.ctx, map);\n }\n\n getBufferInfo(buffer: AudioBuffer): BufferInfo {\n return getBufferInfo(buffer);\n }\n\n // --- Play ---\n\n play(buffer: AudioBuffer, options?: PlayOptions): Playback {\n return play(this.ctx, buffer, options);\n }\n\n // --- Nodes ---\n\n createGain(initialValue?: number): GainNode {\n return createGainNode(this.ctx, initialValue);\n }\n\n createAnalyser(options?: { fftSize?: number; smoothingTimeConstant?: number }): AnalyserNode {\n return createAnalyserNode(this.ctx, options);\n }\n\n createFilter(options?: {\n type?: BiquadFilterType;\n frequency?: number;\n Q?: number;\n gain?: number;\n }): BiquadFilterNode {\n return createFilterNode(this.ctx, options);\n }\n\n createPanner(pan?: number): StereoPannerNode {\n return createPannerNode(this.ctx, pan);\n }\n\n createCompressor(options?: {\n threshold?: number;\n knee?: number;\n ratio?: number;\n attack?: number;\n release?: number;\n }): DynamicsCompressorNode {\n return createCompressorNode(this.ctx, options);\n }\n\n rampGain(gain: GainNode, target: number, duration: number): void {\n rampGain(gain, target, duration);\n }\n\n getFrequencyData(analyser: AnalyserNode): Float32Array {\n return getFrequencyData(analyser);\n }\n\n getFrequencyDataByte(analyser: AnalyserNode): Uint8Array {\n return getFrequencyDataByte(analyser);\n }\n\n chain(...nodes: AudioNode[]): void {\n chain(...nodes);\n }\n\n disconnectChain(...nodes: AudioNode[]): void {\n disconnectChain(...nodes);\n }\n\n // --- Waveform ---\n\n extractPeaks(buffer: AudioBuffer, options?: ExtractPeaksOptions): number[] {\n return extractPeaks(buffer, options);\n }\n\n extractPeakPairs(buffer: AudioBuffer, options?: ExtractPeaksOptions): PeakPair[] {\n return extractPeakPairs(buffer, options);\n }\n\n extractRMS(buffer: AudioBuffer, options?: ExtractPeaksOptions & { channel?: number }): number[] {\n return extractRMS(buffer, options);\n }\n\n // --- Fade ---\n\n fadeIn(gain: GainNode, target: number, options?: FadeOptions): void {\n fadeIn(gain, target, options);\n }\n\n fadeOut(gain: GainNode, options?: FadeOptions): void {\n fadeOut(gain, options);\n }\n\n crossfade(gainA: GainNode, gainB: GainNode, options?: CrossfadeOptions): void {\n crossfade(gainA, gainB, options);\n }\n\n autoFade(playback: Playback, gain: GainNode, options?: AutoFadeOptions): () => void {\n return autoFade(playback, gain, options);\n }\n\n // --- Scheduler ---\n\n createScheduler(options?: SchedulerOptions): Scheduler {\n return createScheduler(this.ctx, options);\n }\n\n createClock(options?: ClockOptions): Clock {\n return createClock(this.ctx, options);\n }\n\n // --- Synth ---\n\n createSineBuffer(frequency: number, duration: number): AudioBuffer {\n return createSineBuffer(this.ctx, frequency, duration);\n }\n\n createNoiseBuffer(duration: number): AudioBuffer {\n return createNoiseBuffer(this.ctx, duration);\n }\n\n createClickBuffer(frequency: number, duration: number): AudioBuffer {\n return createClickBuffer(this.ctx, frequency, duration);\n }\n\n // --- Adapters ---\n\n getSnapshot(playback: Playback): PlaybackSnapshot {\n return getSnapshot(playback);\n }\n\n subscribeSnapshot(playback: Playback, callback: () => void): () => void {\n return subscribeSnapshot(playback, callback);\n }\n\n onFrame(playback: Playback, callback: (snapshot: PlaybackSnapshot) => void): () => void {\n return onFrame(playback, callback);\n }\n\n whenEnded(playback: Playback): Promise<void> {\n return whenEnded(playback);\n }\n\n whenPosition(playback: Playback, position: number): Promise<void> {\n return whenPosition(playback, position);\n }\n\n // --- Lifecycle ---\n\n dispose(): void {\n if (this._ownsContext) {\n this.ctx.close();\n }\n }\n}\n"]}
|
|
@@ -80,5 +80,5 @@ exports.disconnectChain = disconnectChain;
|
|
|
80
80
|
exports.getFrequencyData = getFrequencyData;
|
|
81
81
|
exports.getFrequencyDataByte = getFrequencyDataByte;
|
|
82
82
|
exports.rampGain = rampGain;
|
|
83
|
-
//# sourceMappingURL=chunk-
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-QGZGERGK.cjs.map
|
|
84
|
+
//# sourceMappingURL=chunk-QGZGERGK.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nodes.ts"],"names":[],"mappings":"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","file":"chunk-QGZGERGK.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// M5: Audio node factory & graph utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Create a `GainNode` with an optional initial value.\n */\nexport function createGain(ctx: AudioContext, initialValue?: number): GainNode {\n const gain = ctx.createGain();\n if (initialValue !== undefined) {\n gain.gain.value = initialValue;\n }\n return gain;\n}\n\n/**\n * Smoothly ramp a `GainNode` to a target value over `duration` seconds using\n * `linearRampToValueAtTime`. This avoids audible clicks when changing volume.\n */\nexport function rampGain(gain: GainNode, target: number, duration: number): void {\n const now = gain.context.currentTime;\n gain.gain.cancelScheduledValues(now);\n gain.gain.setValueAtTime(gain.gain.value, now);\n gain.gain.linearRampToValueAtTime(target, now + duration);\n}\n\n/**\n * Create an `AnalyserNode`.\n */\nexport function createAnalyser(\n ctx: AudioContext,\n options?: { fftSize?: number; smoothingTimeConstant?: number },\n): AnalyserNode {\n const analyser = ctx.createAnalyser();\n if (options?.fftSize !== undefined) analyser.fftSize = options.fftSize;\n if (options?.smoothingTimeConstant !== undefined) {\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n }\n return analyser;\n}\n\n/**\n * Get the current frequency data from an `AnalyserNode` as `Float32Array`.\n */\nexport function getFrequencyData(analyser: AnalyserNode): Float32Array {\n const data = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(data);\n return data;\n}\n\n/**\n * Get the current frequency data from an `AnalyserNode` as `Uint8Array`.\n */\nexport function getFrequencyDataByte(analyser: AnalyserNode): Uint8Array {\n const data = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(data);\n return data;\n}\n\n/**\n * Create a `BiquadFilterNode`.\n */\nexport function createFilter(\n ctx: AudioContext,\n options?: {\n type?: BiquadFilterType;\n frequency?: number;\n Q?: number;\n gain?: number;\n },\n): BiquadFilterNode {\n const filter = ctx.createBiquadFilter();\n if (options?.type !== undefined) filter.type = options.type;\n if (options?.frequency !== undefined) filter.frequency.value = options.frequency;\n if (options?.Q !== undefined) filter.Q.value = options.Q;\n if (options?.gain !== undefined) filter.gain.value = options.gain;\n return filter;\n}\n\n/**\n * Create a `StereoPannerNode`.\n */\nexport function createPanner(ctx: AudioContext, pan?: number): StereoPannerNode {\n const panner = ctx.createStereoPanner();\n if (pan !== undefined) {\n panner.pan.value = pan;\n }\n return panner;\n}\n\n/**\n * Create a `DynamicsCompressorNode`.\n */\nexport function createCompressor(\n ctx: AudioContext,\n options?: {\n threshold?: number;\n knee?: number;\n ratio?: number;\n attack?: number;\n release?: number;\n },\n): DynamicsCompressorNode {\n const comp = ctx.createDynamicsCompressor();\n if (options?.threshold !== undefined) comp.threshold.value = options.threshold;\n if (options?.knee !== undefined) comp.knee.value = options.knee;\n if (options?.ratio !== undefined) comp.ratio.value = options.ratio;\n if (options?.attack !== undefined) comp.attack.value = options.attack;\n if (options?.release !== undefined) comp.release.value = options.release;\n return comp;\n}\n\n/**\n * Connect a series of `AudioNode`s in order (serial chain).\n *\n * ```ts\n * chain(source, gain, analyser, ctx.destination);\n * ```\n */\nexport function chain(...nodes: AudioNode[]): void {\n for (let i = 0; i < nodes.length - 1; i++) {\n nodes[i]!.connect(nodes[i + 1]!);\n }\n}\n\n/**\n * Disconnect a series of `AudioNode`s that were previously chained.\n */\nexport function disconnectChain(...nodes: AudioNode[]): void {\n for (const node of nodes) {\n try {\n node.disconnect();\n } catch {\n // Already disconnected — safe to ignore.\n }\n }\n}\n"]}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/waveform.ts
|
|
4
|
+
function calcBlockSize(dataLength, resolution) {
|
|
5
|
+
return Math.max(1, Math.floor(dataLength / resolution));
|
|
6
|
+
}
|
|
4
7
|
function extractPeaks(buffer, options) {
|
|
5
8
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
6
9
|
const data = buffer.getChannelData(channel);
|
|
7
|
-
const blockSize =
|
|
10
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
8
11
|
const peaks = [];
|
|
9
12
|
for (let i = 0; i < resolution; i++) {
|
|
10
13
|
const start = i * blockSize;
|
|
@@ -21,7 +24,7 @@ function extractPeaks(buffer, options) {
|
|
|
21
24
|
function extractPeakPairs(buffer, options) {
|
|
22
25
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
23
26
|
const data = buffer.getChannelData(channel);
|
|
24
|
-
const blockSize =
|
|
27
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
25
28
|
const pairs = [];
|
|
26
29
|
for (let i = 0; i < resolution; i++) {
|
|
27
30
|
const start = i * blockSize;
|
|
@@ -40,6 +43,9 @@ function extractPeakPairs(buffer, options) {
|
|
|
40
43
|
function extractRMS(buffer, options) {
|
|
41
44
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
42
45
|
if (channel === -1) {
|
|
46
|
+
if (buffer.numberOfChannels === 0) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
43
49
|
const allChannels = [];
|
|
44
50
|
for (let ch = 0; ch < buffer.numberOfChannels; ch++) {
|
|
45
51
|
allChannels.push(extractRMS(buffer, { resolution, channel: ch }));
|
|
@@ -53,17 +59,18 @@ function extractRMS(buffer, options) {
|
|
|
53
59
|
});
|
|
54
60
|
}
|
|
55
61
|
const data = buffer.getChannelData(channel);
|
|
56
|
-
const blockSize =
|
|
62
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
57
63
|
const rms = [];
|
|
58
64
|
for (let i = 0; i < resolution; i++) {
|
|
59
65
|
const start = i * blockSize;
|
|
60
66
|
const end = Math.min(start + blockSize, data.length);
|
|
61
67
|
let sumSq = 0;
|
|
68
|
+
const count = end - start;
|
|
62
69
|
for (let j = start; j < end; j++) {
|
|
63
70
|
const s = data[j];
|
|
64
71
|
sumSq += s * s;
|
|
65
72
|
}
|
|
66
|
-
rms.push(Math.sqrt(sumSq /
|
|
73
|
+
rms.push(count > 0 ? Math.sqrt(sumSq / count) : 0);
|
|
67
74
|
}
|
|
68
75
|
return rms;
|
|
69
76
|
}
|
|
@@ -71,5 +78,5 @@ function extractRMS(buffer, options) {
|
|
|
71
78
|
exports.extractPeakPairs = extractPeakPairs;
|
|
72
79
|
exports.extractPeaks = extractPeaks;
|
|
73
80
|
exports.extractRMS = extractRMS;
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
75
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-VOSIA3GF.cjs.map
|
|
82
|
+
//# sourceMappingURL=chunk-VOSIA3GF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/waveform.ts"],"names":[],"mappings":"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","file":"chunk-VOSIA3GF.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// M6: Waveform data extraction\n// ---------------------------------------------------------------------------\n\nimport type { ExtractPeaksOptions, PeakPair } from \"./types.js\";\n\nfunction calcBlockSize(dataLength: number, resolution: number): number {\n return Math.max(1, Math.floor(dataLength / resolution));\n}\n\n/**\n * Extract normalised peak amplitude values from an `AudioBuffer`.\n * Returns an array of numbers in the range `[0, 1]`.\n */\nexport function extractPeaks(buffer: AudioBuffer, options?: ExtractPeaksOptions): number[] {\n const { resolution = 200, channel = 0 } = options ?? {};\n const data = buffer.getChannelData(channel);\n const blockSize = calcBlockSize(data.length, resolution);\n const peaks: number[] = [];\n\n for (let i = 0; i < resolution; i++) {\n const start = i * blockSize;\n const end = Math.min(start + blockSize, data.length);\n let max = 0;\n for (let j = start; j < end; j++) {\n const abs = Math.abs(data[j]!);\n if (abs > max) max = abs;\n }\n peaks.push(max);\n }\n\n return peaks;\n}\n\n/**\n * Extract min/max peak pairs for detailed waveform rendering.\n */\nexport function extractPeakPairs(buffer: AudioBuffer, options?: ExtractPeaksOptions): PeakPair[] {\n const { resolution = 200, channel = 0 } = options ?? {};\n const data = buffer.getChannelData(channel);\n const blockSize = calcBlockSize(data.length, resolution);\n const pairs: PeakPair[] = [];\n\n for (let i = 0; i < resolution; i++) {\n const start = i * blockSize;\n const end = Math.min(start + blockSize, data.length);\n let min = 0;\n let max = 0;\n for (let j = start; j < end; j++) {\n const sample = data[j]!;\n if (sample < min) min = sample;\n if (sample > max) max = sample;\n }\n pairs.push({ min, max });\n }\n\n return pairs;\n}\n\n/**\n * Extract RMS (root mean square) values representing perceived loudness.\n * Returns values in the range `[0, 1]`.\n *\n * When `channel` is set to `-1`, all channels are averaged.\n */\nexport function extractRMS(\n buffer: AudioBuffer,\n options?: ExtractPeaksOptions & { channel?: number },\n): number[] {\n const { resolution = 200, channel = 0 } = options ?? {};\n\n if (channel === -1) {\n if (buffer.numberOfChannels === 0) {\n return [];\n }\n // Average across all channels.\n const allChannels: number[][] = [];\n for (let ch = 0; ch < buffer.numberOfChannels; ch++) {\n allChannels.push(extractRMS(buffer, { resolution, channel: ch }));\n }\n return allChannels[0]!.map((_, i) => {\n let sum = 0;\n for (const ch of allChannels) {\n sum += ch[i]!;\n }\n return sum / allChannels.length;\n });\n }\n\n const data = buffer.getChannelData(channel);\n const blockSize = calcBlockSize(data.length, resolution);\n const rms: number[] = [];\n\n for (let i = 0; i < resolution; i++) {\n const start = i * blockSize;\n const end = Math.min(start + blockSize, data.length);\n let sumSq = 0;\n const count = end - start;\n for (let j = start; j < end; j++) {\n const s = data[j]!;\n sumSq += s * s;\n }\n rms.push(count > 0 ? Math.sqrt(sumSq / count) : 0);\n }\n\n return rms;\n}\n"]}
|