Tone.js/Tone/core/context/Offline.ts

66 lines
2.3 KiB
TypeScript
Raw Normal View History

import { getContext, setContext } from "../Global";
import { Seconds } from "../type/Units";
2019-06-17 18:04:17 +00:00
import { OfflineContext } from "./OfflineContext";
import { ToneAudioBuffer } from "./ToneAudioBuffer";
/**
* Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.
* The OfflineAudioContext is capable of rendering much faster than real time in many cases.
2019-09-14 22:44:37 +00:00
* The callback function also passes in an offline instance of [[Context]] which can be used
* to schedule events along the Transport.
* @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.
2019-06-17 18:04:17 +00:00
* @param duration the amount of time to record for.
2019-09-14 22:44:37 +00:00
* @return The promise which is invoked with the ToneAudioBuffer of the recorded output.
2019-06-17 18:04:17 +00:00
* @example
2019-10-23 20:30:07 +00:00
* // render 2 seconds of the oscillator
* Tone.Offline(() => {
2019-10-23 20:30:07 +00:00
* // only nodes created in this callback will be recorded
* const oscillator = new Tone.Oscillator().toDestination().start(0);
2019-09-14 22:44:37 +00:00
* }, 2).then((buffer) => {
2019-10-23 20:30:07 +00:00
* // do something with the output buffer
* console.log(buffer);
* });
2019-06-17 18:04:17 +00:00
* @example
2019-10-23 20:30:07 +00:00
* // can also schedule events along the Transport
* // using the passed in Offline Transport
* Tone.Offline(({ transport }) => {
* const osc = new Tone.Oscillator().toDestination();
2019-10-23 20:30:07 +00:00
* transport.schedule(time => {
* osc.start(time).stop(time + 0.1);
* }, 1);
* // make sure to start the transport
* transport.start(0.2);
2019-09-14 22:44:37 +00:00
* }, 4).then((buffer) => {
2019-10-23 20:30:07 +00:00
* // do something with the output buffer
* console.log(buffer);
* });
2019-08-26 17:44:43 +00:00
* @category Core
2019-06-17 18:04:17 +00:00
*/
export async function Offline(
callback: (context: OfflineContext) => Promise<void> | void,
duration: Seconds,
2019-11-17 18:09:19 +00:00
channels = 2,
sampleRate: number = getContext().sampleRate,
2019-06-17 18:04:17 +00:00
): Promise<ToneAudioBuffer> {
// set the OfflineAudioContext based on the current context
const originalContext = getContext();
2019-06-17 18:04:17 +00:00
const context = new OfflineContext(channels, duration, sampleRate);
setContext(context);
2019-06-17 18:04:17 +00:00
// invoke the callback/scheduling
await callback(context);
// then render the audio
const bufferPromise = context.render();
2019-06-17 18:04:17 +00:00
// return the original AudioContext
setContext(originalContext);
2019-06-17 18:04:17 +00:00
// await the rendering
const buffer = await bufferPromise;
2019-06-17 18:04:17 +00:00
// return the audio
return new ToneAudioBuffer(buffer);
}