UNPKG

5.26 kBJavaScriptView Raw
1import { Signal } from "./Signal.js";
2import { optionsFromArguments } from "../core/util/Defaults.js";
3import { TransportTimeClass } from "../core/type/TransportTime.js";
4import { ToneConstantSource } from "./ToneConstantSource.js";
5/**
6 * Adds the ability to synchronize the signal to the {@link TransportClass}
7 * @category Signal
8 */
9export class SyncedSignal extends Signal {
10 constructor() {
11 const options = optionsFromArguments(Signal.getDefaults(), arguments, [
12 "value",
13 "units",
14 ]);
15 super(options);
16 this.name = "SyncedSignal";
17 /**
18 * Don't override when something is connected to the input
19 */
20 this.override = false;
21 this._lastVal = options.value;
22 this._synced = this.context.transport.scheduleRepeat(this._onTick.bind(this), "1i");
23 this._syncedCallback = this._anchorValue.bind(this);
24 this.context.transport.on("start", this._syncedCallback);
25 this.context.transport.on("pause", this._syncedCallback);
26 this.context.transport.on("stop", this._syncedCallback);
27 // disconnect the constant source from the output and replace it with another one
28 this._constantSource.disconnect();
29 this._constantSource.stop(0);
30 // create a new one
31 this._constantSource = this.output = new ToneConstantSource({
32 context: this.context,
33 offset: options.value,
34 units: options.units,
35 }).start(0);
36 this.setValueAtTime(options.value, 0);
37 }
38 /**
39 * Callback which is invoked every tick.
40 */
41 _onTick(time) {
42 const val = super.getValueAtTime(this.context.transport.seconds);
43 // approximate ramp curves with linear ramps
44 if (this._lastVal !== val) {
45 this._lastVal = val;
46 this._constantSource.offset.setValueAtTime(val, time);
47 }
48 }
49 /**
50 * Anchor the value at the start and stop of the Transport
51 */
52 _anchorValue(time) {
53 const val = super.getValueAtTime(this.context.transport.seconds);
54 this._lastVal = val;
55 this._constantSource.offset.cancelAndHoldAtTime(time);
56 this._constantSource.offset.setValueAtTime(val, time);
57 }
58 getValueAtTime(time) {
59 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
60 return super.getValueAtTime(computedTime);
61 }
62 setValueAtTime(value, time) {
63 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
64 super.setValueAtTime(value, computedTime);
65 return this;
66 }
67 linearRampToValueAtTime(value, time) {
68 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
69 super.linearRampToValueAtTime(value, computedTime);
70 return this;
71 }
72 exponentialRampToValueAtTime(value, time) {
73 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
74 super.exponentialRampToValueAtTime(value, computedTime);
75 return this;
76 }
77 setTargetAtTime(value, startTime, timeConstant) {
78 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
79 super.setTargetAtTime(value, computedTime, timeConstant);
80 return this;
81 }
82 cancelScheduledValues(startTime) {
83 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
84 super.cancelScheduledValues(computedTime);
85 return this;
86 }
87 setValueCurveAtTime(values, startTime, duration, scaling) {
88 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
89 duration = this.toSeconds(duration);
90 super.setValueCurveAtTime(values, computedTime, duration, scaling);
91 return this;
92 }
93 cancelAndHoldAtTime(time) {
94 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
95 super.cancelAndHoldAtTime(computedTime);
96 return this;
97 }
98 setRampPoint(time) {
99 const computedTime = new TransportTimeClass(this.context, time).toSeconds();
100 super.setRampPoint(computedTime);
101 return this;
102 }
103 exponentialRampTo(value, rampTime, startTime) {
104 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
105 super.exponentialRampTo(value, rampTime, computedTime);
106 return this;
107 }
108 linearRampTo(value, rampTime, startTime) {
109 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
110 super.linearRampTo(value, rampTime, computedTime);
111 return this;
112 }
113 targetRampTo(value, rampTime, startTime) {
114 const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();
115 super.targetRampTo(value, rampTime, computedTime);
116 return this;
117 }
118 dispose() {
119 super.dispose();
120 this.context.transport.clear(this._synced);
121 this.context.transport.off("start", this._syncedCallback);
122 this.context.transport.off("pause", this._syncedCallback);
123 this.context.transport.off("stop", this._syncedCallback);
124 this._constantSource.dispose();
125 return this;
126 }
127}
128//# sourceMappingURL=SyncedSignal.js.map
\No newline at end of file