UNPKG

3.14 kBJavaScriptView Raw
1import { __awaiter } from "tslib";
2import { createOfflineAudioContext } from "../context/AudioContext.js";
3import { Context } from "../context/Context.js";
4import { isOfflineAudioContext } from "../util/AdvancedTypeCheck.js";
5import { ToneAudioBuffer } from "./ToneAudioBuffer.js";
6/**
7 * Wrapper around the OfflineAudioContext
8 * @category Core
9 * @example
10 * // generate a single channel, 0.5 second buffer
11 * const context = new Tone.OfflineContext(1, 0.5, 44100);
12 * const osc = new Tone.Oscillator({ context });
13 * context.render().then(buffer => {
14 * console.log(buffer.numberOfChannels, buffer.duration);
15 * });
16 */
17export class OfflineContext extends Context {
18 constructor() {
19 super({
20 clockSource: "offline",
21 context: isOfflineAudioContext(arguments[0])
22 ? arguments[0]
23 : createOfflineAudioContext(arguments[0], arguments[1] * arguments[2], arguments[2]),
24 lookAhead: 0,
25 updateInterval: isOfflineAudioContext(arguments[0])
26 ? 128 / arguments[0].sampleRate
27 : 128 / arguments[2],
28 });
29 this.name = "OfflineContext";
30 /**
31 * An artificial clock source
32 */
33 this._currentTime = 0;
34 this.isOffline = true;
35 this._duration = isOfflineAudioContext(arguments[0])
36 ? arguments[0].length / arguments[0].sampleRate
37 : arguments[1];
38 }
39 /**
40 * Override the now method to point to the internal clock time
41 */
42 now() {
43 return this._currentTime;
44 }
45 /**
46 * Same as this.now()
47 */
48 get currentTime() {
49 return this._currentTime;
50 }
51 /**
52 * Render just the clock portion of the audio context.
53 */
54 _renderClock(asynchronous) {
55 return __awaiter(this, void 0, void 0, function* () {
56 let index = 0;
57 while (this._duration - this._currentTime >= 0) {
58 // invoke all the callbacks on that time
59 this.emit("tick");
60 // increment the clock in block-sized chunks
61 this._currentTime += 128 / this.sampleRate;
62 // yield once a second of audio
63 index++;
64 const yieldEvery = Math.floor(this.sampleRate / 128);
65 if (asynchronous && index % yieldEvery === 0) {
66 yield new Promise((done) => setTimeout(done, 1));
67 }
68 }
69 });
70 }
71 /**
72 * Render the output of the OfflineContext
73 * @param asynchronous If the clock should be rendered asynchronously, which will not block the main thread, but be slightly slower.
74 */
75 render() {
76 return __awaiter(this, arguments, void 0, function* (asynchronous = true) {
77 yield this.workletsAreReady();
78 yield this._renderClock(asynchronous);
79 const buffer = yield this._context.startRendering();
80 return new ToneAudioBuffer(buffer);
81 });
82 }
83 /**
84 * Close the context
85 */
86 close() {
87 return Promise.resolve();
88 }
89}
90//# sourceMappingURL=OfflineContext.js.map
\No newline at end of file