Skip to content

Commit

Permalink
VBLOCKS-2030 | API stubs and error checking (#202)
Browse files Browse the repository at this point in the history
* AudioProcessor interface

* Adding add and remove api

* lint

* Address PR reviews

* Update audiohelper.ts
  • Loading branch information
charliesantos authored Oct 2, 2023
1 parent 884aba3 commit 5508dfe
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/twilio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
* @packageDocumentation
* @internalapi
*/
import AudioProcessor from './twilio/audioprocessor';
import Call from './twilio/call';
import Device from './twilio/device';
import * as TwilioError from './twilio/errors';
import { Logger } from './twilio/log';
import { PreflightTest } from './twilio/preflight/preflight';

export { Call, Device, PreflightTest, Logger, TwilioError };
export { AudioProcessor, Call, Device, PreflightTest, Logger, TwilioError };
46 changes: 46 additions & 0 deletions lib/twilio/audiohelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @module Voice
*/
import { EventEmitter } from 'events';
import AudioProcessor from './audioprocessor';
import Device from './device';
import { InvalidArgumentError, NotSupportedError } from './errors';
import Log from './log';
Expand Down Expand Up @@ -147,6 +148,11 @@ class AudioHelper extends EventEmitter {
*/
private _onActiveInputChanged: (stream: MediaStream | null) => Promise<void>;

/**
* Internal reference to the added AudioProcessor
*/
private _processor: AudioProcessor | null;

/**
* A record of unknown devices (Devices without labels)
*/
Expand Down Expand Up @@ -342,6 +348,34 @@ class AudioHelper extends EventEmitter {
});
}

/**
* Adds an AudioProcessor object.
* The AudioHelper will route the input audio stream through the processor
* before sending the audio stream to Twilio.
*
* Only one {@link AudioProcessor} can be added at this time.
* @param processor
*/
addProcessor(processor: AudioProcessor): void {
if (this._processor) {
throw new NotSupportedError('Adding multiple AudioProcessors is not supported at this time.');
}

if (typeof processor !== 'object' || processor === null) {
throw new InvalidArgumentError('Missing AudioProcessor argument.');
}

if (typeof processor.createProcessedStream !== 'function') {
throw new InvalidArgumentError('Missing createProcessedStream() method.');
}

if (typeof processor.destroyProcessedStream !== 'function') {
throw new InvalidArgumentError('Missing destroyProcessedStream() method.');
}

this._processor = processor;
}

/**
* Enable or disable the disconnect sound.
* @param doEnable Passing `true` will enable the sound and `false` will disable the sound.
Expand Down Expand Up @@ -372,6 +406,18 @@ class AudioHelper extends EventEmitter {
return this._maybeEnableSound(Device.SoundName.Outgoing, doEnable);
}

/**
* Removes an AudioProcessor.
* @param processor
*/
removeProcessor(processor: AudioProcessor): void {
if (this._processor !== processor) {
throw new InvalidArgumentError('Cannot remove an AudioProcessor that has not been previously added.');
}

this._processor = null;
}

/**
* Set the MediaTrackConstraints to be applied on every getUserMedia call for new input
* device audio. Any deviceId specified here will be ignored. Instead, device IDs should
Expand Down
34 changes: 34 additions & 0 deletions lib/twilio/audioprocessor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @packageDocumentation
* @module Voice
*/

/**
* Represents an AudioProcessor object that receives an audio stream for processing.
* @publicapi
*/
interface AudioProcessor {
/**
* Called whenever the active input audio stream is updated
* and is ready for processing such as adding audio filters
* or removing background noise.
* Use this method to initiate your audio processing pipeline.
*
* @param stream The input audio stream.
* @returns The modified input audio stream after applying filters.
*/
createProcessedStream(stream: MediaStream): Promise<MediaStream>;

/**
* Called after the processed stream has been destroyed.
* This happens whenever the current input stream is updated.
* Use this method to run any necessary teardown routines
* needed by your audio processing pipeline.
*
* @param stream The torn down processed audio stream.
* @returns
*/
destroyProcessedStream(stream: MediaStream): Promise<void>;
}

export default AudioProcessor;

0 comments on commit 5508dfe

Please sign in to comment.