mercury-engine 1.0.9 → 1.2.0
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.
- package/README.md +30 -0
- package/dist/mercury.js +182 -47
- package/dist/mercury.min.es5.js +2 -2
- package/dist/mercury.min.js +1 -1
- package/examples/hydra/index.html +83 -0
- package/examples/interface/index.html +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -180,6 +180,36 @@ Stop the recording and download the file `myRecording.webm`
|
|
|
180
180
|
Engine.record(false, 'myRecording');
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
### Meter
|
|
184
|
+
|
|
185
|
+
You can add a meter to the main audio output and poll for the amplitude value from the meter to for example create audio-reactive visuals in other programming languages such as Hydra or P5.js.
|
|
186
|
+
|
|
187
|
+
First add the meter, optionally with a smoothing factor (default=0.7)
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
Engine.addMeter();
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Get the meter value as floating-point between 0-1
|
|
194
|
+
|
|
195
|
+
```js
|
|
196
|
+
Engine.getMeter();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Store the meters amplitude value in a global variable for usage in other places and update regularly with a setInterval at a defined interval in milliseconds.
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
let amp;
|
|
203
|
+
|
|
204
|
+
setInterval(() => amp = Engine.getMeter(), 100);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
For example control some visual parameter in [Hydra](https://hydra.ojack.xyz)
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
osc(10, 0.2, () => amp * 20).out();
|
|
211
|
+
```
|
|
212
|
+
|
|
183
213
|
### MIDI
|
|
184
214
|
|
|
185
215
|
WebMIDI is included and started if the browser is compatible with it. If not, an error will be printed to the console. You can provide a callback function `onmidi` to execute some code when the WebMIDI enabling was succesful.
|
package/dist/mercury.js
CHANGED
|
@@ -6590,6 +6590,11 @@ module.exports={
|
|
|
6590
6590
|
"low"
|
|
6591
6591
|
],
|
|
6592
6592
|
|
|
6593
|
+
"super" : [
|
|
6594
|
+
"fat",
|
|
6595
|
+
"unison"
|
|
6596
|
+
],
|
|
6597
|
+
|
|
6593
6598
|
"add_fx" : [
|
|
6594
6599
|
"fx",
|
|
6595
6600
|
"withFX",
|
|
@@ -6702,7 +6707,6 @@ const emptyDefault = {
|
|
|
6702
6707
|
'beat' : [ 1, -1 ],
|
|
6703
6708
|
'amp' : [ 1 ],
|
|
6704
6709
|
'env' : [ 1, 250 ],
|
|
6705
|
-
'pan' : [ 0 ],
|
|
6706
6710
|
'note' : [ 0, 0 ],
|
|
6707
6711
|
'add_fx' : []
|
|
6708
6712
|
}
|
|
@@ -6714,14 +6718,16 @@ const instrumentDefaults = {
|
|
|
6714
6718
|
'type' : 'saw',
|
|
6715
6719
|
'functions' : {
|
|
6716
6720
|
'amp' : [ 0.7 ],
|
|
6717
|
-
'wave2' : [ 'saw', 0 ]
|
|
6721
|
+
'wave2' : [ 'saw', 0 ],
|
|
6722
|
+
'pan' : [ 0 ]
|
|
6718
6723
|
}
|
|
6719
6724
|
},
|
|
6720
6725
|
'polySynth' : {
|
|
6721
6726
|
'type' : 'saw',
|
|
6722
6727
|
'functions' : {
|
|
6723
6728
|
'amp' : [ 0.7 ],
|
|
6724
|
-
'wave2' : [ 'saw', 0 ]
|
|
6729
|
+
'wave2' : [ 'saw', 0 ],
|
|
6730
|
+
'pan' : [ 0 ]
|
|
6725
6731
|
}
|
|
6726
6732
|
},
|
|
6727
6733
|
'sample' : {
|
|
@@ -6732,7 +6738,8 @@ const instrumentDefaults = {
|
|
|
6732
6738
|
'stretch' : [ 0, 1, 1 ],
|
|
6733
6739
|
'speed' : [ 1 ],
|
|
6734
6740
|
'note' : [ 'off' ],
|
|
6735
|
-
'tune' : [ 60 ]
|
|
6741
|
+
'tune' : [ 60 ],
|
|
6742
|
+
'pan' : [ 0 ]
|
|
6736
6743
|
}
|
|
6737
6744
|
},
|
|
6738
6745
|
'loop' : {
|
|
@@ -6743,7 +6750,8 @@ const instrumentDefaults = {
|
|
|
6743
6750
|
'stretch' : [ 1, 1, 1 ],
|
|
6744
6751
|
'speed' : [ 1 ],
|
|
6745
6752
|
'note' : [ 'off' ],
|
|
6746
|
-
'tune' : [ 60 ]
|
|
6753
|
+
'tune' : [ 60 ],
|
|
6754
|
+
'pan' : [ 0 ]
|
|
6747
6755
|
}
|
|
6748
6756
|
},
|
|
6749
6757
|
'midi' : {
|
|
@@ -6760,7 +6768,8 @@ const instrumentDefaults = {
|
|
|
6760
6768
|
'functions' : {
|
|
6761
6769
|
'env' : [ -1 ],
|
|
6762
6770
|
'amp' : [ 0.9 ],
|
|
6763
|
-
'note' : [ 'off' ]
|
|
6771
|
+
'note' : [ 'off' ],
|
|
6772
|
+
'pan' : [ 0 ]
|
|
6764
6773
|
}
|
|
6765
6774
|
}
|
|
6766
6775
|
}
|
|
@@ -14922,6 +14931,12 @@ const fxMap = {
|
|
|
14922
14931
|
'degrade' : (params) => {
|
|
14923
14932
|
return new DownSampler(params);
|
|
14924
14933
|
},
|
|
14934
|
+
'room' : (params) => {
|
|
14935
|
+
return new Reverb(params);
|
|
14936
|
+
},
|
|
14937
|
+
'verb' : (params) => {
|
|
14938
|
+
return new Reverb(params);
|
|
14939
|
+
},
|
|
14925
14940
|
'reverb' : (params) => {
|
|
14926
14941
|
return new Reverb(params);
|
|
14927
14942
|
},
|
|
@@ -14931,9 +14946,9 @@ const fxMap = {
|
|
|
14931
14946
|
'pitchShift' : (params) => {
|
|
14932
14947
|
return new PitchShift(params);
|
|
14933
14948
|
},
|
|
14934
|
-
'tune' : (params) => {
|
|
14935
|
-
|
|
14936
|
-
},
|
|
14949
|
+
// 'tune' : (params) => {
|
|
14950
|
+
// return new PitchShift(params);
|
|
14951
|
+
// },
|
|
14937
14952
|
'filter' : (params) => {
|
|
14938
14953
|
return new Filter(params);
|
|
14939
14954
|
},
|
|
@@ -14958,8 +14973,14 @@ const fxMap = {
|
|
|
14958
14973
|
'ppDelay' : (params) => {
|
|
14959
14974
|
return new PingPongDelay(params);
|
|
14960
14975
|
},
|
|
14961
|
-
'freeverb' : (params) => {
|
|
14962
|
-
|
|
14976
|
+
// 'freeverb' : (params) => {
|
|
14977
|
+
// return new FreeVerb(params);
|
|
14978
|
+
// },
|
|
14979
|
+
'chorus' : (params) => {
|
|
14980
|
+
return new Chorus(Util.mapDefaults(params, ['4/1', 45, 0.5]));
|
|
14981
|
+
},
|
|
14982
|
+
'double' : (params) => {
|
|
14983
|
+
return new Chorus(Util.mapDefaults(params, ['8/1', 8, 1]));
|
|
14963
14984
|
}
|
|
14964
14985
|
}
|
|
14965
14986
|
module.exports = fxMap;
|
|
@@ -15077,6 +15098,41 @@ const Compressor = function(_params){
|
|
|
15077
15098
|
}
|
|
15078
15099
|
}
|
|
15079
15100
|
|
|
15101
|
+
// A Chorus effect based on the default ToneJS effect
|
|
15102
|
+
// Also the Double effect if the wetdry is set to 1 (only wet signal)
|
|
15103
|
+
//
|
|
15104
|
+
const Chorus = function(_params){
|
|
15105
|
+
// also start the oscillators for the effect
|
|
15106
|
+
this._fx = new Tone.Chorus().start();
|
|
15107
|
+
|
|
15108
|
+
this.set = (c, time, bpm) => {
|
|
15109
|
+
// convert division to frequency
|
|
15110
|
+
let f = Util.divToF(Util.getParam(_params[0], c), bpm);
|
|
15111
|
+
this._fx.frequency.setValueAtTime(f, time);
|
|
15112
|
+
// delaytime/2 because of up and down through center
|
|
15113
|
+
// eg. 25 goes from 0 to 50, 40 goes from 0 to 80, etc.
|
|
15114
|
+
this._fx.delayTime = Util.getParam(_params[1], c) / 2;
|
|
15115
|
+
|
|
15116
|
+
// waveform for chorus is not supported in browser instead change wetdry
|
|
15117
|
+
let w = Util.getParam(_params[2], c);
|
|
15118
|
+
if (isNaN(w)){
|
|
15119
|
+
log(`Wavetype is not supported currently, instead change wet/dry with this argument, defaults to 0.5`);
|
|
15120
|
+
w = 0.5;
|
|
15121
|
+
}
|
|
15122
|
+
this._fx.wet.setValueAtTime(w, time);
|
|
15123
|
+
}
|
|
15124
|
+
|
|
15125
|
+
this.chain = () => {
|
|
15126
|
+
return { 'send' : this._fx, 'return' : this._fx }
|
|
15127
|
+
}
|
|
15128
|
+
|
|
15129
|
+
this.delete = () => {
|
|
15130
|
+
this._fx.disconnect();
|
|
15131
|
+
this._fx.dispose();
|
|
15132
|
+
}
|
|
15133
|
+
}
|
|
15134
|
+
|
|
15135
|
+
|
|
15080
15136
|
// A distortion/compression effect of an incoming signal
|
|
15081
15137
|
// Based on an algorithm by Peter McCulloch
|
|
15082
15138
|
//
|
|
@@ -15179,9 +15235,11 @@ const LFO = function(_params){
|
|
|
15179
15235
|
rect : 'square',
|
|
15180
15236
|
triangle : 'triangle',
|
|
15181
15237
|
tri : 'triangle',
|
|
15238
|
+
up: 'sawtooth',
|
|
15239
|
+
sawUp: 'sawtooth'
|
|
15182
15240
|
}
|
|
15183
15241
|
|
|
15184
|
-
this._lfo = new Tone.LFO(
|
|
15242
|
+
this._lfo = new Tone.LFO();
|
|
15185
15243
|
this._fx = new Tone.Gain();
|
|
15186
15244
|
this._lfo.connect(this._fx.gain);
|
|
15187
15245
|
// this._fx = new Tone.Tremolo('8n').start();
|
|
@@ -15206,9 +15264,13 @@ const LFO = function(_params){
|
|
|
15206
15264
|
this._lfo.frequency.setValueAtTime(1/f, time);
|
|
15207
15265
|
|
|
15208
15266
|
let a = Util.getParam(this._depth, c);
|
|
15209
|
-
this._lfo.min = Math.min(1, Math.max(0, 1 - a));
|
|
15210
|
-
|
|
15211
|
-
|
|
15267
|
+
this._lfo.min = Math.min(1, Math.max(0, 1 - a));
|
|
15268
|
+
if (this._lfo.state !== 'started'){
|
|
15269
|
+
if (w === 'sawtooth') {
|
|
15270
|
+
this._lfo.phase = 180;
|
|
15271
|
+
}
|
|
15272
|
+
this._lfo.start(time);
|
|
15273
|
+
}
|
|
15212
15274
|
}
|
|
15213
15275
|
|
|
15214
15276
|
this.chain = function(){
|
|
@@ -15640,7 +15702,7 @@ class Instrument extends Sequencer {
|
|
|
15640
15702
|
this.panner.pan.setValueAtTime(p, time);
|
|
15641
15703
|
|
|
15642
15704
|
// ramp volume
|
|
15643
|
-
let g =
|
|
15705
|
+
let g = Util.atodb(Util.getParam(this._gain[0], c) * 0.707);
|
|
15644
15706
|
let r = Util.msToS(Math.max(0, Util.getParam(this._gain[1], c)));
|
|
15645
15707
|
this.source.volume.rampTo(g, r, time);
|
|
15646
15708
|
|
|
@@ -16159,6 +16221,7 @@ class MonoSynth extends Instrument {
|
|
|
16159
16221
|
// // synth specific variables;
|
|
16160
16222
|
this._note = [ 0, 0 ];
|
|
16161
16223
|
this._slide = [ 0 ];
|
|
16224
|
+
this._firstSlide = true;
|
|
16162
16225
|
this._voices = [ 1 ];
|
|
16163
16226
|
this._detune = [ 0 ];
|
|
16164
16227
|
|
|
@@ -16210,14 +16273,15 @@ class MonoSynth extends Instrument {
|
|
|
16210
16273
|
|
|
16211
16274
|
// get the slide time for next note and set the frequency
|
|
16212
16275
|
let s = Util.divToS(Util.getParam(this._slide, c), this.bpm());
|
|
16213
|
-
if (s > 0){
|
|
16276
|
+
if (s > 0 && !this._firstSlide){
|
|
16214
16277
|
this.synth.frequency.rampTo(f, s, time);
|
|
16215
16278
|
} else {
|
|
16216
16279
|
this.synth.frequency.setValueAtTime(f, time);
|
|
16280
|
+
this._firstSlide = false;
|
|
16217
16281
|
}
|
|
16218
16282
|
}
|
|
16219
16283
|
|
|
16220
|
-
super(
|
|
16284
|
+
super(v=[3], d=[0.111]){
|
|
16221
16285
|
// add unison voices and detune the spread
|
|
16222
16286
|
// first argument is the detune amount
|
|
16223
16287
|
// second argument changes the amount of voices
|
|
@@ -16225,11 +16289,6 @@ class MonoSynth extends Instrument {
|
|
|
16225
16289
|
this._detune = Util.toArray(d);
|
|
16226
16290
|
}
|
|
16227
16291
|
|
|
16228
|
-
fat(...a){
|
|
16229
|
-
// alias for super synth
|
|
16230
|
-
this.super(...a);
|
|
16231
|
-
}
|
|
16232
|
-
|
|
16233
16292
|
slide(s){
|
|
16234
16293
|
// portamento from one note to another
|
|
16235
16294
|
this._slide = Util.toArray(s);
|
|
@@ -16525,8 +16584,10 @@ class PolySample extends PolyInstrument {
|
|
|
16525
16584
|
// get the start position
|
|
16526
16585
|
let p = dur * Util.getParam(this._pos, c);
|
|
16527
16586
|
|
|
16528
|
-
// when sample is loaded
|
|
16529
|
-
this.sources[id].
|
|
16587
|
+
// when sample is loaded allow playback to start
|
|
16588
|
+
if (this.sources[id].loaded){
|
|
16589
|
+
this.sources[id].start(time, p);
|
|
16590
|
+
}
|
|
16530
16591
|
}
|
|
16531
16592
|
|
|
16532
16593
|
sound(s){
|
|
@@ -16607,6 +16668,7 @@ class PolySynth extends PolyInstrument {
|
|
|
16607
16668
|
this._wave = Util.toArray(t);
|
|
16608
16669
|
this._note = [ 0, 0 ];
|
|
16609
16670
|
this._slide = [ 0 ];
|
|
16671
|
+
this._firstSlide = [];
|
|
16610
16672
|
this._voices = [ 1 ];
|
|
16611
16673
|
this._detune = [ 0 ];
|
|
16612
16674
|
|
|
@@ -16620,6 +16682,7 @@ class PolySynth extends PolyInstrument {
|
|
|
16620
16682
|
this.sources[i] = new Tone.FatOscillator().connect(this.adsrs[i]);
|
|
16621
16683
|
this.sources[i].count = 1;
|
|
16622
16684
|
this.sources[i].start();
|
|
16685
|
+
this._firstSlide[i] = true;
|
|
16623
16686
|
}
|
|
16624
16687
|
}
|
|
16625
16688
|
|
|
@@ -16652,10 +16715,12 @@ class PolySynth extends PolyInstrument {
|
|
|
16652
16715
|
|
|
16653
16716
|
// get the slide time for next note and set the frequency
|
|
16654
16717
|
let s = Util.divToS(Util.getParam(this._slide, c), this.bpm());
|
|
16655
|
-
if (s > 0){
|
|
16718
|
+
if (s > 0 && !this._firstSlide[id]){
|
|
16656
16719
|
this.sources[id].frequency.rampTo(f, s, time);
|
|
16657
16720
|
} else {
|
|
16658
16721
|
this.sources[id].frequency.setValueAtTime(f, time);
|
|
16722
|
+
// first time the synth plays it doesn't slide!
|
|
16723
|
+
this._firstSlide[id] = false;
|
|
16659
16724
|
}
|
|
16660
16725
|
}
|
|
16661
16726
|
|
|
@@ -16665,7 +16730,7 @@ class PolySynth extends PolyInstrument {
|
|
|
16665
16730
|
this._note = [Util.toArray(i), Util.toArray(o)];
|
|
16666
16731
|
}
|
|
16667
16732
|
|
|
16668
|
-
super(
|
|
16733
|
+
super(v=[3], d=[0.1]){
|
|
16669
16734
|
// add unison voices and detune the spread
|
|
16670
16735
|
// first argument is the detune amount
|
|
16671
16736
|
// second argument changes the amount of voices
|
|
@@ -16673,11 +16738,6 @@ class PolySynth extends PolyInstrument {
|
|
|
16673
16738
|
this._detune = Util.toArray(d);
|
|
16674
16739
|
}
|
|
16675
16740
|
|
|
16676
|
-
fat(...a){
|
|
16677
|
-
// alias for super synth
|
|
16678
|
-
this.super(...a);
|
|
16679
|
-
}
|
|
16680
|
-
|
|
16681
16741
|
slide(s){
|
|
16682
16742
|
// portamento from one note to another
|
|
16683
16743
|
this._slide = Util.toArray(s);
|
|
@@ -16722,6 +16782,7 @@ class Sequencer {
|
|
|
16722
16782
|
// Tone looper
|
|
16723
16783
|
this._event;
|
|
16724
16784
|
this._loop;
|
|
16785
|
+
this._once = false;
|
|
16725
16786
|
this.makeLoop();
|
|
16726
16787
|
|
|
16727
16788
|
console.log('=> class Sequencer()');
|
|
@@ -16793,6 +16854,13 @@ class Sequencer {
|
|
|
16793
16854
|
}
|
|
16794
16855
|
// increment count for sequencing
|
|
16795
16856
|
this._count++;
|
|
16857
|
+
|
|
16858
|
+
// if the sample is set to only play once mute the loop
|
|
16859
|
+
// afterwards and dispose
|
|
16860
|
+
if (this._once){
|
|
16861
|
+
this._loop.mute = 1;
|
|
16862
|
+
this._loop.dispose();
|
|
16863
|
+
}
|
|
16796
16864
|
}
|
|
16797
16865
|
|
|
16798
16866
|
if (this._time){
|
|
@@ -16849,7 +16917,7 @@ class Sequencer {
|
|
|
16849
16917
|
this._loop.stop();
|
|
16850
16918
|
}
|
|
16851
16919
|
|
|
16852
|
-
time(t, o=0
|
|
16920
|
+
time(t, o=0){
|
|
16853
16921
|
// set the timing interval and offset
|
|
16854
16922
|
if (t === 'free'){
|
|
16855
16923
|
this._time = null;
|
|
@@ -16857,11 +16925,22 @@ class Sequencer {
|
|
|
16857
16925
|
} else {
|
|
16858
16926
|
this._time = Util.formatRatio(t, this.bpm());
|
|
16859
16927
|
this._offset = Util.formatRatio(o, this.bpm());
|
|
16860
|
-
// set timing division optionally, also possible via timediv()
|
|
16861
|
-
// this.timediv(s);
|
|
16862
16928
|
}
|
|
16863
16929
|
}
|
|
16864
16930
|
|
|
16931
|
+
once(o=0){
|
|
16932
|
+
// play the sample/synth/midi once or not?
|
|
16933
|
+
// the moment of playing is determined by the time and offset
|
|
16934
|
+
this._once = (o > 0 || o === 'on' || o === 'true') ? true : false;
|
|
16935
|
+
}
|
|
16936
|
+
|
|
16937
|
+
ratchet(p=1, s=[1]){
|
|
16938
|
+
// set the ratcheting probability and subdivision
|
|
16939
|
+
// for now defaults to the timediv method
|
|
16940
|
+
Util.log(`ratchet() is not yet supported. Defaults to timediv() with probability of 1`);
|
|
16941
|
+
this.timediv(s);
|
|
16942
|
+
}
|
|
16943
|
+
|
|
16865
16944
|
timediv(s){
|
|
16866
16945
|
// set timing subdivisions for the loop
|
|
16867
16946
|
let tmp = Util.toArray(s);
|
|
@@ -16910,6 +16989,22 @@ module.exports = Sequencer;
|
|
|
16910
16989
|
},{"./Util.js":66,"tone":44,"webmidi":55}],66:[function(require,module,exports){
|
|
16911
16990
|
const { noteToMidi, toScale, mtof } = require('total-serialism').Translate;
|
|
16912
16991
|
|
|
16992
|
+
// replace defaults with incoming parameters
|
|
16993
|
+
function mapDefaults(params, defaults){
|
|
16994
|
+
defaults.splice(0, params.length, ...params);
|
|
16995
|
+
return defaults.map(p => toArray(p));
|
|
16996
|
+
}
|
|
16997
|
+
|
|
16998
|
+
// convert amplitude to dBFS scale
|
|
16999
|
+
function atodb(a=0){
|
|
17000
|
+
return 20 * Math.log(a);
|
|
17001
|
+
}
|
|
17002
|
+
|
|
17003
|
+
// convert dbFS to amplitude
|
|
17004
|
+
function dbtoa(db=0){
|
|
17005
|
+
return 10 ** (db/20);
|
|
17006
|
+
}
|
|
17007
|
+
|
|
16913
17008
|
// clip a value between a specified range
|
|
16914
17009
|
function clip(v, l, h){
|
|
16915
17010
|
return Math.max(l, Math.min(h, v));
|
|
@@ -17035,6 +17130,11 @@ function divToS(d, bpm){
|
|
|
17035
17130
|
}
|
|
17036
17131
|
}
|
|
17037
17132
|
|
|
17133
|
+
// convert division format to frequency in Hz based on bpm
|
|
17134
|
+
function divToF(d, bpm){
|
|
17135
|
+
return 1.0 / divToS(d, bpm)
|
|
17136
|
+
}
|
|
17137
|
+
|
|
17038
17138
|
// convert note value to a frequency
|
|
17039
17139
|
function noteToFreq(i, o){
|
|
17040
17140
|
if (isNaN(i)){
|
|
@@ -17103,7 +17203,7 @@ function log(msg){
|
|
|
17103
17203
|
}
|
|
17104
17204
|
}
|
|
17105
17205
|
|
|
17106
|
-
module.exports = { clip, assureNum, lookup, randLookup, isRandom, getParam, toArray, msToS, formatRatio, divToS, toMidi, mtof, noteToMidi, noteToFreq, assureWave, log }
|
|
17206
|
+
module.exports = { mapDefaults, atodb, dbtoa, clip, assureNum, lookup, randLookup, isRandom, getParam, toArray, msToS, formatRatio, divToS, divToF, toMidi, mtof, noteToMidi, noteToFreq, assureWave, log }
|
|
17107
17207
|
},{"total-serialism":47}],67:[function(require,module,exports){
|
|
17108
17208
|
module.exports={
|
|
17109
17209
|
"uptempo" : 10,
|
|
@@ -17322,6 +17422,12 @@ class MercuryInterpreter {
|
|
|
17322
17422
|
'lowPass' : (args) => {
|
|
17323
17423
|
this.setLowPass(...args);
|
|
17324
17424
|
// engine.setLowPass(...args);
|
|
17425
|
+
},
|
|
17426
|
+
'samples' : (args) => {
|
|
17427
|
+
// load samples in the audiobuffer
|
|
17428
|
+
// this can be a single url to a soundfile
|
|
17429
|
+
// or a url to a folder that will be searched through
|
|
17430
|
+
this.addBuffers(args);
|
|
17325
17431
|
}
|
|
17326
17432
|
}
|
|
17327
17433
|
|
|
@@ -17490,6 +17596,9 @@ class Mercury extends MercuryInterpreter {
|
|
|
17490
17596
|
this.highPassF = new Tone.Filter(5, 'highpass');
|
|
17491
17597
|
Tone.Destination.chain(this.lowPassF, this.highPassF, this.gain);
|
|
17492
17598
|
|
|
17599
|
+
// an RMS meter for reactive visuals
|
|
17600
|
+
this.meter;
|
|
17601
|
+
|
|
17493
17602
|
// a recorder for the sound
|
|
17494
17603
|
this.recorder = new Tone.Recorder({ mimeType: 'audio/webm' });
|
|
17495
17604
|
this.gain.connect(this.recorder);
|
|
@@ -17587,8 +17696,9 @@ class Mercury extends MercuryInterpreter {
|
|
|
17587
17696
|
// set the bpm and optionally ramp in milliseconds
|
|
17588
17697
|
setBPM(bpm, ramp=0) {
|
|
17589
17698
|
this.bpm = bpm;
|
|
17590
|
-
|
|
17591
|
-
|
|
17699
|
+
let t = Util.divToS(ramp, bpm);
|
|
17700
|
+
if (t > 0){
|
|
17701
|
+
Tone.Transport.bpm.rampTo(bpm, t);
|
|
17592
17702
|
} else {
|
|
17593
17703
|
Tone.Transport.bpm.setValueAtTime(bpm, Tone.now());
|
|
17594
17704
|
}
|
|
@@ -17705,31 +17815,34 @@ class Mercury extends MercuryInterpreter {
|
|
|
17705
17815
|
|
|
17706
17816
|
// set lowpass frequency cutoff and ramptime
|
|
17707
17817
|
setLowPass(f, t=0){
|
|
17708
|
-
this.lowPass = f;
|
|
17818
|
+
this.lowPass = (f === 'default')? 18000 : f;
|
|
17819
|
+
t = Util.divToS(t, this.bpm);
|
|
17709
17820
|
if (t > 0){
|
|
17710
|
-
this.lowPassF.frequency.rampTo(
|
|
17821
|
+
this.lowPassF.frequency.rampTo(this.lowPass, t, Tone.now());
|
|
17711
17822
|
} else {
|
|
17712
|
-
this.lowPassF.frequency.setValueAtTime(
|
|
17823
|
+
this.lowPassF.frequency.setValueAtTime(this.lowPass, Tone.now());
|
|
17713
17824
|
}
|
|
17714
17825
|
}
|
|
17715
17826
|
|
|
17716
17827
|
// set highpass frequency cutoff and ramptime
|
|
17717
17828
|
setHighPass(f, t=0){
|
|
17718
|
-
this.highPass = f;
|
|
17829
|
+
this.highPass = (f === 'default')? 5 : f;
|
|
17830
|
+
t = Util.divToS(t, this.bpm);
|
|
17719
17831
|
if (t > 0){
|
|
17720
|
-
this.highPassF.frequency.rampTo(
|
|
17832
|
+
this.highPassF.frequency.rampTo(this.highPass, t, Tone.now());
|
|
17721
17833
|
} else {
|
|
17722
|
-
this.highPassF.frequency.setValueAtTime(
|
|
17834
|
+
this.highPassF.frequency.setValueAtTime(this.highPass, Tone.now());
|
|
17723
17835
|
}
|
|
17724
17836
|
}
|
|
17725
17837
|
|
|
17726
17838
|
// set volume in floatingpoint and ramptime
|
|
17727
17839
|
setVolume(v, t=0){
|
|
17728
|
-
this.volume = v;
|
|
17840
|
+
this.volume = (v === 'default')? 1 : v;
|
|
17841
|
+
t = Util.divToS(t, this.bpm);
|
|
17729
17842
|
if (t > 0){
|
|
17730
|
-
this.gain.gain.rampTo(
|
|
17843
|
+
this.gain.gain.rampTo(this.volume, t, Tone.now());
|
|
17731
17844
|
} else {
|
|
17732
|
-
this.gain.gain.setValueAtTime(
|
|
17845
|
+
this.gain.gain.setValueAtTime(this.volume, Tone.now());
|
|
17733
17846
|
}
|
|
17734
17847
|
}
|
|
17735
17848
|
|
|
@@ -17765,6 +17878,28 @@ class Mercury extends MercuryInterpreter {
|
|
|
17765
17878
|
isRecording(){
|
|
17766
17879
|
return this.recorder.state;
|
|
17767
17880
|
}
|
|
17881
|
+
|
|
17882
|
+
// add a Tone RMS meter to use for signal analysis
|
|
17883
|
+
addMeter(smooth=0.7){
|
|
17884
|
+
this.meter = new Tone.Meter(smooth);
|
|
17885
|
+
this.meter.normalRange = true;
|
|
17886
|
+
this.gain.connect(this.meter);
|
|
17887
|
+
}
|
|
17888
|
+
|
|
17889
|
+
// return the meter value as float betwee 0-1
|
|
17890
|
+
getMeter(){
|
|
17891
|
+
return this.meter.getValue();
|
|
17892
|
+
}
|
|
17893
|
+
|
|
17894
|
+
// get the webaudio context Mercury is producing sound on
|
|
17895
|
+
// getContext(){
|
|
17896
|
+
// return Tone.getContext();
|
|
17897
|
+
// }
|
|
17898
|
+
|
|
17899
|
+
// get the destination output Mercury is sending sound to
|
|
17900
|
+
// getDestination(){
|
|
17901
|
+
// return Tone.getDestination();
|
|
17902
|
+
// }
|
|
17768
17903
|
}
|
|
17769
17904
|
module.exports = { Mercury };
|
|
17770
17905
|
},{"./core/Util.js":66,"./interpreter":68,"tone":44,"webmidi":55}]},{},[69])(69)
|