Exposed a GainNode from sequence.attachAudio()
This commit is contained in:
parent
b3945e2a61
commit
4bf6f78a00
1 changed files with 48 additions and 4 deletions
|
@ -127,9 +127,48 @@ export interface ISequence {
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
attachAudio(args: IAttachAudioArgs): Promise<{
|
attachAudio(args: IAttachAudioArgs): Promise<{
|
||||||
|
/**
|
||||||
|
* An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer AudioBuffer}.
|
||||||
|
* If `args.source` is a URL, then `decodedBuffer` would be the result
|
||||||
|
* of {@link https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData audioContext.decodeAudioData()}
|
||||||
|
* on the audio file at that URL.
|
||||||
|
*
|
||||||
|
* If `args.source` is an `AudioBuffer`, then `decodedBuffer` would be equal to `args.source`
|
||||||
|
*/
|
||||||
decodedBuffer: AudioBuffer
|
decodedBuffer: AudioBuffer
|
||||||
|
/**
|
||||||
|
* The `AudioContext`. It is either equal to `source.audioContext` if it is provided, or
|
||||||
|
* one that's created on the fly.
|
||||||
|
*/
|
||||||
audioContext: AudioContext
|
audioContext: AudioContext
|
||||||
|
/**
|
||||||
|
* Equals to either `args.destinationNode`, or if none is provided, it equals `audioContext.destinationNode`.
|
||||||
|
*
|
||||||
|
* See `gainNode` for more info.
|
||||||
|
*/
|
||||||
destinationNode: AudioNode
|
destinationNode: AudioNode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an intermediate GainNode that Theatre feeds its audio to. It is by default
|
||||||
|
* connected to destinationNode, but you can disconnect the gainNode and feed it to your own graph.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* ```ts
|
||||||
|
* const {gainNode, audioContext} = await sequence.attachAudio({source: '/audio.mp3'})
|
||||||
|
* // disconnect the gainNode (at this point, the sequence's audio track won't be audible)
|
||||||
|
* gainNode.disconnect()
|
||||||
|
* // create our own gain node
|
||||||
|
* const lowerGain = audioContext.createGain()
|
||||||
|
* // lower its volume to 10%
|
||||||
|
* lowerGain.gain.setValueAtTime(0.1, audioContext.currentTime)
|
||||||
|
* // feed the sequence's audio to our lowered gainNode
|
||||||
|
* gainNode.connect(lowerGain)
|
||||||
|
* // feed the lowered gainNode to the audioContext's destination
|
||||||
|
* lowerGain.connect(audioContext.destination)
|
||||||
|
* // now audio will be audible, with 10% the volume
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
gainNode: GainNode
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,20 +230,21 @@ export default class TheatreSequence implements ISequence {
|
||||||
decodedBuffer: AudioBuffer
|
decodedBuffer: AudioBuffer
|
||||||
audioContext: AudioContext
|
audioContext: AudioContext
|
||||||
destinationNode: AudioNode
|
destinationNode: AudioNode
|
||||||
|
gainNode: GainNode
|
||||||
}> {
|
}> {
|
||||||
const {audioContext, destinationNode, decodedBuffer} =
|
const {audioContext, destinationNode, decodedBuffer, gainNode} =
|
||||||
await resolveAudioBuffer(args)
|
await resolveAudioBuffer(args)
|
||||||
|
|
||||||
const playbackController = new AudioPlaybackController(
|
const playbackController = new AudioPlaybackController(
|
||||||
coreTicker,
|
coreTicker,
|
||||||
decodedBuffer,
|
decodedBuffer,
|
||||||
audioContext,
|
audioContext,
|
||||||
destinationNode,
|
gainNode,
|
||||||
)
|
)
|
||||||
|
|
||||||
privateAPI(this).replacePlaybackController(playbackController)
|
privateAPI(this).replacePlaybackController(playbackController)
|
||||||
|
|
||||||
return {audioContext, destinationNode, decodedBuffer}
|
return {audioContext, destinationNode, decodedBuffer, gainNode}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +252,7 @@ async function resolveAudioBuffer(args: IAttachAudioArgs): Promise<{
|
||||||
decodedBuffer: AudioBuffer
|
decodedBuffer: AudioBuffer
|
||||||
audioContext: AudioContext
|
audioContext: AudioContext
|
||||||
destinationNode: AudioNode
|
destinationNode: AudioNode
|
||||||
|
gainNode: GainNode
|
||||||
}> {
|
}> {
|
||||||
function getAudioContext(): Promise<AudioContext> {
|
function getAudioContext(): Promise<AudioContext> {
|
||||||
if (args.audioContext) return Promise.resolve(args.audioContext)
|
if (args.audioContext) return Promise.resolve(args.audioContext)
|
||||||
|
@ -306,10 +347,13 @@ async function resolveAudioBuffer(args: IAttachAudioArgs): Promise<{
|
||||||
])
|
])
|
||||||
|
|
||||||
const destinationNode = args.destinationNode || audioContext.destination
|
const destinationNode = args.destinationNode || audioContext.destination
|
||||||
|
const gainNode = audioContext.createGain()
|
||||||
|
gainNode.connect(destinationNode)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
destinationNode,
|
|
||||||
audioContext,
|
audioContext,
|
||||||
decodedBuffer,
|
decodedBuffer,
|
||||||
|
gainNode,
|
||||||
|
destinationNode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue