cacophony 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cacophony.ts +78 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cacophony",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Typescript audio library with caching",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/cacophony.ts CHANGED
@@ -163,7 +163,7 @@ export class Sound extends FilterManager implements BaseSound {
163
163
 
164
164
  play(): Playback[] {
165
165
  const playback = this.preplay();
166
- playback.forEach(p => p.source.start());
166
+ playback.forEach(p => p.source!.start());
167
167
  return playback;
168
168
  }
169
169
 
@@ -193,7 +193,7 @@ export class Sound extends FilterManager implements BaseSound {
193
193
  return this.loopCount;
194
194
  }
195
195
  this.loopCount = loopCount;
196
- this.playbacks.forEach(p => p.source.loop = true);
196
+ this.playbacks.forEach(p => p.source!.loop = true);
197
197
  return this.loopCount;
198
198
  }
199
199
 
@@ -219,9 +219,9 @@ export class Sound extends FilterManager implements BaseSound {
219
219
 
220
220
  class Playback extends FilterManager implements BaseSound {
221
221
  context: AudioContext;
222
- source: AudioBufferSourceNode;
223
- gainNode: GainNode;
224
- panner: PannerNode;
222
+ source?: AudioBufferSourceNode;
223
+ gainNode?: GainNode;
224
+ panner?: PannerNode;
225
225
  loopCount: LoopCount = 0;
226
226
  currentLoop: number = 0;
227
227
  buffer: IAudioBuffer | null = null;
@@ -250,36 +250,68 @@ class Playback extends FilterManager implements BaseSound {
250
250
  }
251
251
 
252
252
  play() {
253
+ if (!this.source) {
254
+ throw new Error('Cannot play a sound that has been cleaned up');
255
+ }
253
256
  this.source.start();
254
257
  return [this];
255
258
  }
256
259
 
257
260
  get volume(): number {
261
+ if (!this.gainNode) {
262
+ throw new Error('Cannot get volume of a sound that has been cleaned up');
263
+ }
258
264
  return this.gainNode.gain.value;
259
265
  }
260
266
 
261
267
  set volume(v: number) {
268
+ if (!this.gainNode) {
269
+ throw new Error('Cannot set volume of a sound that has been cleaned up');
270
+ }
262
271
  this.gainNode.gain.value = v;
263
272
  }
264
273
 
265
- fadeIn(time: number, FfadeType: FadeType = 'linear'): Promise<void> {
274
+ fadeIn(time: number, fadeType: FadeType = 'linear'): Promise<void> {
266
275
  return new Promise(resolve => {
267
- let volume = 0;
268
- const increment = this.gainNode.gain.value / (time * 60); // Assuming time is in seconds
269
- const interval = setInterval(() => {
270
- volume += increment;
271
- this.gainNode.gain.value = volume;
272
- if (volume >= this.gainNode.gain.value) {
273
- clearInterval(interval);
274
- resolve();
276
+ if (!this.gainNode) {
277
+ throw new Error('Cannot fade in a sound that has been cleaned up');
278
+ }
279
+
280
+ const initialVolume = this.gainNode.gain.value;
281
+ const targetVolume = 1; // Assuming the target volume after fade-in is 1 (full volume)
282
+
283
+ // Reset volume to 0 to start the fade-in process
284
+ this.gainNode.gain.value = 0;
285
+
286
+ switch (fadeType) {
287
+ case 'exponential':
288
+ // Start at a low value (0.01) because exponentialRampToValueAtTime cannot ramp from 0
289
+ this.gainNode.gain.setValueAtTime(0.01, this.context.currentTime);
290
+ this.gainNode.gain.exponentialRampToValueAtTime(targetVolume, this.context.currentTime + time);
291
+ break;
292
+ case 'linear':
293
+ this.gainNode.gain.linearRampToValueAtTime(targetVolume, this.context.currentTime + time);
294
+ break;
295
+ }
296
+
297
+ // Resolve the Promise after the fade-in time
298
+ setTimeout(() => {
299
+ // Ensure the final volume is set to the target volume
300
+ if (!this.gainNode) {
301
+ throw new Error('Cannot fade in a sound that has been cleaned up');
275
302
  }
276
- }, 1000 / 60); // 60 times per second
303
+ this.gainNode.gain.value = targetVolume;
304
+ resolve();
305
+ }, time * 1000);
277
306
  });
278
307
  }
279
308
 
280
309
  fadeOut(time: number, fadeType: FadeType = 'linear'): Promise<void> {
281
310
  return new Promise(resolve => {
282
311
  // Storing the current gain value
312
+ if (!this.gainNode) {
313
+ throw new Error('Cannot fade out a sound that has been cleaned up');
314
+ }
283
315
  const initialVolume = this.gainNode.gain.value;
284
316
  switch (fadeType) {
285
317
  case 'exponential':
@@ -296,7 +328,23 @@ class Playback extends FilterManager implements BaseSound {
296
328
  });
297
329
  }
298
330
 
331
+ cleanup(): void {
332
+ if (this.source) {
333
+ this.source.disconnect();
334
+ this.source = undefined;
335
+ }
336
+ if (this.gainNode) {
337
+ this.gainNode.disconnect();
338
+ this.gainNode = undefined;
339
+ }
340
+ this.filters.forEach(filter => filter.disconnect());
341
+ this.filters = [];
342
+ }
343
+
299
344
  loop(loopCount?: LoopCount): LoopCount {
345
+ if (!this.source) {
346
+ throw new Error('Cannot loop a sound that has been cleaned up');
347
+ }
300
348
  if (loopCount === undefined) {
301
349
  return this.source.loop === true ? 'infinite' : 0;
302
350
  }
@@ -307,16 +355,25 @@ class Playback extends FilterManager implements BaseSound {
307
355
  }
308
356
 
309
357
  stop(): void {
358
+ if (!this.source) {
359
+ throw new Error('Cannot stop a sound that has been cleaned up');
360
+ }
310
361
  this.source.stop();
311
362
  }
312
363
 
313
364
  pause(): void {
365
+ if (!this.source) {
366
+ throw new Error('Cannot pause a sound that has been cleaned up');
367
+ }
314
368
  if ('suspend' in this.source.context) {
315
369
  this.source.context.suspend();
316
370
  }
317
371
  }
318
372
 
319
373
  resume(): void {
374
+ if (!this.source) {
375
+ throw new Error('Cannot resume a sound that has been cleaned up');
376
+ }
320
377
  if ('resume' in this.source.context) {
321
378
  this.source.context.resume();
322
379
  }
@@ -333,12 +390,18 @@ class Playback extends FilterManager implements BaseSound {
333
390
  }
334
391
 
335
392
  moveTo(x: number, y: number, z: number): void {
393
+ if (!this.panner) {
394
+ throw new Error('Cannot move a sound that has been cleaned up');
395
+ }
336
396
  this.panner.positionX.value = x;
337
397
  this.panner.positionY.value = y;
338
398
  this.panner.positionZ.value = z;
339
399
  }
340
400
 
341
401
  private refreshFilters(): void {
402
+ if (!this.source || !this.gainNode) {
403
+ throw new Error('Cannot update filters on a sound that has been cleaned up');
404
+ }
342
405
  let connection = this.source;
343
406
  this.source.disconnect();
344
407
  connection = this.applyFilters(connection);