@waveform-playlist/playout 5.0.0-alpha.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.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Naomi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,224 @@
1
+ import { Gain, ToneAudioNode, Volume, BaseContext, Context } from 'tone';
2
+ import { Fade, Track } from '@waveform-playlist/core';
3
+
4
+ type TrackEffectsFunction = (graphEnd: Gain, masterGainNode: ToneAudioNode, isOffline: boolean) => void | (() => void);
5
+ interface ClipInfo {
6
+ buffer: AudioBuffer;
7
+ startTime: number;
8
+ duration: number;
9
+ offset: number;
10
+ fadeIn?: Fade;
11
+ fadeOut?: Fade;
12
+ gain: number;
13
+ }
14
+ interface ToneTrackOptions {
15
+ buffer?: AudioBuffer;
16
+ clips?: ClipInfo[];
17
+ track: Track;
18
+ effects?: TrackEffectsFunction;
19
+ destination?: ToneAudioNode;
20
+ }
21
+ declare class ToneTrack {
22
+ private clips;
23
+ private volumeNode;
24
+ private panNode;
25
+ private muteGain;
26
+ private track;
27
+ private effectsCleanup?;
28
+ private onStopCallback?;
29
+ private activePlayers;
30
+ constructor(options: ToneTrackOptions);
31
+ /**
32
+ * Schedule fade envelopes for a clip at the given start time
33
+ */
34
+ private scheduleFades;
35
+ private gainToDb;
36
+ setVolume(gain: number): void;
37
+ setPan(pan: number): void;
38
+ setMute(muted: boolean): void;
39
+ setSolo(soloed: boolean): void;
40
+ play(when?: number, offset?: number, duration?: number): void;
41
+ pause(): void;
42
+ stop(when?: number): void;
43
+ dispose(): void;
44
+ get id(): string;
45
+ get duration(): number;
46
+ get buffer(): AudioBuffer;
47
+ get isPlaying(): boolean;
48
+ get muted(): boolean;
49
+ get startTime(): number;
50
+ setOnStopCallback(callback: () => void): void;
51
+ }
52
+
53
+ type EffectsFunction = (masterGainNode: Volume, destination: ToneAudioNode, isOffline: boolean) => void | (() => void);
54
+ interface TonePlayoutOptions {
55
+ tracks?: ToneTrack[];
56
+ masterGain?: number;
57
+ effects?: EffectsFunction;
58
+ }
59
+ declare class TonePlayout {
60
+ private tracks;
61
+ private masterVolume;
62
+ private isInitialized;
63
+ private soloedTracks;
64
+ private manualMuteState;
65
+ private effectsCleanup?;
66
+ private onPlaybackCompleteCallback?;
67
+ private activeTracks;
68
+ private playbackSessionId;
69
+ constructor(options?: TonePlayoutOptions);
70
+ private gainToDb;
71
+ init(): Promise<void>;
72
+ addTrack(trackOptions: ToneTrackOptions): ToneTrack;
73
+ removeTrack(trackId: string): void;
74
+ getTrack(trackId: string): ToneTrack | undefined;
75
+ play(when?: number, offset?: number, duration?: number): void;
76
+ pause(): void;
77
+ stop(): void;
78
+ setMasterGain(gain: number): void;
79
+ setSolo(trackId: string, soloed: boolean): void;
80
+ private updateSoloMuting;
81
+ setMute(trackId: string, muted: boolean): void;
82
+ getCurrentTime(): number;
83
+ seekTo(time: number): void;
84
+ dispose(): void;
85
+ get context(): BaseContext;
86
+ get sampleRate(): number;
87
+ setOnPlaybackComplete(callback: () => void): void;
88
+ }
89
+
90
+ /**
91
+ * Global AudioContext Manager
92
+ *
93
+ * Provides a single AudioContext shared across the entire application.
94
+ * This context is used by Tone.js for playback and by all recording/monitoring hooks.
95
+ *
96
+ * Uses Tone.js's Context class which wraps standardized-audio-context for
97
+ * cross-browser compatibility (fixes Firefox AudioListener issues).
98
+ */
99
+
100
+ /**
101
+ * Get the global Tone.js Context
102
+ * This is the main context for cross-browser audio operations.
103
+ * Use context.createAudioWorkletNode(), context.createMediaStreamSource(), etc.
104
+ * @returns The Tone.js Context instance
105
+ */
106
+ declare function getGlobalContext(): Context;
107
+ /**
108
+ * Get or create the global AudioContext
109
+ * Uses Tone.js Context for cross-browser compatibility
110
+ * @returns The global AudioContext instance (rawContext from Tone.Context)
111
+ */
112
+ declare function getGlobalAudioContext(): AudioContext;
113
+ /**
114
+ * @deprecated Use getGlobalContext() instead
115
+ * Get the Tone.js Context's rawContext typed as IAudioContext
116
+ * @returns The rawContext cast as IAudioContext
117
+ */
118
+ declare function getGlobalToneContext(): Context;
119
+ /**
120
+ * Resume the global AudioContext if it's suspended
121
+ * Should be called in response to a user gesture (e.g., button click)
122
+ * @returns Promise that resolves when context is running
123
+ */
124
+ declare function resumeGlobalAudioContext(): Promise<void>;
125
+ /**
126
+ * Get the current state of the global AudioContext
127
+ * @returns The AudioContext state ('suspended', 'running', or 'closed')
128
+ */
129
+ declare function getGlobalAudioContextState(): AudioContextState;
130
+ /**
131
+ * Close the global AudioContext
132
+ * Should only be called when the application is shutting down
133
+ */
134
+ declare function closeGlobalAudioContext(): Promise<void>;
135
+
136
+ /**
137
+ * MediaStreamSource Manager
138
+ *
139
+ * Manages MediaStreamAudioSourceNode instances to ensure only one source
140
+ * is created per MediaStream per AudioContext.
141
+ *
142
+ * Web Audio API constraint: You can only create one MediaStreamAudioSourceNode
143
+ * per MediaStream per AudioContext. Multiple attempts will fail or disconnect
144
+ * previous sources.
145
+ *
146
+ * This manager ensures a single source is shared across multiple consumers
147
+ * (e.g., AnalyserNode for VU meter, AudioWorkletNode for recording).
148
+ *
149
+ * NOTE: With Tone.js Context, you can also use context.createMediaStreamSource()
150
+ * directly, which handles cross-browser compatibility internally.
151
+ */
152
+ /**
153
+ * Get or create a MediaStreamAudioSourceNode for the given stream
154
+ *
155
+ * @param stream - The MediaStream to create a source for
156
+ * @returns MediaStreamAudioSourceNode that can be connected to multiple nodes
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const source = getMediaStreamSource(stream);
161
+ *
162
+ * // Multiple consumers can connect to the same source
163
+ * source.connect(analyserNode); // For VU meter
164
+ * source.connect(workletNode); // For recording
165
+ * ```
166
+ */
167
+ declare function getMediaStreamSource(stream: MediaStream): MediaStreamAudioSourceNode;
168
+ /**
169
+ * Manually release a MediaStreamSource
170
+ *
171
+ * Normally you don't need to call this - cleanup happens automatically
172
+ * when the stream ends. Only call this if you need to force cleanup.
173
+ *
174
+ * @param stream - The MediaStream to release the source for
175
+ */
176
+ declare function releaseMediaStreamSource(stream: MediaStream): void;
177
+ /**
178
+ * Check if a MediaStreamSource exists for the given stream
179
+ *
180
+ * @param stream - The MediaStream to check
181
+ * @returns true if a source exists for this stream
182
+ */
183
+ declare function hasMediaStreamSource(stream: MediaStream): boolean;
184
+
185
+ /**
186
+ * Fade utilities for Web Audio API
187
+ *
188
+ * Applies fade in/out envelopes to AudioParam (typically gain)
189
+ * using various curve types.
190
+ */
191
+ type FadeType = 'linear' | 'logarithmic' | 'exponential' | 'sCurve';
192
+ /**
193
+ * Simple fade configuration - just duration and type
194
+ */
195
+ interface FadeConfig {
196
+ /** Duration of the fade in seconds */
197
+ duration: number;
198
+ /** Type of fade curve (default: 'linear') */
199
+ type?: FadeType;
200
+ }
201
+ /**
202
+ * Apply a fade in to an AudioParam
203
+ *
204
+ * @param param - The AudioParam to apply the fade to (usually gain)
205
+ * @param startTime - When the fade starts (in seconds, AudioContext time)
206
+ * @param duration - Duration of the fade in seconds
207
+ * @param type - Type of fade curve
208
+ * @param startValue - Starting value (default: 0)
209
+ * @param endValue - Ending value (default: 1)
210
+ */
211
+ declare function applyFadeIn(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
212
+ /**
213
+ * Apply a fade out to an AudioParam
214
+ *
215
+ * @param param - The AudioParam to apply the fade to (usually gain)
216
+ * @param startTime - When the fade starts (in seconds, AudioContext time)
217
+ * @param duration - Duration of the fade in seconds
218
+ * @param type - Type of fade curve
219
+ * @param startValue - Starting value (default: 1)
220
+ * @param endValue - Ending value (default: 0)
221
+ */
222
+ declare function applyFadeOut(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
223
+
224
+ export { type EffectsFunction, type FadeConfig, type FadeType, TonePlayout, type TonePlayoutOptions, ToneTrack, type ToneTrackOptions, type TrackEffectsFunction, applyFadeIn, applyFadeOut, closeGlobalAudioContext, getGlobalAudioContext, getGlobalAudioContextState, getGlobalContext, getGlobalToneContext, getMediaStreamSource, hasMediaStreamSource, releaseMediaStreamSource, resumeGlobalAudioContext };
@@ -0,0 +1,224 @@
1
+ import { Gain, ToneAudioNode, Volume, BaseContext, Context } from 'tone';
2
+ import { Fade, Track } from '@waveform-playlist/core';
3
+
4
+ type TrackEffectsFunction = (graphEnd: Gain, masterGainNode: ToneAudioNode, isOffline: boolean) => void | (() => void);
5
+ interface ClipInfo {
6
+ buffer: AudioBuffer;
7
+ startTime: number;
8
+ duration: number;
9
+ offset: number;
10
+ fadeIn?: Fade;
11
+ fadeOut?: Fade;
12
+ gain: number;
13
+ }
14
+ interface ToneTrackOptions {
15
+ buffer?: AudioBuffer;
16
+ clips?: ClipInfo[];
17
+ track: Track;
18
+ effects?: TrackEffectsFunction;
19
+ destination?: ToneAudioNode;
20
+ }
21
+ declare class ToneTrack {
22
+ private clips;
23
+ private volumeNode;
24
+ private panNode;
25
+ private muteGain;
26
+ private track;
27
+ private effectsCleanup?;
28
+ private onStopCallback?;
29
+ private activePlayers;
30
+ constructor(options: ToneTrackOptions);
31
+ /**
32
+ * Schedule fade envelopes for a clip at the given start time
33
+ */
34
+ private scheduleFades;
35
+ private gainToDb;
36
+ setVolume(gain: number): void;
37
+ setPan(pan: number): void;
38
+ setMute(muted: boolean): void;
39
+ setSolo(soloed: boolean): void;
40
+ play(when?: number, offset?: number, duration?: number): void;
41
+ pause(): void;
42
+ stop(when?: number): void;
43
+ dispose(): void;
44
+ get id(): string;
45
+ get duration(): number;
46
+ get buffer(): AudioBuffer;
47
+ get isPlaying(): boolean;
48
+ get muted(): boolean;
49
+ get startTime(): number;
50
+ setOnStopCallback(callback: () => void): void;
51
+ }
52
+
53
+ type EffectsFunction = (masterGainNode: Volume, destination: ToneAudioNode, isOffline: boolean) => void | (() => void);
54
+ interface TonePlayoutOptions {
55
+ tracks?: ToneTrack[];
56
+ masterGain?: number;
57
+ effects?: EffectsFunction;
58
+ }
59
+ declare class TonePlayout {
60
+ private tracks;
61
+ private masterVolume;
62
+ private isInitialized;
63
+ private soloedTracks;
64
+ private manualMuteState;
65
+ private effectsCleanup?;
66
+ private onPlaybackCompleteCallback?;
67
+ private activeTracks;
68
+ private playbackSessionId;
69
+ constructor(options?: TonePlayoutOptions);
70
+ private gainToDb;
71
+ init(): Promise<void>;
72
+ addTrack(trackOptions: ToneTrackOptions): ToneTrack;
73
+ removeTrack(trackId: string): void;
74
+ getTrack(trackId: string): ToneTrack | undefined;
75
+ play(when?: number, offset?: number, duration?: number): void;
76
+ pause(): void;
77
+ stop(): void;
78
+ setMasterGain(gain: number): void;
79
+ setSolo(trackId: string, soloed: boolean): void;
80
+ private updateSoloMuting;
81
+ setMute(trackId: string, muted: boolean): void;
82
+ getCurrentTime(): number;
83
+ seekTo(time: number): void;
84
+ dispose(): void;
85
+ get context(): BaseContext;
86
+ get sampleRate(): number;
87
+ setOnPlaybackComplete(callback: () => void): void;
88
+ }
89
+
90
+ /**
91
+ * Global AudioContext Manager
92
+ *
93
+ * Provides a single AudioContext shared across the entire application.
94
+ * This context is used by Tone.js for playback and by all recording/monitoring hooks.
95
+ *
96
+ * Uses Tone.js's Context class which wraps standardized-audio-context for
97
+ * cross-browser compatibility (fixes Firefox AudioListener issues).
98
+ */
99
+
100
+ /**
101
+ * Get the global Tone.js Context
102
+ * This is the main context for cross-browser audio operations.
103
+ * Use context.createAudioWorkletNode(), context.createMediaStreamSource(), etc.
104
+ * @returns The Tone.js Context instance
105
+ */
106
+ declare function getGlobalContext(): Context;
107
+ /**
108
+ * Get or create the global AudioContext
109
+ * Uses Tone.js Context for cross-browser compatibility
110
+ * @returns The global AudioContext instance (rawContext from Tone.Context)
111
+ */
112
+ declare function getGlobalAudioContext(): AudioContext;
113
+ /**
114
+ * @deprecated Use getGlobalContext() instead
115
+ * Get the Tone.js Context's rawContext typed as IAudioContext
116
+ * @returns The rawContext cast as IAudioContext
117
+ */
118
+ declare function getGlobalToneContext(): Context;
119
+ /**
120
+ * Resume the global AudioContext if it's suspended
121
+ * Should be called in response to a user gesture (e.g., button click)
122
+ * @returns Promise that resolves when context is running
123
+ */
124
+ declare function resumeGlobalAudioContext(): Promise<void>;
125
+ /**
126
+ * Get the current state of the global AudioContext
127
+ * @returns The AudioContext state ('suspended', 'running', or 'closed')
128
+ */
129
+ declare function getGlobalAudioContextState(): AudioContextState;
130
+ /**
131
+ * Close the global AudioContext
132
+ * Should only be called when the application is shutting down
133
+ */
134
+ declare function closeGlobalAudioContext(): Promise<void>;
135
+
136
+ /**
137
+ * MediaStreamSource Manager
138
+ *
139
+ * Manages MediaStreamAudioSourceNode instances to ensure only one source
140
+ * is created per MediaStream per AudioContext.
141
+ *
142
+ * Web Audio API constraint: You can only create one MediaStreamAudioSourceNode
143
+ * per MediaStream per AudioContext. Multiple attempts will fail or disconnect
144
+ * previous sources.
145
+ *
146
+ * This manager ensures a single source is shared across multiple consumers
147
+ * (e.g., AnalyserNode for VU meter, AudioWorkletNode for recording).
148
+ *
149
+ * NOTE: With Tone.js Context, you can also use context.createMediaStreamSource()
150
+ * directly, which handles cross-browser compatibility internally.
151
+ */
152
+ /**
153
+ * Get or create a MediaStreamAudioSourceNode for the given stream
154
+ *
155
+ * @param stream - The MediaStream to create a source for
156
+ * @returns MediaStreamAudioSourceNode that can be connected to multiple nodes
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const source = getMediaStreamSource(stream);
161
+ *
162
+ * // Multiple consumers can connect to the same source
163
+ * source.connect(analyserNode); // For VU meter
164
+ * source.connect(workletNode); // For recording
165
+ * ```
166
+ */
167
+ declare function getMediaStreamSource(stream: MediaStream): MediaStreamAudioSourceNode;
168
+ /**
169
+ * Manually release a MediaStreamSource
170
+ *
171
+ * Normally you don't need to call this - cleanup happens automatically
172
+ * when the stream ends. Only call this if you need to force cleanup.
173
+ *
174
+ * @param stream - The MediaStream to release the source for
175
+ */
176
+ declare function releaseMediaStreamSource(stream: MediaStream): void;
177
+ /**
178
+ * Check if a MediaStreamSource exists for the given stream
179
+ *
180
+ * @param stream - The MediaStream to check
181
+ * @returns true if a source exists for this stream
182
+ */
183
+ declare function hasMediaStreamSource(stream: MediaStream): boolean;
184
+
185
+ /**
186
+ * Fade utilities for Web Audio API
187
+ *
188
+ * Applies fade in/out envelopes to AudioParam (typically gain)
189
+ * using various curve types.
190
+ */
191
+ type FadeType = 'linear' | 'logarithmic' | 'exponential' | 'sCurve';
192
+ /**
193
+ * Simple fade configuration - just duration and type
194
+ */
195
+ interface FadeConfig {
196
+ /** Duration of the fade in seconds */
197
+ duration: number;
198
+ /** Type of fade curve (default: 'linear') */
199
+ type?: FadeType;
200
+ }
201
+ /**
202
+ * Apply a fade in to an AudioParam
203
+ *
204
+ * @param param - The AudioParam to apply the fade to (usually gain)
205
+ * @param startTime - When the fade starts (in seconds, AudioContext time)
206
+ * @param duration - Duration of the fade in seconds
207
+ * @param type - Type of fade curve
208
+ * @param startValue - Starting value (default: 0)
209
+ * @param endValue - Ending value (default: 1)
210
+ */
211
+ declare function applyFadeIn(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
212
+ /**
213
+ * Apply a fade out to an AudioParam
214
+ *
215
+ * @param param - The AudioParam to apply the fade to (usually gain)
216
+ * @param startTime - When the fade starts (in seconds, AudioContext time)
217
+ * @param duration - Duration of the fade in seconds
218
+ * @param type - Type of fade curve
219
+ * @param startValue - Starting value (default: 1)
220
+ * @param endValue - Ending value (default: 0)
221
+ */
222
+ declare function applyFadeOut(param: AudioParam, startTime: number, duration: number, type?: FadeType, startValue?: number, endValue?: number): void;
223
+
224
+ export { type EffectsFunction, type FadeConfig, type FadeType, TonePlayout, type TonePlayoutOptions, ToneTrack, type ToneTrackOptions, type TrackEffectsFunction, applyFadeIn, applyFadeOut, closeGlobalAudioContext, getGlobalAudioContext, getGlobalAudioContextState, getGlobalContext, getGlobalToneContext, getMediaStreamSource, hasMediaStreamSource, releaseMediaStreamSource, resumeGlobalAudioContext };