mercury-engine 1.0.8 → 1.1.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/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
- return new PitchShift(params);
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
- return new FreeVerb(params);
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('8n', 0, 1);
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
- this._lfo.start(time);
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 = 20 * Math.log(Util.getParam(this._gain[0], c) * 0.707);
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(d=[0.1], v=[3]){
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, start
16529
- this.sources[id].start(time, p);
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(d=[0.1], v=[3]){
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, s=[1]){
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,17 @@ 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
+
16913
17003
  // clip a value between a specified range
16914
17004
  function clip(v, l, h){
16915
17005
  return Math.max(l, Math.min(h, v));
@@ -17035,6 +17125,11 @@ function divToS(d, bpm){
17035
17125
  }
17036
17126
  }
17037
17127
 
17128
+ // convert division format to frequency in Hz based on bpm
17129
+ function divToF(d, bpm){
17130
+ return 1.0 / divToS(d, bpm)
17131
+ }
17132
+
17038
17133
  // convert note value to a frequency
17039
17134
  function noteToFreq(i, o){
17040
17135
  if (isNaN(i)){
@@ -17103,7 +17198,7 @@ function log(msg){
17103
17198
  }
17104
17199
  }
17105
17200
 
17106
- module.exports = { clip, assureNum, lookup, randLookup, isRandom, getParam, toArray, msToS, formatRatio, divToS, toMidi, mtof, noteToMidi, noteToFreq, assureWave, log }
17201
+ module.exports = { mapDefaults, atodb, clip, assureNum, lookup, randLookup, isRandom, getParam, toArray, msToS, formatRatio, divToS, divToF, toMidi, mtof, noteToMidi, noteToFreq, assureWave, log }
17107
17202
  },{"total-serialism":47}],67:[function(require,module,exports){
17108
17203
  module.exports={
17109
17204
  "uptempo" : 10,
@@ -17322,6 +17417,12 @@ class MercuryInterpreter {
17322
17417
  'lowPass' : (args) => {
17323
17418
  this.setLowPass(...args);
17324
17419
  // engine.setLowPass(...args);
17420
+ },
17421
+ 'samples' : (args) => {
17422
+ // load samples in the audiobuffer
17423
+ // this can be a single url to a soundfile
17424
+ // or a url to a folder that will be searched through
17425
+ this.addBuffers(args);
17325
17426
  }
17326
17427
  }
17327
17428
 
@@ -17389,7 +17490,7 @@ class MercuryInterpreter {
17389
17490
 
17390
17491
  // if silenced break out of everything
17391
17492
  if (this.silenced){
17392
- return;
17493
+ return this.parse;
17393
17494
  }
17394
17495
 
17395
17496
  // copy current sounds over to past
@@ -17587,8 +17688,9 @@ class Mercury extends MercuryInterpreter {
17587
17688
  // set the bpm and optionally ramp in milliseconds
17588
17689
  setBPM(bpm, ramp=0) {
17589
17690
  this.bpm = bpm;
17590
- if (ramp > 0){
17591
- Tone.Transport.bpm.rampTo(bpm, ramp / 1000);
17691
+ let t = Util.divToS(ramp, bpm);
17692
+ if (t > 0){
17693
+ Tone.Transport.bpm.rampTo(bpm, t);
17592
17694
  } else {
17593
17695
  Tone.Transport.bpm.setValueAtTime(bpm, Tone.now());
17594
17696
  }
@@ -17705,31 +17807,34 @@ class Mercury extends MercuryInterpreter {
17705
17807
 
17706
17808
  // set lowpass frequency cutoff and ramptime
17707
17809
  setLowPass(f, t=0){
17708
- this.lowPass = f;
17810
+ this.lowPass = (f === 'default')? 18000 : f;
17811
+ t = Util.divToS(t, this.bpm);
17709
17812
  if (t > 0){
17710
- this.lowPassF.frequency.rampTo(f, t/1000, Tone.now());
17813
+ this.lowPassF.frequency.rampTo(this.lowPass, t, Tone.now());
17711
17814
  } else {
17712
- this.lowPassF.frequency.setValueAtTime(f, Tone.now());
17815
+ this.lowPassF.frequency.setValueAtTime(this.lowPass, Tone.now());
17713
17816
  }
17714
17817
  }
17715
17818
 
17716
17819
  // set highpass frequency cutoff and ramptime
17717
17820
  setHighPass(f, t=0){
17718
- this.highPass = f;
17821
+ this.highPass = (f === 'default')? 5 : f;
17822
+ t = Util.divToS(t, this.bpm);
17719
17823
  if (t > 0){
17720
- this.highPassF.frequency.rampTo(f, t/1000, Tone.now());
17824
+ this.highPassF.frequency.rampTo(this.highPass, t, Tone.now());
17721
17825
  } else {
17722
- this.highPassF.frequency.setValueAtTime(f, Tone.now());
17826
+ this.highPassF.frequency.setValueAtTime(this.highPass, Tone.now());
17723
17827
  }
17724
17828
  }
17725
17829
 
17726
17830
  // set volume in floatingpoint and ramptime
17727
17831
  setVolume(v, t=0){
17728
- this.volume = v;
17832
+ this.volume = (v === 'default')? 1 : v;
17833
+ t = Util.divToS(t, this.bpm);
17729
17834
  if (t > 0){
17730
- this.gain.gain.rampTo(v, t/1000, Tone.now());
17835
+ this.gain.gain.rampTo(this.volume, t, Tone.now());
17731
17836
  } else {
17732
- this.gain.gain.setValueAtTime(v, Tone.now());
17837
+ this.gain.gain.setValueAtTime(this.volume, Tone.now());
17733
17838
  }
17734
17839
  }
17735
17840