@antha/audio 0.4.0 → 0.4.2

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.
@@ -241,6 +241,7 @@ export declare class AudioFile extends ListenTarget<AllAudioFileEvents> {
241
241
  readonly isDestroyed: boolean;
242
242
  readonly gainNode: GainNode;
243
243
  readonly sourceKey: string;
244
+ protected readonly activeBufferSources: Set<AudioBufferSourceNode>;
244
245
  constructor(params: AudioFileParams);
245
246
  /**
246
247
  * Load the audio file so it's ready to play. This will automatically be called on the first
@@ -257,6 +258,8 @@ export declare class AudioFile extends ListenTarget<AllAudioFileEvents> {
257
258
  * if audio is currently disabled.
258
259
  */
259
260
  play(): Promise<boolean>;
261
+ /** Stops every active playback while preserving the loaded audio buffer. */
262
+ stop(): void;
260
263
  /** Destroys this audio file entirely; it cannot be used anymore. */
261
264
  destroy(): Promise<void>;
262
265
  /**
@@ -159,6 +159,7 @@ export class AudioFile extends ListenTarget {
159
159
  isDestroyed = false;
160
160
  gainNode;
161
161
  sourceKey;
162
+ activeBufferSources = new Set();
162
163
  constructor(params) {
163
164
  super();
164
165
  this.params = params;
@@ -231,7 +232,9 @@ export class AudioFile extends ListenTarget {
231
232
  const bufferSource = this.audioContext.createBufferSource();
232
233
  bufferSource.buffer = audioBuffer;
233
234
  bufferSource.connect(this.outputNode);
235
+ this.activeBufferSources.add(bufferSource);
234
236
  bufferSource.addEventListener('ended', () => {
237
+ this.activeBufferSources.delete(bufferSource);
235
238
  deferredPlayPromise.resolve(true);
236
239
  this.dispatch(new AudioFilePlayEndEvent());
237
240
  });
@@ -239,6 +242,14 @@ export class AudioFile extends ListenTarget {
239
242
  bufferSource.start();
240
243
  return deferredPlayPromise.promise;
241
244
  }
245
+ /** Stops every active playback while preserving the loaded audio buffer. */
246
+ stop() {
247
+ const activeBufferSources = [...this.activeBufferSources];
248
+ this.activeBufferSources.clear();
249
+ activeBufferSources.forEach((bufferSource) => {
250
+ bufferSource.stop();
251
+ });
252
+ }
242
253
  /** Destroys this audio file entirely; it cannot be used anymore. */
243
254
  async destroy() {
244
255
  if (this.isDestroyed) {
@@ -246,6 +257,7 @@ export class AudioFile extends ListenTarget {
246
257
  return;
247
258
  }
248
259
  makeWritable(this).isDestroyed = true;
260
+ this.stop();
249
261
  super.destroy();
250
262
  const cacheEntry = await this.audioCache[this.urlOrBase64];
251
263
  if (cacheEntry) {
@@ -58,6 +58,12 @@ export declare class AudioPlayer extends ListenTarget<AllAudioFileEvents> {
58
58
  protected setupAudioFile(params: Readonly<AudioSetupParams>): AudioFile;
59
59
  /** Unloads all the attached files. */
60
60
  unloadFiles(files: ReadonlyArray<Readonly<AudioSetupParams>>): Promise<void>;
61
+ /** Stops all active playback for an already-loaded audio file. */
62
+ stopFile(file: Readonly<AudioSetupParams>): void;
63
+ /** Stops all active playback for the given already-loaded audio files. */
64
+ stopFiles(files: ReadonlyArray<Readonly<AudioSetupParams>>): void;
65
+ /** Stops all active playback without unloading any audio files. */
66
+ stopAllFiles(): void;
61
67
  /** Load a batch of audio files. */
62
68
  loadFiles(files: ReadonlyArray<Readonly<AudioSetupParams>>, options?: Readonly<PartialWithUndefined<{
63
69
  progressCallback: AudioLoadProgressCallback;
@@ -1,4 +1,4 @@
1
- import { awaitedBlockingMap, clamp, makeWritable, } from '@augment-vir/common';
1
+ import { awaitedBlockingMap, clamp, getObjectTypedValues, makeWritable, } from '@augment-vir/common';
2
2
  import { ListenTarget } from 'typed-event-target';
3
3
  import { AudioFile, createAudioSourceKey, PlayingEnabledEvent, setupEffects, } from './audio-file.js';
4
4
  /**
@@ -72,6 +72,23 @@ export class AudioPlayer extends ListenTarget {
72
72
  delete this.audioFiles[sourceKey];
73
73
  }));
74
74
  }
75
+ /** Stops all active playback for an already-loaded audio file. */
76
+ stopFile(file) {
77
+ const sourceKey = createAudioSourceKey(file);
78
+ this.audioFiles[sourceKey]?.stop();
79
+ }
80
+ /** Stops all active playback for the given already-loaded audio files. */
81
+ stopFiles(files) {
82
+ files.forEach((file) => {
83
+ this.stopFile(file);
84
+ });
85
+ }
86
+ /** Stops all active playback without unloading any audio files. */
87
+ stopAllFiles() {
88
+ getObjectTypedValues(this.audioFiles).forEach((audioFile) => {
89
+ audioFile.stop();
90
+ });
91
+ }
75
92
  /** Load a batch of audio files. */
76
93
  async loadFiles(files, options = {}) {
77
94
  let loadedCount = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antha/audio",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "An Antha mod for handling audio.",
5
5
  "keywords": [
6
6
  "vir",
@@ -37,7 +37,7 @@
37
37
  "@augment-vir/common": "^32.2.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@antha/engine": "^0.4.0",
40
+ "@antha/engine": "^0.4.2",
41
41
  "@augment-vir/test": "^32.2.3",
42
42
  "@web/dev-server-esbuild": "^2.0.0",
43
43
  "@web/test-runner": "^1.0.0",
@@ -46,7 +46,7 @@
46
46
  "typed-event-target": "^4.3.3"
47
47
  },
48
48
  "peerDependencies": {
49
- "@antha/engine": "^0.4.0",
49
+ "@antha/engine": "^0.4.2",
50
50
  "element-vir": ">=26",
51
51
  "typed-event-target": ">=4.3"
52
52
  },