waa-play 0.1.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.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/adapters.cjs +28 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +42 -0
- package/dist/adapters.d.ts +42 -0
- package/dist/adapters.js +3 -0
- package/dist/adapters.js.map +1 -0
- package/dist/buffer.cjs +24 -0
- package/dist/buffer.cjs.map +1 -0
- package/dist/buffer.d.cts +34 -0
- package/dist/buffer.d.ts +34 -0
- package/dist/buffer.js +3 -0
- package/dist/buffer.js.map +1 -0
- package/dist/chunk-2DL7CAEP.js +69 -0
- package/dist/chunk-2DL7CAEP.js.map +1 -0
- package/dist/chunk-37CPPRLV.js +24 -0
- package/dist/chunk-37CPPRLV.js.map +1 -0
- package/dist/chunk-4LNVRSTM.cjs +72 -0
- package/dist/chunk-4LNVRSTM.cjs.map +1 -0
- package/dist/chunk-5J7S6QV3.cjs +44 -0
- package/dist/chunk-5J7S6QV3.cjs.map +1 -0
- package/dist/chunk-6UTN73HG.cjs +29 -0
- package/dist/chunk-6UTN73HG.cjs.map +1 -0
- package/dist/chunk-AGP2IRC6.js +63 -0
- package/dist/chunk-AGP2IRC6.js.map +1 -0
- package/dist/chunk-C2ASIYN5.js +67 -0
- package/dist/chunk-C2ASIYN5.js.map +1 -0
- package/dist/chunk-CJJC6ASU.js +73 -0
- package/dist/chunk-CJJC6ASU.js.map +1 -0
- package/dist/chunk-CPAT75WD.cjs +60 -0
- package/dist/chunk-CPAT75WD.cjs.map +1 -0
- package/dist/chunk-CRODJ4KS.js +71 -0
- package/dist/chunk-CRODJ4KS.js.map +1 -0
- package/dist/chunk-D5CD5KQZ.cjs +72 -0
- package/dist/chunk-D5CD5KQZ.cjs.map +1 -0
- package/dist/chunk-GYH2JSCY.js +42 -0
- package/dist/chunk-GYH2JSCY.js.map +1 -0
- package/dist/chunk-HTGOHC73.cjs +69 -0
- package/dist/chunk-HTGOHC73.cjs.map +1 -0
- package/dist/chunk-LETS7FKB.js +33 -0
- package/dist/chunk-LETS7FKB.js.map +1 -0
- package/dist/chunk-M5PDY5EZ.cjs +84 -0
- package/dist/chunk-M5PDY5EZ.cjs.map +1 -0
- package/dist/chunk-PZE6HTZR.cjs +358 -0
- package/dist/chunk-PZE6HTZR.cjs.map +1 -0
- package/dist/chunk-QFFQQMU4.cjs +75 -0
- package/dist/chunk-QFFQQMU4.cjs.map +1 -0
- package/dist/chunk-QWNV2BZ5.cjs +37 -0
- package/dist/chunk-QWNV2BZ5.cjs.map +1 -0
- package/dist/chunk-RWJ4EWJT.js +356 -0
- package/dist/chunk-RWJ4EWJT.js.map +1 -0
- package/dist/chunk-T74FBKTY.js +55 -0
- package/dist/chunk-T74FBKTY.js.map +1 -0
- package/dist/chunk-TULV7V5M.cjs +1710 -0
- package/dist/chunk-TULV7V5M.cjs.map +1 -0
- package/dist/chunk-V2QX5K42.js +1708 -0
- package/dist/chunk-V2QX5K42.js.map +1 -0
- package/dist/context.cjs +24 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +27 -0
- package/dist/context.d.ts +27 -0
- package/dist/context.js +3 -0
- package/dist/context.js.map +1 -0
- package/dist/emitter.cjs +12 -0
- package/dist/emitter.cjs.map +1 -0
- package/dist/emitter.d.cts +24 -0
- package/dist/emitter.d.ts +24 -0
- package/dist/emitter.js +3 -0
- package/dist/emitter.js.map +1 -0
- package/dist/engine-5JK2FCNL.cjs +13 -0
- package/dist/engine-5JK2FCNL.cjs.map +1 -0
- package/dist/engine-M2U4LE3F.js +4 -0
- package/dist/engine-M2U4LE3F.js.map +1 -0
- package/dist/fade.cjs +24 -0
- package/dist/fade.cjs.map +1 -0
- package/dist/fade.d.cts +21 -0
- package/dist/fade.d.ts +21 -0
- package/dist/fade.js +3 -0
- package/dist/fade.js.map +1 -0
- package/dist/index.cjs +165 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes.cjs +48 -0
- package/dist/nodes.cjs.map +1 -0
- package/dist/nodes.d.cts +61 -0
- package/dist/nodes.d.ts +61 -0
- package/dist/nodes.js +3 -0
- package/dist/nodes.js.map +1 -0
- package/dist/play.cjs +13 -0
- package/dist/play.cjs.map +1 -0
- package/dist/play.d.cts +19 -0
- package/dist/play.d.ts +19 -0
- package/dist/play.js +4 -0
- package/dist/play.js.map +1 -0
- package/dist/scheduler.cjs +16 -0
- package/dist/scheduler.cjs.map +1 -0
- package/dist/scheduler.d.cts +39 -0
- package/dist/scheduler.d.ts +39 -0
- package/dist/scheduler.js +3 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/stretcher.cjs +13 -0
- package/dist/stretcher.cjs.map +1 -0
- package/dist/stretcher.d.cts +171 -0
- package/dist/stretcher.d.ts +171 -0
- package/dist/stretcher.js +4 -0
- package/dist/stretcher.js.map +1 -0
- package/dist/synth.cjs +20 -0
- package/dist/synth.cjs.map +1 -0
- package/dist/synth.d.cts +15 -0
- package/dist/synth.d.ts +15 -0
- package/dist/synth.js +3 -0
- package/dist/synth.js.map +1 -0
- package/dist/types-DUrbEbPl.d.cts +177 -0
- package/dist/types-DUrbEbPl.d.ts +177 -0
- package/dist/waveform.cjs +20 -0
- package/dist/waveform.cjs.map +1 -0
- package/dist/waveform.d.cts +22 -0
- package/dist/waveform.d.ts +22 -0
- package/dist/waveform.js +3 -0
- package/dist/waveform.js.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/** State of a single chunk in the conversion pipeline. */
|
|
2
|
+
type ChunkState = "pending" | "queued" | "converting" | "ready" | "failed" | "skipped" | "evicted";
|
|
3
|
+
/** Playback state of the stretcher engine. */
|
|
4
|
+
type StretcherPlaybackState = "waiting" | "playing" | "buffering" | "paused" | "ended";
|
|
5
|
+
/** Buffer health classification. */
|
|
6
|
+
type BufferHealth = "healthy" | "low" | "critical" | "empty";
|
|
7
|
+
/** Metadata and state for a single chunk. */
|
|
8
|
+
interface ChunkInfo {
|
|
9
|
+
index: number;
|
|
10
|
+
state: ChunkState;
|
|
11
|
+
inputStartSample: number;
|
|
12
|
+
inputEndSample: number;
|
|
13
|
+
overlapBefore: number;
|
|
14
|
+
overlapAfter: number;
|
|
15
|
+
outputBuffer: Float32Array[] | null;
|
|
16
|
+
outputLength: number;
|
|
17
|
+
priority: number;
|
|
18
|
+
retryCount: number;
|
|
19
|
+
}
|
|
20
|
+
/** Stretcher engine configuration. */
|
|
21
|
+
interface StretcherEngineOptions {
|
|
22
|
+
tempo: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
loop?: boolean;
|
|
25
|
+
through?: AudioNode[];
|
|
26
|
+
destination?: AudioNode;
|
|
27
|
+
timeupdateInterval?: number;
|
|
28
|
+
workerPoolSize?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Aggregate status of the stretcher engine. */
|
|
31
|
+
interface StretcherStatus {
|
|
32
|
+
phase: StretcherPlaybackState;
|
|
33
|
+
conversion: {
|
|
34
|
+
total: number;
|
|
35
|
+
ready: number;
|
|
36
|
+
converting: number;
|
|
37
|
+
progress: number;
|
|
38
|
+
};
|
|
39
|
+
buffer: {
|
|
40
|
+
health: BufferHealth;
|
|
41
|
+
aheadSeconds: number;
|
|
42
|
+
};
|
|
43
|
+
playback: {
|
|
44
|
+
position: number;
|
|
45
|
+
duration: number;
|
|
46
|
+
tempo: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Snapshot extension for PlaybackSnapshot. */
|
|
50
|
+
interface StretcherSnapshotExtension {
|
|
51
|
+
tempo: number;
|
|
52
|
+
converting: boolean;
|
|
53
|
+
conversionProgress: number;
|
|
54
|
+
bufferHealth: BufferHealth;
|
|
55
|
+
aheadSeconds: number;
|
|
56
|
+
buffering: boolean;
|
|
57
|
+
chunkStates: ChunkState[];
|
|
58
|
+
currentChunkIndex: number;
|
|
59
|
+
activeWindowStart: number;
|
|
60
|
+
activeWindowEnd: number;
|
|
61
|
+
totalChunks: number;
|
|
62
|
+
windowConversionProgress: number;
|
|
63
|
+
}
|
|
64
|
+
/** Events emitted by the stretcher engine. */
|
|
65
|
+
interface StretcherEvents {
|
|
66
|
+
progress: {
|
|
67
|
+
total: number;
|
|
68
|
+
ready: number;
|
|
69
|
+
progress: number;
|
|
70
|
+
};
|
|
71
|
+
bufferhealth: {
|
|
72
|
+
health: BufferHealth;
|
|
73
|
+
aheadSeconds: number;
|
|
74
|
+
};
|
|
75
|
+
buffering: {
|
|
76
|
+
reason: "initial" | "seek" | "tempo-change" | "underrun";
|
|
77
|
+
};
|
|
78
|
+
buffered: {
|
|
79
|
+
stallDuration: number;
|
|
80
|
+
};
|
|
81
|
+
chunkready: {
|
|
82
|
+
index: number;
|
|
83
|
+
};
|
|
84
|
+
complete: void;
|
|
85
|
+
ended: void;
|
|
86
|
+
error: {
|
|
87
|
+
message: string;
|
|
88
|
+
chunkIndex?: number;
|
|
89
|
+
fatal: boolean;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** The stretcher engine interface. */
|
|
93
|
+
interface StretcherEngine {
|
|
94
|
+
start(): void;
|
|
95
|
+
pause(): void;
|
|
96
|
+
resume(): void;
|
|
97
|
+
seek(position: number): void;
|
|
98
|
+
stop(): void;
|
|
99
|
+
setTempo(tempo: number): void;
|
|
100
|
+
getCurrentPosition(): number;
|
|
101
|
+
getStatus(): StretcherStatus;
|
|
102
|
+
getSnapshot(): StretcherSnapshotExtension;
|
|
103
|
+
on<K extends keyof StretcherEvents>(event: K, handler: (data: StretcherEvents[K]) => void): () => void;
|
|
104
|
+
off<K extends keyof StretcherEvents>(event: K, handler: (data: StretcherEvents[K]) => void): void;
|
|
105
|
+
dispose(): void;
|
|
106
|
+
}
|
|
107
|
+
interface WorkerManager {
|
|
108
|
+
postConvert(chunkIndex: number, inputData: Float32Array[], tempo: number, sampleRate: number): void;
|
|
109
|
+
cancelCurrent(): void;
|
|
110
|
+
cancelChunk(chunkIndex: number): void;
|
|
111
|
+
isBusy(): boolean;
|
|
112
|
+
hasCapacity(): boolean;
|
|
113
|
+
getCurrentChunkIndex(): number | null;
|
|
114
|
+
getLastPostTime(): number | null;
|
|
115
|
+
getPostTimeForChunk(chunkIndex: number): number | null;
|
|
116
|
+
terminate(): void;
|
|
117
|
+
}
|
|
118
|
+
interface PriorityQueue<T> {
|
|
119
|
+
enqueue(item: T): void;
|
|
120
|
+
dequeue(): T | undefined;
|
|
121
|
+
peek(): T | undefined;
|
|
122
|
+
remove(predicate: (item: T) => boolean): boolean;
|
|
123
|
+
rebuild(): void;
|
|
124
|
+
clear(): void;
|
|
125
|
+
size(): number;
|
|
126
|
+
toArray(): T[];
|
|
127
|
+
}
|
|
128
|
+
interface ConversionScheduler {
|
|
129
|
+
start(currentChunkIndex: number): void;
|
|
130
|
+
updatePriorities(currentChunkIndex: number): void;
|
|
131
|
+
handleSeek(newChunkIndex: number): void;
|
|
132
|
+
handleTempoChange(newTempo: number): void;
|
|
133
|
+
restorePreviousTempo(): boolean;
|
|
134
|
+
dispatchNext(): void;
|
|
135
|
+
getChunks(): ChunkInfo[];
|
|
136
|
+
dispose(): void;
|
|
137
|
+
_handleResult(chunkIndex: number, outputData: Float32Array[], outputLength: number): void;
|
|
138
|
+
_handleError(chunkIndex: number, error: string): void;
|
|
139
|
+
}
|
|
140
|
+
interface ChunkPlayer {
|
|
141
|
+
playChunk(buffer: AudioBuffer, startTime: number, offsetInChunk?: number): void;
|
|
142
|
+
scheduleNext(buffer: AudioBuffer, startTime: number): void;
|
|
143
|
+
hasNextScheduled(): boolean;
|
|
144
|
+
handleSeek(buffer: AudioBuffer, offsetInChunk: number): void;
|
|
145
|
+
pause(): void;
|
|
146
|
+
resume(): void;
|
|
147
|
+
stop(): void;
|
|
148
|
+
getCurrentPosition(): number;
|
|
149
|
+
setOnChunkEnded(callback: () => void): void;
|
|
150
|
+
setOnNeedNext(callback: () => void): void;
|
|
151
|
+
setOnTransition(callback: () => void): void;
|
|
152
|
+
dispose(): void;
|
|
153
|
+
}
|
|
154
|
+
interface BufferMonitor {
|
|
155
|
+
getHealth(currentChunkIndex: number, chunks: ChunkInfo[]): BufferHealth;
|
|
156
|
+
getAheadSeconds(currentChunkIndex: number, chunks: ChunkInfo[]): number;
|
|
157
|
+
shouldEnterBuffering(currentChunkIndex: number, chunks: ChunkInfo[]): boolean;
|
|
158
|
+
shouldExitBuffering(currentChunkIndex: number, chunks: ChunkInfo[]): boolean;
|
|
159
|
+
}
|
|
160
|
+
interface ConversionEstimator {
|
|
161
|
+
recordConversion(durationMs: number): void;
|
|
162
|
+
estimateRemaining(remainingChunks: number): number;
|
|
163
|
+
getAverageMs(): number;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Create the stretcher engine that orchestrates all components.
|
|
168
|
+
*/
|
|
169
|
+
declare function createStretcherEngine(ctx: AudioContext, buffer: AudioBuffer, options: StretcherEngineOptions): StretcherEngine;
|
|
170
|
+
|
|
171
|
+
export { type BufferHealth, type BufferMonitor, type ChunkInfo, type ChunkPlayer, type ChunkState, type ConversionEstimator, type ConversionScheduler, type PriorityQueue, type StretcherEngine, type StretcherEngineOptions, type StretcherEvents, type StretcherPlaybackState, type StretcherSnapshotExtension, type StretcherStatus, type WorkerManager, createStretcherEngine };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/** State of a single chunk in the conversion pipeline. */
|
|
2
|
+
type ChunkState = "pending" | "queued" | "converting" | "ready" | "failed" | "skipped" | "evicted";
|
|
3
|
+
/** Playback state of the stretcher engine. */
|
|
4
|
+
type StretcherPlaybackState = "waiting" | "playing" | "buffering" | "paused" | "ended";
|
|
5
|
+
/** Buffer health classification. */
|
|
6
|
+
type BufferHealth = "healthy" | "low" | "critical" | "empty";
|
|
7
|
+
/** Metadata and state for a single chunk. */
|
|
8
|
+
interface ChunkInfo {
|
|
9
|
+
index: number;
|
|
10
|
+
state: ChunkState;
|
|
11
|
+
inputStartSample: number;
|
|
12
|
+
inputEndSample: number;
|
|
13
|
+
overlapBefore: number;
|
|
14
|
+
overlapAfter: number;
|
|
15
|
+
outputBuffer: Float32Array[] | null;
|
|
16
|
+
outputLength: number;
|
|
17
|
+
priority: number;
|
|
18
|
+
retryCount: number;
|
|
19
|
+
}
|
|
20
|
+
/** Stretcher engine configuration. */
|
|
21
|
+
interface StretcherEngineOptions {
|
|
22
|
+
tempo: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
loop?: boolean;
|
|
25
|
+
through?: AudioNode[];
|
|
26
|
+
destination?: AudioNode;
|
|
27
|
+
timeupdateInterval?: number;
|
|
28
|
+
workerPoolSize?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Aggregate status of the stretcher engine. */
|
|
31
|
+
interface StretcherStatus {
|
|
32
|
+
phase: StretcherPlaybackState;
|
|
33
|
+
conversion: {
|
|
34
|
+
total: number;
|
|
35
|
+
ready: number;
|
|
36
|
+
converting: number;
|
|
37
|
+
progress: number;
|
|
38
|
+
};
|
|
39
|
+
buffer: {
|
|
40
|
+
health: BufferHealth;
|
|
41
|
+
aheadSeconds: number;
|
|
42
|
+
};
|
|
43
|
+
playback: {
|
|
44
|
+
position: number;
|
|
45
|
+
duration: number;
|
|
46
|
+
tempo: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Snapshot extension for PlaybackSnapshot. */
|
|
50
|
+
interface StretcherSnapshotExtension {
|
|
51
|
+
tempo: number;
|
|
52
|
+
converting: boolean;
|
|
53
|
+
conversionProgress: number;
|
|
54
|
+
bufferHealth: BufferHealth;
|
|
55
|
+
aheadSeconds: number;
|
|
56
|
+
buffering: boolean;
|
|
57
|
+
chunkStates: ChunkState[];
|
|
58
|
+
currentChunkIndex: number;
|
|
59
|
+
activeWindowStart: number;
|
|
60
|
+
activeWindowEnd: number;
|
|
61
|
+
totalChunks: number;
|
|
62
|
+
windowConversionProgress: number;
|
|
63
|
+
}
|
|
64
|
+
/** Events emitted by the stretcher engine. */
|
|
65
|
+
interface StretcherEvents {
|
|
66
|
+
progress: {
|
|
67
|
+
total: number;
|
|
68
|
+
ready: number;
|
|
69
|
+
progress: number;
|
|
70
|
+
};
|
|
71
|
+
bufferhealth: {
|
|
72
|
+
health: BufferHealth;
|
|
73
|
+
aheadSeconds: number;
|
|
74
|
+
};
|
|
75
|
+
buffering: {
|
|
76
|
+
reason: "initial" | "seek" | "tempo-change" | "underrun";
|
|
77
|
+
};
|
|
78
|
+
buffered: {
|
|
79
|
+
stallDuration: number;
|
|
80
|
+
};
|
|
81
|
+
chunkready: {
|
|
82
|
+
index: number;
|
|
83
|
+
};
|
|
84
|
+
complete: void;
|
|
85
|
+
ended: void;
|
|
86
|
+
error: {
|
|
87
|
+
message: string;
|
|
88
|
+
chunkIndex?: number;
|
|
89
|
+
fatal: boolean;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** The stretcher engine interface. */
|
|
93
|
+
interface StretcherEngine {
|
|
94
|
+
start(): void;
|
|
95
|
+
pause(): void;
|
|
96
|
+
resume(): void;
|
|
97
|
+
seek(position: number): void;
|
|
98
|
+
stop(): void;
|
|
99
|
+
setTempo(tempo: number): void;
|
|
100
|
+
getCurrentPosition(): number;
|
|
101
|
+
getStatus(): StretcherStatus;
|
|
102
|
+
getSnapshot(): StretcherSnapshotExtension;
|
|
103
|
+
on<K extends keyof StretcherEvents>(event: K, handler: (data: StretcherEvents[K]) => void): () => void;
|
|
104
|
+
off<K extends keyof StretcherEvents>(event: K, handler: (data: StretcherEvents[K]) => void): void;
|
|
105
|
+
dispose(): void;
|
|
106
|
+
}
|
|
107
|
+
interface WorkerManager {
|
|
108
|
+
postConvert(chunkIndex: number, inputData: Float32Array[], tempo: number, sampleRate: number): void;
|
|
109
|
+
cancelCurrent(): void;
|
|
110
|
+
cancelChunk(chunkIndex: number): void;
|
|
111
|
+
isBusy(): boolean;
|
|
112
|
+
hasCapacity(): boolean;
|
|
113
|
+
getCurrentChunkIndex(): number | null;
|
|
114
|
+
getLastPostTime(): number | null;
|
|
115
|
+
getPostTimeForChunk(chunkIndex: number): number | null;
|
|
116
|
+
terminate(): void;
|
|
117
|
+
}
|
|
118
|
+
interface PriorityQueue<T> {
|
|
119
|
+
enqueue(item: T): void;
|
|
120
|
+
dequeue(): T | undefined;
|
|
121
|
+
peek(): T | undefined;
|
|
122
|
+
remove(predicate: (item: T) => boolean): boolean;
|
|
123
|
+
rebuild(): void;
|
|
124
|
+
clear(): void;
|
|
125
|
+
size(): number;
|
|
126
|
+
toArray(): T[];
|
|
127
|
+
}
|
|
128
|
+
interface ConversionScheduler {
|
|
129
|
+
start(currentChunkIndex: number): void;
|
|
130
|
+
updatePriorities(currentChunkIndex: number): void;
|
|
131
|
+
handleSeek(newChunkIndex: number): void;
|
|
132
|
+
handleTempoChange(newTempo: number): void;
|
|
133
|
+
restorePreviousTempo(): boolean;
|
|
134
|
+
dispatchNext(): void;
|
|
135
|
+
getChunks(): ChunkInfo[];
|
|
136
|
+
dispose(): void;
|
|
137
|
+
_handleResult(chunkIndex: number, outputData: Float32Array[], outputLength: number): void;
|
|
138
|
+
_handleError(chunkIndex: number, error: string): void;
|
|
139
|
+
}
|
|
140
|
+
interface ChunkPlayer {
|
|
141
|
+
playChunk(buffer: AudioBuffer, startTime: number, offsetInChunk?: number): void;
|
|
142
|
+
scheduleNext(buffer: AudioBuffer, startTime: number): void;
|
|
143
|
+
hasNextScheduled(): boolean;
|
|
144
|
+
handleSeek(buffer: AudioBuffer, offsetInChunk: number): void;
|
|
145
|
+
pause(): void;
|
|
146
|
+
resume(): void;
|
|
147
|
+
stop(): void;
|
|
148
|
+
getCurrentPosition(): number;
|
|
149
|
+
setOnChunkEnded(callback: () => void): void;
|
|
150
|
+
setOnNeedNext(callback: () => void): void;
|
|
151
|
+
setOnTransition(callback: () => void): void;
|
|
152
|
+
dispose(): void;
|
|
153
|
+
}
|
|
154
|
+
interface BufferMonitor {
|
|
155
|
+
getHealth(currentChunkIndex: number, chunks: ChunkInfo[]): BufferHealth;
|
|
156
|
+
getAheadSeconds(currentChunkIndex: number, chunks: ChunkInfo[]): number;
|
|
157
|
+
shouldEnterBuffering(currentChunkIndex: number, chunks: ChunkInfo[]): boolean;
|
|
158
|
+
shouldExitBuffering(currentChunkIndex: number, chunks: ChunkInfo[]): boolean;
|
|
159
|
+
}
|
|
160
|
+
interface ConversionEstimator {
|
|
161
|
+
recordConversion(durationMs: number): void;
|
|
162
|
+
estimateRemaining(remainingChunks: number): number;
|
|
163
|
+
getAverageMs(): number;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Create the stretcher engine that orchestrates all components.
|
|
168
|
+
*/
|
|
169
|
+
declare function createStretcherEngine(ctx: AudioContext, buffer: AudioBuffer, options: StretcherEngineOptions): StretcherEngine;
|
|
170
|
+
|
|
171
|
+
export { type BufferHealth, type BufferMonitor, type ChunkInfo, type ChunkPlayer, type ChunkState, type ConversionEstimator, type ConversionScheduler, type PriorityQueue, type StretcherEngine, type StretcherEngineOptions, type StretcherEvents, type StretcherPlaybackState, type StretcherSnapshotExtension, type StretcherStatus, type WorkerManager, createStretcherEngine };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"stretcher.js"}
|
package/dist/synth.cjs
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkQWNV2BZ5_cjs = require('./chunk-QWNV2BZ5.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "createClickBuffer", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkQWNV2BZ5_cjs.createClickBuffer; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "createNoiseBuffer", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunkQWNV2BZ5_cjs.createNoiseBuffer; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "createSineBuffer", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunkQWNV2BZ5_cjs.createSineBuffer; }
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=synth.cjs.map
|
|
20
|
+
//# sourceMappingURL=synth.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"synth.cjs"}
|
package/dist/synth.d.cts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an `AudioBuffer` containing a sine wave.
|
|
3
|
+
* Useful for test tones and debugging.
|
|
4
|
+
*/
|
|
5
|
+
declare function createSineBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;
|
|
6
|
+
/**
|
|
7
|
+
* Create an `AudioBuffer` containing white noise.
|
|
8
|
+
*/
|
|
9
|
+
declare function createNoiseBuffer(ctx: AudioContext, duration: number): AudioBuffer;
|
|
10
|
+
/**
|
|
11
|
+
* Create an `AudioBuffer` containing a short click/impulse.
|
|
12
|
+
*/
|
|
13
|
+
declare function createClickBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;
|
|
14
|
+
|
|
15
|
+
export { createClickBuffer, createNoiseBuffer, createSineBuffer };
|
package/dist/synth.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an `AudioBuffer` containing a sine wave.
|
|
3
|
+
* Useful for test tones and debugging.
|
|
4
|
+
*/
|
|
5
|
+
declare function createSineBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;
|
|
6
|
+
/**
|
|
7
|
+
* Create an `AudioBuffer` containing white noise.
|
|
8
|
+
*/
|
|
9
|
+
declare function createNoiseBuffer(ctx: AudioContext, duration: number): AudioBuffer;
|
|
10
|
+
/**
|
|
11
|
+
* Create an `AudioBuffer` containing a short click/impulse.
|
|
12
|
+
*/
|
|
13
|
+
declare function createClickBuffer(ctx: AudioContext, frequency: number, duration: number): AudioBuffer;
|
|
14
|
+
|
|
15
|
+
export { createClickBuffer, createNoiseBuffer, createSineBuffer };
|
package/dist/synth.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"synth.js"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** Possible states of a Playback instance. */
|
|
2
|
+
type PlaybackState = "playing" | "paused" | "stopped";
|
|
3
|
+
/** Options accepted by `play()`. */
|
|
4
|
+
interface PlayOptions {
|
|
5
|
+
/** Start offset in seconds within the buffer. @default 0 */
|
|
6
|
+
offset?: number;
|
|
7
|
+
/** Whether the source should loop. @default false */
|
|
8
|
+
loop?: boolean;
|
|
9
|
+
/** Loop region start in seconds. */
|
|
10
|
+
loopStart?: number;
|
|
11
|
+
/** Loop region end in seconds. */
|
|
12
|
+
loopEnd?: number;
|
|
13
|
+
/** Playback speed multiplier. @default 1 */
|
|
14
|
+
playbackRate?: number;
|
|
15
|
+
/**
|
|
16
|
+
* A chain of AudioNodes the source should route through before reaching the
|
|
17
|
+
* destination. The first node receives the source output; the last node is
|
|
18
|
+
* connected to `destination`.
|
|
19
|
+
*/
|
|
20
|
+
through?: AudioNode[];
|
|
21
|
+
/**
|
|
22
|
+
* Final destination node. Defaults to `ctx.destination`.
|
|
23
|
+
*/
|
|
24
|
+
destination?: AudioNode;
|
|
25
|
+
/**
|
|
26
|
+
* Interval (ms) for `timeupdate` events. @default 50
|
|
27
|
+
*/
|
|
28
|
+
timeupdateInterval?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Enable pitch-preserving time-stretch via WSOLA.
|
|
31
|
+
* When true, `playbackRate` controls tempo without changing pitch.
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
preservePitch?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** Stretcher snapshot extension (re-declared here to avoid static import). */
|
|
37
|
+
interface StretcherSnapshotExtension {
|
|
38
|
+
tempo: number;
|
|
39
|
+
converting: boolean;
|
|
40
|
+
conversionProgress: number;
|
|
41
|
+
bufferHealth: "healthy" | "low" | "critical" | "empty";
|
|
42
|
+
aheadSeconds: number;
|
|
43
|
+
buffering: boolean;
|
|
44
|
+
chunkStates: ("pending" | "queued" | "converting" | "ready" | "failed" | "skipped" | "evicted")[];
|
|
45
|
+
currentChunkIndex: number;
|
|
46
|
+
activeWindowStart: number;
|
|
47
|
+
activeWindowEnd: number;
|
|
48
|
+
totalChunks: number;
|
|
49
|
+
windowConversionProgress: number;
|
|
50
|
+
}
|
|
51
|
+
/** An immutable snapshot of a Playback's current state. */
|
|
52
|
+
interface PlaybackSnapshot {
|
|
53
|
+
state: PlaybackState;
|
|
54
|
+
position: number;
|
|
55
|
+
duration: number;
|
|
56
|
+
progress: number;
|
|
57
|
+
stretcher?: StretcherSnapshotExtension;
|
|
58
|
+
}
|
|
59
|
+
/** Event map emitted by a Playback instance. */
|
|
60
|
+
interface PlaybackEventMap {
|
|
61
|
+
play: void;
|
|
62
|
+
pause: void;
|
|
63
|
+
resume: void;
|
|
64
|
+
seek: {
|
|
65
|
+
position: number;
|
|
66
|
+
};
|
|
67
|
+
stop: void;
|
|
68
|
+
ended: void;
|
|
69
|
+
loop: void;
|
|
70
|
+
statechange: {
|
|
71
|
+
state: PlaybackState;
|
|
72
|
+
};
|
|
73
|
+
timeupdate: {
|
|
74
|
+
position: number;
|
|
75
|
+
duration: number;
|
|
76
|
+
};
|
|
77
|
+
buffering: {
|
|
78
|
+
reason: "initial" | "seek" | "tempo-change" | "underrun";
|
|
79
|
+
};
|
|
80
|
+
buffered: {
|
|
81
|
+
stallDuration: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** The object returned by `play()`. */
|
|
85
|
+
interface Playback {
|
|
86
|
+
/** Current playback state. */
|
|
87
|
+
getState(): PlaybackState;
|
|
88
|
+
/** Current playback position in seconds (AudioContext‑accurate). */
|
|
89
|
+
getCurrentTime(): number;
|
|
90
|
+
/** Total duration of the underlying buffer in seconds. */
|
|
91
|
+
getDuration(): number;
|
|
92
|
+
/** Current progress as a ratio 0 – 1. */
|
|
93
|
+
getProgress(): number;
|
|
94
|
+
pause(): void;
|
|
95
|
+
resume(): void;
|
|
96
|
+
togglePlayPause(): void;
|
|
97
|
+
seek(position: number): void;
|
|
98
|
+
stop(): void;
|
|
99
|
+
setPlaybackRate(rate: number): void;
|
|
100
|
+
setLoop(loop: boolean): void;
|
|
101
|
+
/** Subscribe to a playback event. Returns an unsubscribe function. */
|
|
102
|
+
on<K extends keyof PlaybackEventMap>(event: K, handler: (data: PlaybackEventMap[K]) => void): () => void;
|
|
103
|
+
/** Unsubscribe a previously registered handler. */
|
|
104
|
+
off<K extends keyof PlaybackEventMap>(event: K, handler: (data: PlaybackEventMap[K]) => void): void;
|
|
105
|
+
/** Release all resources (source node, timers, listeners). */
|
|
106
|
+
dispose(): void;
|
|
107
|
+
}
|
|
108
|
+
/** Options for `loadBuffer`. */
|
|
109
|
+
interface LoadBufferOptions {
|
|
110
|
+
/** Progress callback receiving a value between 0 and 1 (if available). */
|
|
111
|
+
onProgress?: (progress: number) => void;
|
|
112
|
+
}
|
|
113
|
+
/** Information about an AudioBuffer. */
|
|
114
|
+
interface BufferInfo {
|
|
115
|
+
duration: number;
|
|
116
|
+
numberOfChannels: number;
|
|
117
|
+
sampleRate: number;
|
|
118
|
+
length: number;
|
|
119
|
+
}
|
|
120
|
+
/** Options for waveform extraction functions. */
|
|
121
|
+
interface ExtractPeaksOptions {
|
|
122
|
+
/** Number of output data points. @default 200 */
|
|
123
|
+
resolution?: number;
|
|
124
|
+
/** Channel index to analyze. @default 0 */
|
|
125
|
+
channel?: number;
|
|
126
|
+
}
|
|
127
|
+
/** A min/max pair representing a single segment of the waveform. */
|
|
128
|
+
interface PeakPair {
|
|
129
|
+
min: number;
|
|
130
|
+
max: number;
|
|
131
|
+
}
|
|
132
|
+
/** Curve types for fade operations. */
|
|
133
|
+
type FadeCurve = "linear" | "exponential" | "equal-power";
|
|
134
|
+
/** Options for fade functions. */
|
|
135
|
+
interface FadeOptions {
|
|
136
|
+
/** Duration of the fade in seconds. @default 1 */
|
|
137
|
+
duration?: number;
|
|
138
|
+
/** Easing curve. @default "linear" */
|
|
139
|
+
curve?: FadeCurve;
|
|
140
|
+
}
|
|
141
|
+
/** Options for crossfade. */
|
|
142
|
+
interface CrossfadeOptions extends FadeOptions {
|
|
143
|
+
}
|
|
144
|
+
/** Options for autoFade. */
|
|
145
|
+
interface AutoFadeOptions {
|
|
146
|
+
/** Fade-in duration at the start in seconds. @default 0 */
|
|
147
|
+
fadeIn?: number;
|
|
148
|
+
/** Fade-out duration before the end in seconds. @default 0 */
|
|
149
|
+
fadeOut?: number;
|
|
150
|
+
/** Curve for both fades. @default "linear" */
|
|
151
|
+
curve?: FadeCurve;
|
|
152
|
+
}
|
|
153
|
+
/** Options for `createScheduler`. */
|
|
154
|
+
interface SchedulerOptions {
|
|
155
|
+
/** How far ahead (seconds) to schedule events. @default 0.1 */
|
|
156
|
+
lookahead?: number;
|
|
157
|
+
/** Interval (ms) between scheduler ticks. @default 25 */
|
|
158
|
+
interval?: number;
|
|
159
|
+
}
|
|
160
|
+
/** A scheduled event entry. */
|
|
161
|
+
interface ScheduledEvent {
|
|
162
|
+
id: string;
|
|
163
|
+
time: number;
|
|
164
|
+
callback: (time: number) => void;
|
|
165
|
+
}
|
|
166
|
+
/** Options for `createClock`. */
|
|
167
|
+
interface ClockOptions {
|
|
168
|
+
/** Beats per minute. @default 120 */
|
|
169
|
+
bpm?: number;
|
|
170
|
+
}
|
|
171
|
+
/** Options for `createContext`. */
|
|
172
|
+
interface CreateContextOptions {
|
|
173
|
+
sampleRate?: number;
|
|
174
|
+
latencyHint?: AudioContextLatencyCategory | number;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export type { AutoFadeOptions as A, BufferInfo as B, ClockOptions as C, ExtractPeaksOptions as E, FadeCurve as F, LoadBufferOptions as L, PeakPair as P, ScheduledEvent as S, CreateContextOptions as a, CrossfadeOptions as b, FadeOptions as c, PlayOptions as d, Playback as e, PlaybackEventMap as f, PlaybackSnapshot as g, PlaybackState as h, SchedulerOptions as i, StretcherSnapshotExtension as j };
|