@idealyst/audio 1.2.48

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/src/types.ts ADDED
@@ -0,0 +1,470 @@
1
+ // ============================================
2
+ // AUDIO CONFIGURATION
3
+ // ============================================
4
+
5
+ export type SampleRate = 8000 | 16000 | 22050 | 44100 | 48000;
6
+ export type BitDepth = 8 | 16 | 32;
7
+ export type ChannelCount = 1 | 2;
8
+
9
+ /**
10
+ * Audio configuration for recording and playback.
11
+ */
12
+ export interface AudioConfig {
13
+ /** Sample rate in Hz. Default: 16000 */
14
+ sampleRate: SampleRate;
15
+
16
+ /** Number of audio channels. Default: 1 (mono) */
17
+ channels: ChannelCount;
18
+
19
+ /** Bits per sample. Default: 16 */
20
+ bitDepth: BitDepth;
21
+ }
22
+
23
+ // ============================================
24
+ // AUDIO SESSION (iOS/Android)
25
+ // ============================================
26
+
27
+ /**
28
+ * iOS AVAudioSession categories
29
+ */
30
+ export type AudioSessionCategory =
31
+ | 'ambient'
32
+ | 'soloAmbient'
33
+ | 'playback'
34
+ | 'record'
35
+ | 'playAndRecord'
36
+ | 'multiRoute';
37
+
38
+ /**
39
+ * iOS AVAudioSession category options
40
+ */
41
+ export type AudioSessionCategoryOption =
42
+ | 'mixWithOthers'
43
+ | 'duckOthers'
44
+ | 'allowBluetooth'
45
+ | 'allowBluetoothA2DP'
46
+ | 'allowAirPlay'
47
+ | 'defaultToSpeaker'
48
+ | 'interruptSpokenAudioAndMixWithOthers';
49
+
50
+ /**
51
+ * iOS AVAudioSession modes
52
+ */
53
+ export type AudioSessionMode =
54
+ | 'default'
55
+ | 'voiceChat'
56
+ | 'gameChat'
57
+ | 'videoRecording'
58
+ | 'measurement'
59
+ | 'moviePlayback'
60
+ | 'videoChat'
61
+ | 'spokenAudio';
62
+
63
+ /**
64
+ * Audio session configuration
65
+ */
66
+ export interface AudioSessionConfig {
67
+ category: AudioSessionCategory;
68
+ categoryOptions?: AudioSessionCategoryOption[];
69
+ mode?: AudioSessionMode;
70
+ active?: boolean;
71
+ }
72
+
73
+ /**
74
+ * Audio session state
75
+ */
76
+ export interface AudioSessionState {
77
+ isActive: boolean;
78
+ category: AudioSessionCategory;
79
+ mode: AudioSessionMode;
80
+ categoryOptions: AudioSessionCategoryOption[];
81
+ }
82
+
83
+ /**
84
+ * Audio session interruption info
85
+ */
86
+ export interface AudioSessionInterruption {
87
+ type: 'began' | 'ended';
88
+ shouldResume?: boolean;
89
+ }
90
+
91
+ /**
92
+ * Audio session route change info
93
+ */
94
+ export interface AudioSessionRouteChange {
95
+ reason: string;
96
+ previousOutputs: string[];
97
+ currentOutputs: string[];
98
+ }
99
+
100
+ // ============================================
101
+ // PCM DATA
102
+ // ============================================
103
+
104
+ /**
105
+ * PCM audio data packet
106
+ */
107
+ export interface PCMData {
108
+ /** Raw audio buffer */
109
+ buffer: ArrayBuffer;
110
+
111
+ /** Typed array of samples */
112
+ samples: Int8Array | Int16Array | Float32Array;
113
+
114
+ /** Capture/playback timestamp */
115
+ timestamp: number;
116
+
117
+ /** Audio configuration */
118
+ config: AudioConfig;
119
+
120
+ /** Convert to Base64 string */
121
+ toBase64(): string;
122
+ }
123
+
124
+ /**
125
+ * Audio level information
126
+ */
127
+ export interface AudioLevel {
128
+ /** Current level (0.0 - 1.0) */
129
+ current: number;
130
+
131
+ /** Peak level since last reset (0.0 - 1.0) */
132
+ peak: number;
133
+
134
+ /** RMS (root mean square) */
135
+ rms: number;
136
+
137
+ /** Decibel value (-Infinity to 0) */
138
+ db: number;
139
+ }
140
+
141
+ // ============================================
142
+ // RECORDER TYPES
143
+ // ============================================
144
+
145
+ export type RecorderState =
146
+ | 'idle'
147
+ | 'requesting_permission'
148
+ | 'starting'
149
+ | 'recording'
150
+ | 'paused'
151
+ | 'stopping'
152
+ | 'error';
153
+
154
+ export type PermissionStatus = 'undetermined' | 'granted' | 'denied' | 'blocked';
155
+
156
+ export interface RecorderStatus {
157
+ state: RecorderState;
158
+ isRecording: boolean;
159
+ isPaused: boolean;
160
+ permission: PermissionStatus;
161
+ duration: number;
162
+ level: AudioLevel;
163
+ config: AudioConfig;
164
+ error?: AudioError;
165
+ }
166
+
167
+ export type RecorderDataCallback = (data: PCMData) => void;
168
+ export type RecorderLevelCallback = (level: AudioLevel) => void;
169
+ export type RecorderStateCallback = (status: RecorderStatus) => void;
170
+
171
+ /**
172
+ * Recorder interface
173
+ */
174
+ export interface IRecorder {
175
+ readonly status: RecorderStatus;
176
+
177
+ checkPermission(): Promise<PermissionStatus>;
178
+ requestPermission(): Promise<PermissionStatus>;
179
+
180
+ start(config?: Partial<AudioConfig>): Promise<void>;
181
+ stop(): Promise<void>;
182
+ pause(): Promise<void>;
183
+ resume(): Promise<void>;
184
+
185
+ onData(callback: RecorderDataCallback): () => void;
186
+ onLevel(callback: RecorderLevelCallback, intervalMs?: number): () => void;
187
+ onStateChange(callback: RecorderStateCallback): () => void;
188
+
189
+ resetPeakLevel(): void;
190
+ dispose(): void;
191
+ }
192
+
193
+ // ============================================
194
+ // PLAYER TYPES
195
+ // ============================================
196
+
197
+ export type PlayerState =
198
+ | 'idle'
199
+ | 'loading'
200
+ | 'ready'
201
+ | 'playing'
202
+ | 'paused'
203
+ | 'stopped'
204
+ | 'error';
205
+
206
+ export interface PlayerStatus {
207
+ state: PlayerState;
208
+ isPlaying: boolean;
209
+ isPaused: boolean;
210
+ duration: number;
211
+ position: number;
212
+ buffered: number;
213
+ volume: number;
214
+ muted: boolean;
215
+ error?: AudioError;
216
+ }
217
+
218
+ export type PlayerStateCallback = (status: PlayerStatus) => void;
219
+ export type PlayerPositionCallback = (position: number) => void;
220
+ export type PlayerBufferCallback = (buffered: number) => void;
221
+ export type PlayerEndedCallback = () => void;
222
+
223
+ /**
224
+ * Player interface
225
+ */
226
+ export interface IPlayer {
227
+ readonly status: PlayerStatus;
228
+
229
+ // File playback
230
+ loadFile(uri: string): Promise<void>;
231
+ unload(): void;
232
+
233
+ // PCM streaming
234
+ loadPCMStream(config: AudioConfig): Promise<void>;
235
+ feedPCMData(data: ArrayBuffer | Int16Array): void;
236
+ flush(): Promise<void>;
237
+
238
+ // Playback control
239
+ play(): Promise<void>;
240
+ pause(): void;
241
+ stop(): void;
242
+ seek(positionMs: number): Promise<void>;
243
+
244
+ // Volume
245
+ setVolume(volume: number): void;
246
+ setMuted(muted: boolean): void;
247
+
248
+ // Events
249
+ onStateChange(callback: PlayerStateCallback): () => void;
250
+ onPosition(callback: PlayerPositionCallback, intervalMs?: number): () => void;
251
+ onBufferChange(callback: PlayerBufferCallback): () => void;
252
+ onEnded(callback: PlayerEndedCallback): () => void;
253
+
254
+ dispose(): void;
255
+ }
256
+
257
+ // ============================================
258
+ // AUDIO CONTEXT
259
+ // ============================================
260
+
261
+ /**
262
+ * Shared audio context interface
263
+ */
264
+ export interface IAudioContext {
265
+ /** Native sample rate of the audio context */
266
+ readonly sampleRate: number;
267
+
268
+ /** Current time in seconds */
269
+ readonly currentTime: number;
270
+
271
+ /** Whether the context is initialized */
272
+ readonly isInitialized: boolean;
273
+
274
+ /** Initialize the audio context (call before using recorder/player) */
275
+ initialize(): Promise<void>;
276
+
277
+ /** Get the underlying platform audio context */
278
+ getContext(): AudioContext | null;
279
+
280
+ /** Suspend the audio context */
281
+ suspend(): Promise<void>;
282
+
283
+ /** Resume the audio context */
284
+ resume(): Promise<void>;
285
+
286
+ /** Close and dispose the audio context */
287
+ close(): Promise<void>;
288
+ }
289
+
290
+ /**
291
+ * Audio session manager interface
292
+ */
293
+ export interface IAudioSessionManager {
294
+ readonly state: AudioSessionState;
295
+
296
+ configure(config: Partial<AudioSessionConfig>): Promise<void>;
297
+ activate(): Promise<void>;
298
+ deactivate(notifyOthers?: boolean): Promise<void>;
299
+
300
+ onInterruption(callback: (interruption: AudioSessionInterruption) => void): () => void;
301
+ onRouteChange(callback: (change: AudioSessionRouteChange) => void): () => void;
302
+
303
+ getCurrentOutputs(): string[];
304
+ }
305
+
306
+ // ============================================
307
+ // ERROR TYPES
308
+ // ============================================
309
+
310
+ export type AudioErrorCode =
311
+ // Permission errors
312
+ | 'PERMISSION_DENIED'
313
+ | 'PERMISSION_BLOCKED'
314
+ // Device errors
315
+ | 'DEVICE_NOT_FOUND'
316
+ | 'DEVICE_IN_USE'
317
+ | 'NOT_SUPPORTED'
318
+ // Playback errors
319
+ | 'SOURCE_NOT_FOUND'
320
+ | 'FORMAT_NOT_SUPPORTED'
321
+ | 'DECODE_ERROR'
322
+ | 'PLAYBACK_ERROR'
323
+ | 'BUFFER_UNDERRUN'
324
+ // Recording errors
325
+ | 'RECORDING_ERROR'
326
+ // General errors
327
+ | 'INITIALIZATION_FAILED'
328
+ | 'INVALID_STATE'
329
+ | 'INVALID_CONFIG'
330
+ | 'UNKNOWN';
331
+
332
+ export interface AudioError {
333
+ code: AudioErrorCode;
334
+ message: string;
335
+ originalError?: Error;
336
+ }
337
+
338
+ // ============================================
339
+ // HOOK TYPES
340
+ // ============================================
341
+
342
+ export interface UseAudioOptions {
343
+ /** Audio session configuration (native only) */
344
+ session?: Partial<AudioSessionConfig>;
345
+
346
+ /** Whether to initialize on mount. Default: true */
347
+ initializeOnMount?: boolean;
348
+ }
349
+
350
+ export interface UseAudioResult {
351
+ /** Whether the audio context is initialized */
352
+ isInitialized: boolean;
353
+
354
+ /** Audio session state (native) */
355
+ sessionState: AudioSessionState;
356
+
357
+ /** Current audio outputs */
358
+ outputs: string[];
359
+
360
+ /** Initialize audio (call before using recorder/player) */
361
+ initialize: () => Promise<void>;
362
+
363
+ /** Configure audio session (native) */
364
+ configureSession: (config: Partial<AudioSessionConfig>) => Promise<void>;
365
+
366
+ /** Suspend audio context */
367
+ suspend: () => Promise<void>;
368
+
369
+ /** Resume audio context */
370
+ resume: () => Promise<void>;
371
+ }
372
+
373
+ export interface UseRecorderOptions {
374
+ /** Audio configuration */
375
+ config?: Partial<AudioConfig>;
376
+
377
+ /** Auto request permission on mount */
378
+ autoRequestPermission?: boolean;
379
+
380
+ /** Level update interval in ms. Default: 100 */
381
+ levelUpdateInterval?: number;
382
+ }
383
+
384
+ export interface UseRecorderResult {
385
+ // State
386
+ status: RecorderStatus;
387
+ isRecording: boolean;
388
+ isPaused: boolean;
389
+ permission: PermissionStatus;
390
+ duration: number;
391
+ level: AudioLevel;
392
+ error: AudioError | null;
393
+
394
+ // Actions
395
+ start: (config?: Partial<AudioConfig>) => Promise<void>;
396
+ stop: () => Promise<void>;
397
+ pause: () => Promise<void>;
398
+ resume: () => Promise<void>;
399
+
400
+ // Permissions
401
+ checkPermission: () => Promise<PermissionStatus>;
402
+ requestPermission: () => Promise<PermissionStatus>;
403
+
404
+ // Data subscription
405
+ subscribeToData: (callback: RecorderDataCallback) => () => void;
406
+
407
+ // Utilities
408
+ resetPeakLevel: () => void;
409
+ }
410
+
411
+ export interface UsePlayerOptions {
412
+ /** Auto play when source is loaded */
413
+ autoPlay?: boolean;
414
+
415
+ /** Initial volume (0.0 - 1.0) */
416
+ volume?: number;
417
+
418
+ /** Position update interval in ms. Default: 100 */
419
+ positionUpdateInterval?: number;
420
+ }
421
+
422
+ export interface UsePlayerResult {
423
+ // State
424
+ status: PlayerStatus;
425
+ isPlaying: boolean;
426
+ isPaused: boolean;
427
+ isLoading: boolean;
428
+ position: number;
429
+ duration: number;
430
+ volume: number;
431
+ error: AudioError | null;
432
+
433
+ // File playback
434
+ loadFile: (uri: string) => Promise<void>;
435
+ unload: () => void;
436
+
437
+ // PCM streaming
438
+ loadPCMStream: (config: AudioConfig) => Promise<void>;
439
+ feedPCMData: (data: ArrayBuffer | Int16Array) => void;
440
+ flush: () => Promise<void>;
441
+
442
+ // Playback control
443
+ play: () => Promise<void>;
444
+ pause: () => void;
445
+ stop: () => void;
446
+ seek: (positionMs: number) => Promise<void>;
447
+
448
+ // Volume
449
+ setVolume: (volume: number) => void;
450
+ toggleMute: () => void;
451
+ }
452
+
453
+ // ============================================
454
+ // PRESET TYPES
455
+ // ============================================
456
+
457
+ export interface AudioProfiles {
458
+ speech: AudioConfig;
459
+ highQuality: AudioConfig;
460
+ studio: AudioConfig;
461
+ phone: AudioConfig;
462
+ }
463
+
464
+ export interface SessionPresets {
465
+ playback: AudioSessionConfig;
466
+ record: AudioSessionConfig;
467
+ voiceChat: AudioSessionConfig;
468
+ ambient: AudioSessionConfig;
469
+ default: AudioSessionConfig;
470
+ }