tone 15.4.3 → 15.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -69,6 +69,20 @@ describe("Meter", () => {
69
69
  }, 400);
70
70
  });
71
71
 
72
+ it("returns 0 below a threshold", (done) => {
73
+ const meter = new Meter({
74
+ normalRange: true,
75
+ });
76
+ const osc = new Oscillator().connect(meter).start();
77
+ osc.volume.value = -101;
78
+ setTimeout(() => {
79
+ expect(meter.getValue()).to.equal(0);
80
+ meter.dispose();
81
+ osc.dispose();
82
+ done();
83
+ }, 400);
84
+ });
85
+
72
86
  it("can get the values in normal range", (done) => {
73
87
  const meter = new Meter({
74
88
  normalRange: true,
@@ -1,4 +1,4 @@
1
- import { gainToDb } from "../../core/type/Conversions.js";
1
+ import { dbToGain, gainToDb } from "../../core/type/Conversions.js";
2
2
  import { NormalRange } from "../../core/type/Units.js";
3
3
  import { warn } from "../../core/util/Debug.js";
4
4
  import { optionsFromArguments } from "../../core/util/Defaults.js";
@@ -93,6 +93,11 @@ export class Meter extends MeterBase<MeterOptions> {
93
93
  return this.getValue();
94
94
  }
95
95
 
96
+ /**
97
+ * Below this threshold, stop smoothing.
98
+ */
99
+ private minValue = dbToGain(-100);
100
+
96
101
  /**
97
102
  * Get the current value of the incoming signal.
98
103
  * Output is in decibels when {@link normalRange} is `false`.
@@ -106,18 +111,25 @@ export class Meter extends MeterBase<MeterOptions> {
106
111
  this.channels === 1
107
112
  ? [aValues as Float32Array]
108
113
  : (aValues as Float32Array[]);
109
- const vals = channelValues.map((values, index) => {
114
+ const vals = channelValues.map((values, channel) => {
110
115
  const totalSquared = values.reduce(
111
116
  (total, current) => total + current * current,
112
117
  0
113
118
  );
114
119
  const rms = Math.sqrt(totalSquared / values.length);
115
- // the rms can only fall at the rate of the smoothing
116
- // but can jump up instantly
117
- this._rms[index] = Math.max(rms, this._rms[index] * this.smoothing);
120
+ if (rms < this.minValue) {
121
+ this._rms[channel] = 0;
122
+ } else {
123
+ // the rms can only fall at the rate of the smoothing
124
+ // but can jump up instantly
125
+ this._rms[channel] = Math.max(
126
+ rms,
127
+ this._rms[channel] * this.smoothing
128
+ );
129
+ }
118
130
  return this.normalRange
119
- ? this._rms[index]
120
- : gainToDb(this._rms[index]);
131
+ ? this._rms[channel]
132
+ : gainToDb(this._rms[channel]);
121
133
  });
122
134
  if (this.channels === 1) {
123
135
  return vals[0];
@@ -9,6 +9,7 @@ import { optionsFromArguments } from "../../core/util/Defaults.js";
9
9
  import { readOnly } from "../../core/util/Interface.js";
10
10
  import { GainToAudio } from "../../signal/GainToAudio.js";
11
11
  import { Signal } from "../../signal/Signal.js";
12
+ import { ToneConstantSource } from "../../signal/ToneConstantSource.js";
12
13
 
13
14
  interface CrossFadeOptions extends ToneAudioNodeOptions {
14
15
  fade: NormalRange;
@@ -59,6 +60,11 @@ export class CrossFade extends ToneAudioNode<CrossFadeOptions> {
59
60
  */
60
61
  private _g2a: GainToAudio = new GainToAudio({ context: this.context });
61
62
 
63
+ /**
64
+ * The constant source which is used to control the panner
65
+ */
66
+ private _constant: ToneConstantSource;
67
+
62
68
  /**
63
69
  * The input which is at full level when fade = 0
64
70
  */
@@ -114,7 +120,11 @@ export class CrossFade extends ToneAudioNode<CrossFadeOptions> {
114
120
  });
115
121
  readOnly(this, "fade");
116
122
 
117
- this.context.getConstant(1).connect(this._panner);
123
+ this._constant = new ToneConstantSource({
124
+ context: this.context,
125
+ offset: 1,
126
+ }).start();
127
+ this._constant.connect(this._panner);
118
128
  this._panner.connect(this._split);
119
129
  // this is necessary for standardized-audio-context
120
130
  // doesn't make any difference for the native AudioContext
@@ -145,6 +155,7 @@ export class CrossFade extends ToneAudioNode<CrossFadeOptions> {
145
155
  this._g2a.dispose();
146
156
  this._panner.disconnect();
147
157
  this._split.disconnect();
158
+ this._constant.dispose();
148
159
  return this;
149
160
  }
150
161
  }
@@ -129,6 +129,9 @@ export abstract class BaseContext
129
129
 
130
130
  abstract clearInterval(_id: number): this;
131
131
 
132
+ /**
133
+ * @deprecated use ToneConstantSource instead
134
+ */
132
135
  abstract getConstant(_val: number): AudioBufferSourceNode;
133
136
 
134
137
  abstract get currentTime(): Seconds;
@@ -40,7 +40,7 @@ export class Context extends BaseContext {
40
40
  readonly name: string = "Context";
41
41
 
42
42
  /**
43
- * A private reference to the BaseAudioContext.
43
+ * A private reference to the BaseAudioContext.
44
44
  */
45
45
  protected readonly _context: AnyAudioContext;
46
46
 
@@ -521,6 +521,7 @@ export class Context extends BaseContext {
521
521
 
522
522
  /**
523
523
  * **Internal** Generate a looped buffer at some constant value.
524
+ * @deprecated
524
525
  */
525
526
  getConstant(val: number): AudioBufferSourceNode {
526
527
  if (this._constants.has(val)) {
@@ -87,23 +87,5 @@ describe("AutoPanner", () => {
87
87
  expect(buffer.getValueAtTime(0)).to.be.closeTo(2, 0.1);
88
88
  expect(buffer.getValueAtTime(0.05)).to.be.closeTo(2, 0.1);
89
89
  });
90
-
91
- /**
92
- * Width Tests
93
- */
94
- it("can set the width", () => {
95
- const autoPanner = new AutoPanner();
96
- autoPanner.width = 0.5;
97
- expect(autoPanner.width).to.be.closeTo(0.5, 0.01);
98
- autoPanner.dispose();
99
- });
100
-
101
- it("can pass width in the constructor", () => {
102
- const autoPanner = new AutoPanner({
103
- width: 0.3,
104
- });
105
- expect(autoPanner.width).to.be.closeTo(0.3, 0.01);
106
- autoPanner.dispose();
107
- });
108
90
  });
109
91
  });
@@ -1,11 +1,10 @@
1
1
  import { Panner } from "../component/channel/Panner.js";
2
- import { Frequency, NormalRange } from "../core/type/Units.js";
2
+ import { Frequency } from "../core/type/Units.js";
3
3
  import { optionsFromArguments } from "../core/util/Defaults.js";
4
4
  import { LFOEffect, LFOEffectOptions } from "./LFOEffect.js";
5
5
 
6
6
  export interface AutoPannerOptions extends LFOEffectOptions {
7
7
  channelCount: number;
8
- width: NormalRange;
9
8
  }
10
9
 
11
10
  /**
@@ -25,9 +24,7 @@ export class AutoPanner extends LFOEffect<AutoPannerOptions> {
25
24
  /**
26
25
  * The filter node
27
26
  */
28
- private readonly _panner: Panner;
29
-
30
- private _width: NormalRange;
27
+ readonly _panner: Panner;
31
28
 
32
29
  /**
33
30
  * @param frequency Rate of left-right oscillation.
@@ -46,42 +43,19 @@ export class AutoPanner extends LFOEffect<AutoPannerOptions> {
46
43
  context: this.context,
47
44
  channelCount: options.channelCount,
48
45
  });
49
-
50
- this._width = options.width;
51
-
52
46
  // connections
53
47
  this.connectEffect(this._panner);
54
48
  this._lfo.connect(this._panner.pan);
55
- this._updateLFORange();
49
+ this._lfo.min = -1;
50
+ this._lfo.max = 1;
56
51
  }
57
52
 
58
53
  static getDefaults(): AutoPannerOptions {
59
54
  return Object.assign(LFOEffect.getDefaults(), {
60
55
  channelCount: 1,
61
- width: 1,
62
56
  });
63
57
  }
64
58
 
65
- /**
66
- * Updates the LFO min/max based on width
67
- */
68
- private _updateLFORange(): void {
69
- this._lfo.min = -this._width;
70
- this._lfo.max = this._width;
71
- }
72
-
73
- /**
74
- * The width of the panning effect. 0 = no panning, 1 = full left-right panning.
75
- */
76
- get width(): NormalRange {
77
- return this._width;
78
- }
79
-
80
- set width(width: NormalRange) {
81
- this._width = width;
82
- this._updateLFORange();
83
- }
84
-
85
59
  dispose(): this {
86
60
  super.dispose();
87
61
  this._panner.dispose();
@@ -1,11 +1,10 @@
1
- import { Gain } from "../core/context/Gain.js";
2
1
  import {
3
- connect,
4
- disconnect,
2
+ ToneAudioNode,
5
3
  ToneAudioNodeOptions,
6
4
  } from "../core/context/ToneAudioNode.js";
7
5
  import { optionsFromArguments } from "../core/util/Defaults.js";
8
6
  import { SignalOperator } from "./SignalOperator.js";
7
+ import { ToneConstantSource } from "./ToneConstantSource.js";
9
8
 
10
9
  /**
11
10
  * Tone.Zero outputs 0's at audio-rate. The reason this has to be
@@ -17,14 +16,14 @@ export class Zero extends SignalOperator<ToneAudioNodeOptions> {
17
16
  readonly name: string = "Zero";
18
17
 
19
18
  /**
20
- * The gain node which connects the constant source to the output
19
+ * A constant source which outputs 0
21
20
  */
22
- private _gain = new Gain({ context: this.context });
21
+ private _constant: ToneConstantSource;
23
22
 
24
23
  /**
25
24
  * Only outputs 0
26
25
  */
27
- output = this._gain;
26
+ output: ToneAudioNode;
28
27
 
29
28
  /**
30
29
  * no input node
@@ -34,7 +33,10 @@ export class Zero extends SignalOperator<ToneAudioNodeOptions> {
34
33
  constructor(options?: Partial<ToneAudioNodeOptions>);
35
34
  constructor() {
36
35
  super(optionsFromArguments(Zero.getDefaults(), arguments));
37
- connect(this.context.getConstant(0), this._gain);
36
+ this._constant = this.output = new ToneConstantSource({
37
+ context: this.context,
38
+ offset: 0,
39
+ }).start();
38
40
  }
39
41
 
40
42
  /**
@@ -42,7 +44,7 @@ export class Zero extends SignalOperator<ToneAudioNodeOptions> {
42
44
  */
43
45
  dispose(): this {
44
46
  super.dispose();
45
- disconnect(this.context.getConstant(0), this._gain);
47
+ this._constant.dispose();
46
48
  return this;
47
49
  }
48
50
  }
package/Tone/version.ts CHANGED
@@ -1 +1 @@
1
- export const version: string = "15.4.3";
1
+ export const version: string = "15.5.1";