1 | import { getContext } from "../Global.js";
|
2 | import { Tone } from "../Tone.js";
|
3 | import { FrequencyClass } from "../type/Frequency.js";
|
4 | import { TimeClass } from "../type/Time.js";
|
5 | import { TransportTimeClass } from "../type/TransportTime.js";
|
6 | import { assertUsedScheduleTime } from "../util/Debug.js";
|
7 | import { getDefaultsFromInstance, optionsFromArguments, } from "../util/Defaults.js";
|
8 | import { isArray, isBoolean, isDefined, isNumber, isString, isUndef, } from "../util/TypeCheck.js";
|
9 | /**
|
10 | * The Base class for all nodes that have an AudioContext.
|
11 | */
|
12 | export class ToneWithContext extends Tone {
|
13 | constructor() {
|
14 | super();
|
15 | const options = optionsFromArguments(ToneWithContext.getDefaults(), arguments, ["context"]);
|
16 | if (this.defaultContext) {
|
17 | this.context = this.defaultContext;
|
18 | }
|
19 | else {
|
20 | this.context = options.context;
|
21 | }
|
22 | }
|
23 | static getDefaults() {
|
24 | return {
|
25 | context: getContext(),
|
26 | };
|
27 | }
|
28 | /**
|
29 | * Return the current time of the Context clock plus the lookAhead.
|
30 | * @example
|
31 | * setInterval(() => {
|
32 | * console.log(Tone.now());
|
33 | * }, 100);
|
34 | */
|
35 | now() {
|
36 | return this.context.currentTime + this.context.lookAhead;
|
37 | }
|
38 | /**
|
39 | * Return the current time of the Context clock without any lookAhead.
|
40 | * @example
|
41 | * setInterval(() => {
|
42 | * console.log(Tone.immediate());
|
43 | * }, 100);
|
44 | */
|
45 | immediate() {
|
46 | return this.context.currentTime;
|
47 | }
|
48 | /**
|
49 | * The duration in seconds of one sample.
|
50 | */
|
51 | get sampleTime() {
|
52 | return 1 / this.context.sampleRate;
|
53 | }
|
54 | /**
|
55 | * The number of seconds of 1 processing block (128 samples)
|
56 | * @example
|
57 | * console.log(Tone.Destination.blockTime);
|
58 | */
|
59 | get blockTime() {
|
60 | return 128 / this.context.sampleRate;
|
61 | }
|
62 | /**
|
63 | * Convert the incoming time to seconds.
|
64 | * This is calculated against the current {@link TransportClass} bpm
|
65 | * @example
|
66 | * const gain = new Tone.Gain();
|
67 | * setInterval(() => console.log(gain.toSeconds("4n")), 100);
|
68 | * // ramp the tempo to 60 bpm over 30 seconds
|
69 | * Tone.getTransport().bpm.rampTo(60, 30);
|
70 | */
|
71 | toSeconds(time) {
|
72 | assertUsedScheduleTime(time);
|
73 | return new TimeClass(this.context, time).toSeconds();
|
74 | }
|
75 | /**
|
76 | * Convert the input to a frequency number
|
77 | * @example
|
78 | * const gain = new Tone.Gain();
|
79 | * console.log(gain.toFrequency("4n"));
|
80 | */
|
81 | toFrequency(freq) {
|
82 | return new FrequencyClass(this.context, freq).toFrequency();
|
83 | }
|
84 | /**
|
85 | * Convert the input time into ticks
|
86 | * @example
|
87 | * const gain = new Tone.Gain();
|
88 | * console.log(gain.toTicks("4n"));
|
89 | */
|
90 | toTicks(time) {
|
91 | return new TransportTimeClass(this.context, time).toTicks();
|
92 | }
|
93 | //-------------------------------------
|
94 | // GET/SET
|
95 | //-------------------------------------
|
96 | /**
|
97 | * Get a subset of the properties which are in the partial props
|
98 | */
|
99 | _getPartialProperties(props) {
|
100 | const options = this.get();
|
101 | // remove attributes from the prop that are not in the partial
|
102 | Object.keys(options).forEach((name) => {
|
103 | if (isUndef(props[name])) {
|
104 | delete options[name];
|
105 | }
|
106 | });
|
107 | return options;
|
108 | }
|
109 | /**
|
110 | * Get the object's attributes.
|
111 | * @example
|
112 | * const osc = new Tone.Oscillator();
|
113 | * console.log(osc.get());
|
114 | */
|
115 | get() {
|
116 | const defaults = getDefaultsFromInstance(this);
|
117 | Object.keys(defaults).forEach((attribute) => {
|
118 | if (Reflect.has(this, attribute)) {
|
119 | const member = this[attribute];
|
120 | if (isDefined(member) &&
|
121 | isDefined(member.value) &&
|
122 | isDefined(member.setValueAtTime)) {
|
123 | defaults[attribute] = member.value;
|
124 | }
|
125 | else if (member instanceof ToneWithContext) {
|
126 | defaults[attribute] = member._getPartialProperties(defaults[attribute]);
|
127 | // otherwise make sure it's a serializable type
|
128 | }
|
129 | else if (isArray(member) ||
|
130 | isNumber(member) ||
|
131 | isString(member) ||
|
132 | isBoolean(member)) {
|
133 | defaults[attribute] = member;
|
134 | }
|
135 | else {
|
136 | // remove all undefined and unserializable attributes
|
137 | delete defaults[attribute];
|
138 | }
|
139 | }
|
140 | });
|
141 | return defaults;
|
142 | }
|
143 | /**
|
144 | * Set multiple properties at once with an object.
|
145 | * @example
|
146 | * const filter = new Tone.Filter().toDestination();
|
147 | * // set values using an object
|
148 | * filter.set({
|
149 | * frequency: "C6",
|
150 | * type: "highpass"
|
151 | * });
|
152 | * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/Analogsynth_octaves_highmid.mp3").connect(filter);
|
153 | * player.autostart = true;
|
154 | */
|
155 | set(props) {
|
156 | Object.keys(props).forEach((attribute) => {
|
157 | if (Reflect.has(this, attribute) && isDefined(this[attribute])) {
|
158 | if (this[attribute] &&
|
159 | isDefined(this[attribute].value) &&
|
160 | isDefined(this[attribute].setValueAtTime)) {
|
161 | // small optimization
|
162 | if (this[attribute].value !== props[attribute]) {
|
163 | this[attribute].value = props[attribute];
|
164 | }
|
165 | }
|
166 | else if (this[attribute] instanceof ToneWithContext) {
|
167 | this[attribute].set(props[attribute]);
|
168 | }
|
169 | else {
|
170 | this[attribute] = props[attribute];
|
171 | }
|
172 | }
|
173 | });
|
174 | return this;
|
175 | }
|
176 | }
|
177 | //# sourceMappingURL=ToneWithContext.js.map |
\ | No newline at end of file |