mercury-engine 1.0.2 → 1.0.4
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 +192 -27
- package/dist/mercury.js +174 -87
- package/dist/mercury.min.es5.js +2 -2
- package/dist/mercury.min.js +1 -1
- package/examples/basic/index.html +25 -19
- package/examples/interface/index.html +87 -0
- package/examples/midi/index.html +68 -0
- package/examples/samples/freesound-samples.json +6 -0
- package/examples/samples/samples-freesound.html +74 -0
- package/examples/samples/samples-from-json.html +79 -0
- package/package.json +1 -1
package/dist/mercury.js
CHANGED
|
@@ -15195,7 +15195,7 @@ const LFO = function(_params){
|
|
|
15195
15195
|
if (this._waveMap[w]){
|
|
15196
15196
|
w = this._waveMap[w];
|
|
15197
15197
|
} else {
|
|
15198
|
-
|
|
15198
|
+
Util.log(`'${w} is not a valid waveshape`);
|
|
15199
15199
|
// default wave if wave does not exist
|
|
15200
15200
|
w = 'sine';
|
|
15201
15201
|
}
|
|
@@ -15244,7 +15244,7 @@ const Filter = function(_params){
|
|
|
15244
15244
|
if (this._types[_params[0]]){
|
|
15245
15245
|
this._fx.set({ type: this._types[_params[0]] });
|
|
15246
15246
|
} else {
|
|
15247
|
-
|
|
15247
|
+
Util.log(`'${_params[0]}' is not a valid filter type`);
|
|
15248
15248
|
this._fx.set({ type: 'lowpass' });
|
|
15249
15249
|
}
|
|
15250
15250
|
this._fx.set({ rolloff: -24 });
|
|
@@ -15318,7 +15318,7 @@ const TriggerFilter = function(_params){
|
|
|
15318
15318
|
if (this._types[_params[0][0]]){
|
|
15319
15319
|
this._fx.set({ type: this._types[_params[0][0]] });
|
|
15320
15320
|
} else {
|
|
15321
|
-
|
|
15321
|
+
Util.log(`'${_params[0][0]}' is not a valid filter type. Defaulting to lowpass`);
|
|
15322
15322
|
this._fx.set({ type: 'lowpass' });
|
|
15323
15323
|
}
|
|
15324
15324
|
|
|
@@ -15758,7 +15758,7 @@ class Instrument extends Sequencer {
|
|
|
15758
15758
|
let tmpF = fxMap[f[0]](f.slice(1));
|
|
15759
15759
|
this._fx.push(tmpF);
|
|
15760
15760
|
} else {
|
|
15761
|
-
log(`Effect ${f[0]} does not exist`);
|
|
15761
|
+
Util.log(`Effect ${f[0]} does not exist`);
|
|
15762
15762
|
}
|
|
15763
15763
|
});
|
|
15764
15764
|
// if any fx working
|
|
@@ -15789,6 +15789,7 @@ module.exports = Instrument;
|
|
|
15789
15789
|
},{"./Effects.js":56,"./Sequencer.js":65,"./Util.js":66,"tone":44}],58:[function(require,module,exports){
|
|
15790
15790
|
const Tone = require('tone');
|
|
15791
15791
|
const Instrument = require('./Instrument.js');
|
|
15792
|
+
const Util = require('./Util.js');
|
|
15792
15793
|
|
|
15793
15794
|
class MonoInput extends Instrument {
|
|
15794
15795
|
constructor(engine, d, canvas){
|
|
@@ -15799,7 +15800,7 @@ class MonoInput extends Instrument {
|
|
|
15799
15800
|
} else if (d.match(/in(\d+)/g)){
|
|
15800
15801
|
this._device = Number(d.match(/in(\d+)/)[1]);
|
|
15801
15802
|
} else {
|
|
15802
|
-
|
|
15803
|
+
Util.log(`${d} is not a valid microphone input. defaults to in0`);
|
|
15803
15804
|
this._device = 0;
|
|
15804
15805
|
}
|
|
15805
15806
|
|
|
@@ -15812,9 +15813,9 @@ class MonoInput extends Instrument {
|
|
|
15812
15813
|
createSource(){
|
|
15813
15814
|
this.mic = new Tone.UserMedia().connect(this.channelStrip());
|
|
15814
15815
|
this.mic.open(this._device).then(() => {
|
|
15815
|
-
|
|
15816
|
+
Util.log(`Opened microphone: ${window.devices[this._device]}`);
|
|
15816
15817
|
}).catch((e) => {
|
|
15817
|
-
|
|
15818
|
+
Util.log(`Unable to use microphone`);
|
|
15818
15819
|
});
|
|
15819
15820
|
this.mic.channelInterpretation = 'discrete';
|
|
15820
15821
|
|
|
@@ -15837,11 +15838,11 @@ class MonoInput extends Instrument {
|
|
|
15837
15838
|
}
|
|
15838
15839
|
}
|
|
15839
15840
|
module.exports = MonoInput;
|
|
15840
|
-
},{"./Instrument.js":57,"tone":44}],59:[function(require,module,exports){
|
|
15841
|
+
},{"./Instrument.js":57,"./Util.js":66,"tone":44}],59:[function(require,module,exports){
|
|
15841
15842
|
const Tone = require('tone');
|
|
15842
15843
|
const Util = require('./Util.js');
|
|
15843
15844
|
const Sequencer = require('./Sequencer.js');
|
|
15844
|
-
const WebMidi = require("webmidi");
|
|
15845
|
+
const { WebMidi } = require("webmidi");
|
|
15845
15846
|
|
|
15846
15847
|
class MonoMidi extends Sequencer {
|
|
15847
15848
|
constructor(engine, d='default', canvas){
|
|
@@ -15852,7 +15853,7 @@ class MonoMidi extends Sequencer {
|
|
|
15852
15853
|
if (d === 'default'){
|
|
15853
15854
|
this._device = WebMidi.outputs[0];
|
|
15854
15855
|
} else if (!this._device){
|
|
15855
|
-
|
|
15856
|
+
Util.log(`${d} is not a valid MIDI Device name, set to default`);
|
|
15856
15857
|
this._device = WebMidi.outputs[0];
|
|
15857
15858
|
}
|
|
15858
15859
|
|
|
@@ -15919,8 +15920,8 @@ class MonoMidi extends Sequencer {
|
|
|
15919
15920
|
n[x] = Util.toMidi(i[x], o);
|
|
15920
15921
|
}
|
|
15921
15922
|
|
|
15922
|
-
// play the note(s)!
|
|
15923
|
-
this._device.playNote(n, ch, { duration: d,
|
|
15923
|
+
// play the note(s)! updated for webmidi 3.x
|
|
15924
|
+
this._device.playNote(n, ch, { duration: d, attack: g, time: sync });
|
|
15924
15925
|
|
|
15925
15926
|
// }
|
|
15926
15927
|
}
|
|
@@ -15959,7 +15960,7 @@ class MonoMidi extends Sequencer {
|
|
|
15959
15960
|
this._cc = [];
|
|
15960
15961
|
cc.forEach((c) => {
|
|
15961
15962
|
if (isNaN(c[0])){
|
|
15962
|
-
|
|
15963
|
+
Util.log(`'${c[0]}' is not a valid CC number`);
|
|
15963
15964
|
} else {
|
|
15964
15965
|
let cc = [];
|
|
15965
15966
|
cc[0] = c[0];
|
|
@@ -16084,7 +16085,7 @@ class MonoSample extends Instrument {
|
|
|
16084
16085
|
// error if soundfile does not exist
|
|
16085
16086
|
else if (!this._bufs.has(s)){
|
|
16086
16087
|
// set default (or an ampty soundfile?)
|
|
16087
|
-
|
|
16088
|
+
Util.log(`sample ${s} not found`);
|
|
16088
16089
|
return 'kick_909';
|
|
16089
16090
|
}
|
|
16090
16091
|
return s;
|
|
@@ -16191,7 +16192,7 @@ class MonoSynth extends Instrument {
|
|
|
16191
16192
|
if (this._waveMap[w]){
|
|
16192
16193
|
w = this._waveMap[w];
|
|
16193
16194
|
} else {
|
|
16194
|
-
|
|
16195
|
+
Util.log(`${w} is not a valid waveshape`);
|
|
16195
16196
|
// default wave if wave does not exist
|
|
16196
16197
|
w = 'sine';
|
|
16197
16198
|
}
|
|
@@ -16387,7 +16388,7 @@ class PolyInstrument extends Instrument {
|
|
|
16387
16388
|
}
|
|
16388
16389
|
|
|
16389
16390
|
voices(v){
|
|
16390
|
-
|
|
16391
|
+
Util.log(`Changing voice amount is not yet supported. You can use voice-stealing with steal(on)`);
|
|
16391
16392
|
// TODO change voice amount
|
|
16392
16393
|
// set the voiceamount for the polyphonic synth
|
|
16393
16394
|
// this.numVoices = Math.max(1, isNaN(Number(v))? 6 : Number(v));
|
|
@@ -16402,7 +16403,7 @@ class PolyInstrument extends Instrument {
|
|
|
16402
16403
|
} else if (s === 'off' || s == 0){
|
|
16403
16404
|
this._steal = false;
|
|
16404
16405
|
} else {
|
|
16405
|
-
|
|
16406
|
+
Util.log(`${s} is not a valid argument for steal()`);
|
|
16406
16407
|
}
|
|
16407
16408
|
}
|
|
16408
16409
|
|
|
@@ -16543,7 +16544,7 @@ class PolySample extends PolyInstrument {
|
|
|
16543
16544
|
// error if soundfile does not exist
|
|
16544
16545
|
else if (!this._bufs.has(s)){
|
|
16545
16546
|
// set default (or an ampty soundfile?)
|
|
16546
|
-
|
|
16547
|
+
Util.log(`sample ${s} not found`);
|
|
16547
16548
|
return 'kick_909';
|
|
16548
16549
|
}
|
|
16549
16550
|
return s;
|
|
@@ -16960,7 +16961,7 @@ function getOSC(a){
|
|
|
16960
16961
|
return a;
|
|
16961
16962
|
} else if (osc.match(/^\/[^`'"\s]+/g)){
|
|
16962
16963
|
if (!window.oscMessages[osc]){
|
|
16963
|
-
|
|
16964
|
+
log(`No message received on address ${osc}`);
|
|
16964
16965
|
return [0];
|
|
16965
16966
|
}
|
|
16966
16967
|
return window.oscMessages[osc];
|
|
@@ -16993,7 +16994,7 @@ function evalExpr(a){
|
|
|
16993
16994
|
try {
|
|
16994
16995
|
result = eval(expr);
|
|
16995
16996
|
} catch (e){
|
|
16996
|
-
|
|
16997
|
+
log(`Unable to evaluate expression: ${expr}`);
|
|
16997
16998
|
}
|
|
16998
16999
|
return result;
|
|
16999
17000
|
}
|
|
@@ -17018,8 +17019,7 @@ function formatRatio(d, bpm){
|
|
|
17018
17019
|
} else if (!isNaN(Number(d))){
|
|
17019
17020
|
return Number(d) * 4.0 * 60 / bpm;
|
|
17020
17021
|
} else {
|
|
17021
|
-
|
|
17022
|
-
console.log(`${d} is not a valid time value`);
|
|
17022
|
+
log(`${d} is not a valid time value`);
|
|
17023
17023
|
return 60 / bpm;
|
|
17024
17024
|
}
|
|
17025
17025
|
}
|
|
@@ -17031,7 +17031,7 @@ function divToS(d, bpm){
|
|
|
17031
17031
|
} else if (!isNaN(Number(d))){
|
|
17032
17032
|
return Number(d) / 1000;
|
|
17033
17033
|
} else {
|
|
17034
|
-
|
|
17034
|
+
log(`${d} is not a valid time value`);
|
|
17035
17035
|
return 0.1;
|
|
17036
17036
|
}
|
|
17037
17037
|
}
|
|
@@ -17041,7 +17041,7 @@ function noteToFreq(i, o){
|
|
|
17041
17041
|
if (isNaN(i)){
|
|
17042
17042
|
let _i = noteToMidi(i);
|
|
17043
17043
|
if (!_i){
|
|
17044
|
-
|
|
17044
|
+
log(`${i} is not a valid number or name`);
|
|
17045
17045
|
i = 0;
|
|
17046
17046
|
} else {
|
|
17047
17047
|
i = _i - 48;
|
|
@@ -17072,7 +17072,7 @@ function assureWave(w){
|
|
|
17072
17072
|
if (waveMap[w]){
|
|
17073
17073
|
w = waveMap[w];
|
|
17074
17074
|
} else {
|
|
17075
|
-
|
|
17075
|
+
log(`${w} is not a valid waveshape`);
|
|
17076
17076
|
// default wave if wave does not exist
|
|
17077
17077
|
w = 'sine';
|
|
17078
17078
|
}
|
|
@@ -17084,7 +17084,7 @@ function toMidi(n=0, o=0){
|
|
|
17084
17084
|
if (isNaN(n)){
|
|
17085
17085
|
let _n = noteToMidi(n);
|
|
17086
17086
|
if (!_n){
|
|
17087
|
-
|
|
17087
|
+
log(`${n} is not a valid number or name`);
|
|
17088
17088
|
n = 0;
|
|
17089
17089
|
} else {
|
|
17090
17090
|
n = _n - 36;
|
|
@@ -17093,7 +17093,18 @@ function toMidi(n=0, o=0){
|
|
|
17093
17093
|
return toScale(n + o * 12 + 36);
|
|
17094
17094
|
}
|
|
17095
17095
|
|
|
17096
|
-
|
|
17096
|
+
// the log message is used to log to the console but also
|
|
17097
|
+
// sends a custom event that can be listened for to print the
|
|
17098
|
+
// content at some other place in the window, for example using a div
|
|
17099
|
+
function log(msg){
|
|
17100
|
+
console.log(msg);
|
|
17101
|
+
if (window){
|
|
17102
|
+
let print = new CustomEvent('mercuryLog', { detail: msg });
|
|
17103
|
+
window.dispatchEvent(print);
|
|
17104
|
+
}
|
|
17105
|
+
}
|
|
17106
|
+
|
|
17107
|
+
module.exports = { clip, assureNum, lookup, randLookup, isRandom, getParam, toArray, msToS, formatRatio, divToS, toMidi, mtof, noteToMidi, noteToFreq, assureWave, log }
|
|
17097
17108
|
},{"total-serialism":47}],67:[function(require,module,exports){
|
|
17098
17109
|
module.exports={
|
|
17099
17110
|
"uptempo" : 10,
|
|
@@ -17120,7 +17131,7 @@ module.exports={
|
|
|
17120
17131
|
const Tone = require('tone');
|
|
17121
17132
|
const Mercury = require('mercury-lang');
|
|
17122
17133
|
const TL = require('total-serialism').Translate;
|
|
17123
|
-
const
|
|
17134
|
+
const { normalize, multiply } = require('total-serialism').Utility;
|
|
17124
17135
|
|
|
17125
17136
|
const MonoSample = require('./core/MonoSample.js');
|
|
17126
17137
|
const MonoMidi = require('./core/MonoMidi.js');
|
|
@@ -17129,11 +17140,12 @@ const MonoInput = require('./core/MonoInput.js');
|
|
|
17129
17140
|
const PolySynth = require('./core/PolySynth.js');
|
|
17130
17141
|
const PolySample = require('./core/PolySample.js');
|
|
17131
17142
|
const Tempos = require('./data/genre-tempos.json');
|
|
17143
|
+
const Util = require('./core/Util.js');
|
|
17132
17144
|
|
|
17133
17145
|
class MercuryInterpreter {
|
|
17134
17146
|
constructor({ hydra, p5canvas } = {}){
|
|
17135
17147
|
// cross-fade time
|
|
17136
|
-
this.crossFade
|
|
17148
|
+
this.crossFade;
|
|
17137
17149
|
|
|
17138
17150
|
// arrays with the current and previous instruments for crossfade
|
|
17139
17151
|
this._sounds = [];
|
|
@@ -17173,34 +17185,45 @@ class MercuryInterpreter {
|
|
|
17173
17185
|
startSounds(s, f=0){
|
|
17174
17186
|
// fade in new sounds
|
|
17175
17187
|
s.map((_s) => {
|
|
17176
|
-
_s.fadeIn(f);
|
|
17188
|
+
if (_s){ _s.fadeIn(f); }
|
|
17177
17189
|
});
|
|
17178
17190
|
}
|
|
17179
17191
|
|
|
17180
17192
|
removeSounds(s, f=0) {
|
|
17181
17193
|
// fade out and delete after fade
|
|
17182
17194
|
s.map((_s) => {
|
|
17183
|
-
_s.fadeOut(f);
|
|
17195
|
+
if (_s){ _s.fadeOut(f); }
|
|
17184
17196
|
});
|
|
17185
17197
|
// empty array to trigger garbage collection
|
|
17186
17198
|
s.length = 0;
|
|
17187
17199
|
}
|
|
17188
17200
|
|
|
17201
|
+
makeLoops(s){
|
|
17202
|
+
// make the loops for all the instruments
|
|
17203
|
+
s.map((_s) => {
|
|
17204
|
+
if (_s){ _s.makeLoop(); }
|
|
17205
|
+
});
|
|
17206
|
+
}
|
|
17207
|
+
|
|
17189
17208
|
setCrossFade(f){
|
|
17190
17209
|
// set the crossFade in milliseconds
|
|
17191
17210
|
this.crossFade = Number(f) / 1000;
|
|
17192
|
-
|
|
17211
|
+
Util.log(`Crossfade set to: ${f}ms`);
|
|
17212
|
+
}
|
|
17213
|
+
|
|
17214
|
+
getCode(){
|
|
17215
|
+
// return the last evaluated code
|
|
17216
|
+
return this._code;
|
|
17193
17217
|
}
|
|
17194
17218
|
|
|
17195
17219
|
code(file=''){
|
|
17196
17220
|
// parse and evaluate the inputted code
|
|
17197
|
-
// as an asyncronous function with promise
|
|
17198
17221
|
let c = (!file)? this._code : file;
|
|
17199
|
-
this._code = c;
|
|
17200
|
-
|
|
17201
|
-
let t = Tone.Transport.seconds;
|
|
17202
17222
|
|
|
17223
|
+
let t = Tone.Transport.seconds;
|
|
17224
|
+
|
|
17203
17225
|
// is this necessary?
|
|
17226
|
+
// as an asyncronous function with promise
|
|
17204
17227
|
// let parser = new Promise((resolve) => {
|
|
17205
17228
|
// return resolve(Mercury(c));
|
|
17206
17229
|
// });
|
|
@@ -17216,18 +17239,19 @@ class MercuryInterpreter {
|
|
|
17216
17239
|
// l.innerHTML = '';
|
|
17217
17240
|
// handle .print and .errors
|
|
17218
17241
|
this.errors.forEach((e) => {
|
|
17219
|
-
|
|
17220
|
-
// log(e);
|
|
17242
|
+
Util.log(e);
|
|
17221
17243
|
});
|
|
17222
17244
|
if (this.errors.length > 0){
|
|
17223
17245
|
// return if the code contains any syntax errors
|
|
17224
|
-
|
|
17225
|
-
|
|
17246
|
+
Util.log(`Could not run because of syntax error`);
|
|
17247
|
+
Util.log(`Please see Help for more information`);
|
|
17226
17248
|
return;
|
|
17227
17249
|
}
|
|
17250
|
+
// if no errors the last evaluated code is stored
|
|
17251
|
+
this._code = c;
|
|
17228
17252
|
|
|
17229
17253
|
this.tree.print.forEach((p) => {
|
|
17230
|
-
|
|
17254
|
+
Util.log(p);
|
|
17231
17255
|
});
|
|
17232
17256
|
|
|
17233
17257
|
// set timer to check evaluation time
|
|
@@ -17244,7 +17268,7 @@ class MercuryInterpreter {
|
|
|
17244
17268
|
if (isNaN(t)){
|
|
17245
17269
|
t = Tempos[args[0].toLowerCase()];
|
|
17246
17270
|
if (t === undefined){
|
|
17247
|
-
|
|
17271
|
+
Util.log(`tempo ${args[0]} is not a valid genre or number`);
|
|
17248
17272
|
return;
|
|
17249
17273
|
}
|
|
17250
17274
|
args[0] = t;
|
|
@@ -17274,16 +17298,15 @@ class MercuryInterpreter {
|
|
|
17274
17298
|
if (s.indexOf(scl) > -1){
|
|
17275
17299
|
TL.setScale(scl);
|
|
17276
17300
|
} else {
|
|
17277
|
-
|
|
17301
|
+
Util.log(`${scl} is not a valid scale`);
|
|
17278
17302
|
}
|
|
17279
17303
|
if (rt){
|
|
17280
17304
|
TL.setRoot(rt);
|
|
17281
17305
|
}
|
|
17282
|
-
|
|
17283
|
-
let
|
|
17284
|
-
let tmpR = TL.getScale().root;
|
|
17306
|
+
// let tmpS = TL.getScale().scale;
|
|
17307
|
+
// let tmpR = TL.getScale().root;
|
|
17285
17308
|
// document.getElementById('scale').innerHTML = `scale = ${tmpR} ${tmpS}`;
|
|
17286
|
-
// log(`set scale to ${tmpR} ${tmpS}`);
|
|
17309
|
+
// Util.log(`set scale to ${tmpR} ${tmpS}`);
|
|
17287
17310
|
},
|
|
17288
17311
|
'amp' : (args) => {
|
|
17289
17312
|
this.setVolume(...args);
|
|
@@ -17328,6 +17351,10 @@ class MercuryInterpreter {
|
|
|
17328
17351
|
return inst;
|
|
17329
17352
|
},
|
|
17330
17353
|
'midi' : (obj) => {
|
|
17354
|
+
if (!this.midi.enabled){
|
|
17355
|
+
Util.log(`WebMIDI is not started. Please load the package and check your browser compatibility`);
|
|
17356
|
+
return null;
|
|
17357
|
+
}
|
|
17331
17358
|
let inst = new MonoMidi(this, obj.type, this.canvas);
|
|
17332
17359
|
objectMap.applyFunctions(obj.functions, inst, obj.type);
|
|
17333
17360
|
return inst;
|
|
@@ -17368,18 +17395,15 @@ class MercuryInterpreter {
|
|
|
17368
17395
|
if (objectMap[type]){
|
|
17369
17396
|
this.sounds.push(objectMap[type](this.tree.objects[o]));
|
|
17370
17397
|
} else {
|
|
17371
|
-
log(`Instrument named '${type}' is not supported`);
|
|
17398
|
+
Util.log(`Instrument named '${type}' is not supported`);
|
|
17372
17399
|
}
|
|
17373
17400
|
}
|
|
17374
17401
|
|
|
17375
17402
|
// start new loops;
|
|
17376
|
-
this.sounds
|
|
17377
|
-
s.makeLoop();
|
|
17378
|
-
});
|
|
17379
|
-
|
|
17380
|
-
console.log(`Instruments added in: ${((Tone.Transport.seconds - t) * 1000).toFixed(3)}ms`);
|
|
17381
|
-
|
|
17403
|
+
this.makeLoops(this.sounds);
|
|
17382
17404
|
this.transferCounts(this._sounds, this.sounds);
|
|
17405
|
+
|
|
17406
|
+
console.log(`Instruments added in: ${((Tone.Transport.seconds - t) * 1000).toFixed(3)}ms`);
|
|
17383
17407
|
|
|
17384
17408
|
// when all loops started fade in the new sounds and fade out old
|
|
17385
17409
|
if (!this.sounds.length){
|
|
@@ -17398,7 +17422,7 @@ class MercuryInterpreter {
|
|
|
17398
17422
|
// handle .display to p5
|
|
17399
17423
|
tree.display.forEach((p) => {
|
|
17400
17424
|
// restart canvas if view is used
|
|
17401
|
-
let n =
|
|
17425
|
+
let n = multiply(normalize(p), 255);
|
|
17402
17426
|
this.p5canvas.sketch.fillCanvas(n);
|
|
17403
17427
|
this.p5canvas.display();
|
|
17404
17428
|
});
|
|
@@ -17406,20 +17430,21 @@ class MercuryInterpreter {
|
|
|
17406
17430
|
}
|
|
17407
17431
|
}
|
|
17408
17432
|
module.exports = { MercuryInterpreter }
|
|
17409
|
-
},{"./core/MonoInput.js":58,"./core/MonoMidi.js":59,"./core/MonoSample.js":60,"./core/MonoSynth.js":61,"./core/PolySample.js":63,"./core/PolySynth.js":64,"./data/genre-tempos.json":67,"mercury-lang":27,"tone":44,"total-serialism":47}],69:[function(require,module,exports){
|
|
17433
|
+
},{"./core/MonoInput.js":58,"./core/MonoMidi.js":59,"./core/MonoSample.js":60,"./core/MonoSynth.js":61,"./core/PolySample.js":63,"./core/PolySynth.js":64,"./core/Util.js":66,"./data/genre-tempos.json":67,"mercury-lang":27,"tone":44,"total-serialism":47}],69:[function(require,module,exports){
|
|
17410
17434
|
|
|
17411
17435
|
console.log(`
|
|
17412
17436
|
Mercury Engine by Timo Hoogland (c) 2023
|
|
17413
17437
|
more info:
|
|
17414
17438
|
https://www.timohoogland.com
|
|
17415
|
-
https://mercury.timohoogland.com
|
|
17416
17439
|
https://github.com/tmhglnd/mercury-playground
|
|
17417
17440
|
https://github.com/tmhglnd/mercury-engine
|
|
17418
17441
|
|
|
17419
17442
|
`);
|
|
17420
17443
|
|
|
17421
17444
|
const Tone = require('tone');
|
|
17445
|
+
const Util = require('./core/Util.js');
|
|
17422
17446
|
const { MercuryInterpreter } = require('./interpreter');
|
|
17447
|
+
const { WebMidi } = require("webmidi");
|
|
17423
17448
|
|
|
17424
17449
|
// load extra AudioWorkletProcessors from file
|
|
17425
17450
|
// transformed to inline with browserify brfs
|
|
@@ -17431,41 +17456,91 @@ Tone.getContext().addAudioWorkletModule(URL.createObjectURL(new Blob([ fxExtensi
|
|
|
17431
17456
|
// also has the interpreter evaluating the code and adding the instruments
|
|
17432
17457
|
//
|
|
17433
17458
|
class Mercury extends MercuryInterpreter {
|
|
17434
|
-
constructor({ onload, hydra, p5canvas } = {}){
|
|
17459
|
+
constructor({ onload, onmidi, hydra, p5canvas } = {}){
|
|
17435
17460
|
// initalize the constructor of inheriting class with
|
|
17436
17461
|
// optionally a hydra and p5 canvas
|
|
17437
17462
|
super({ hydra, p5canvas });
|
|
17438
17463
|
|
|
17439
17464
|
// store sample files in buffers
|
|
17440
|
-
this.samples = JSON.parse("{\n \"noise_a\": \"noise/noise_a.wav\",\n \"drone_cymbal\": \"ambient/cymbal/drone_cymbal.wav\",\n \"drone_cymbal_01\": \"ambient/cymbal/drone_cymbal_01.wav\",\n \"clap_808\": \"drums/clap/clap_808.wav\",\n \"clap_808_short\": \"drums/clap/clap_808_short.wav\",\n \"clap_909\": \"drums/clap/clap_909.wav\",\n \"clap_min\": \"drums/clap/clap_min.wav\",\n \"hat_808\": \"drums/hat/hat_808.wav\",\n \"hat_808_open\": \"drums/hat/hat_808_open.wav\",\n \"hat_808_semi\": \"drums/hat/hat_808_semi.wav\",\n \"hat_909\": \"drums/hat/hat_909.wav\",\n \"hat_909_open\": \"drums/hat/hat_909_open.wav\",\n \"hat_909_open_short\": \"drums/hat/hat_909_open_short.wav\",\n \"hat_909_short\": \"drums/hat/hat_909_short.wav\",\n \"hat_click\": \"drums/hat/hat_click.wav\",\n \"hat_dub\": \"drums/hat/hat_dub.wav\",\n \"hat_min\": \"drums/hat/hat_min.wav\",\n \"hat_min_open\": \"drums/hat/hat_min_open.wav\",\n \"kick_808\": \"drums/kick/kick_808.wav\",\n \"kick_808_dist\": \"drums/kick/kick_808_dist.wav\",\n \"kick_909\": \"drums/kick/kick_909.wav\",\n \"kick_909_dist\": \"drums/kick/kick_909_dist.wav\",\n \"kick_909_dist_long\": \"drums/kick/kick_909_dist_long.wav\",\n \"kick_909_long\": \"drums/kick/kick_909_long.wav\",\n \"kick_deep\": \"drums/kick/kick_deep.wav\",\n \"kick_dub\": \"drums/kick/kick_dub.wav\",\n \"kick_house\": \"drums/kick/kick_house.wav\",\n \"kick_min\": \"drums/kick/kick_min.wav\",\n \"kick_sub\": \"drums/kick/kick_sub.wav\",\n \"kick_ua\": \"drums/kick/kick_ua.wav\",\n \"kick_vintage\": \"drums/kick/kick_vintage.wav\",\n \"block\": \"drums/perc/block.wav\",\n \"block_lo\": \"drums/perc/block_lo.wav\",\n \"bongo\": \"drums/perc/bongo.wav\",\n \"bongo_lo\": \"drums/perc/bongo_lo.wav\",\n \"clave_808\": \"drums/perc/clave_808.wav\",\n \"cowbell_808\": \"drums/perc/cowbell_808.wav\",\n \"cymbal_808\": \"drums/perc/cymbal_808.wav\",\n \"maracas_808\": \"drums/perc/maracas_808.wav\",\n \"snare_808\": \"drums/snare/snare_808.wav\",\n \"snare_909\": \"drums/snare/snare_909.wav\",\n \"snare_909_short\": \"drums/snare/snare_909_short.wav\",\n \"snare_ac\": \"drums/snare/snare_ac.wav\",\n \"snare_dnb\": \"drums/snare/snare_dnb.wav\",\n \"snare_dub\": \"drums/snare/snare_dub.wav\",\n \"snare_fat\": \"drums/snare/snare_fat.wav\",\n \"snare_hvy\": \"drums/snare/snare_hvy.wav\",\n \"snare_min\": \"drums/snare/snare_min.wav\",\n \"snare_rock\": \"drums/snare/snare_rock.wav\",\n \"snare_step\": \"drums/snare/snare_step.wav\",\n \"tabla_01\": \"drums/tabla/tabla_01.wav\",\n \"tabla_02\": \"drums/tabla/tabla_02.wav\",\n \"tabla_03\": \"drums/tabla/tabla_03.wav\",\n \"tabla_hi\": \"drums/tabla/tabla_hi.wav\",\n \"tabla_hi_long\": \"drums/tabla/tabla_hi_long.wav\",\n \"tabla_hi_short\": \"drums/tabla/tabla_hi_short.wav\",\n \"tabla_lo\": \"drums/tabla/tabla_lo.wav\",\n \"tabla_lo_long\": \"drums/tabla/tabla_lo_long.wav\",\n \"tabla_lo_short\": \"drums/tabla/tabla_lo_short.wav\",\n \"tabla_mid\": \"drums/tabla/tabla_mid.wav\",\n \"tabla_mid_long\": \"drums/tabla/tabla_mid_long.wav\",\n \"tabla_mid_short\": \"drums/tabla/tabla_mid_short.wav\",\n \"tom_808\": \"drums/tom/tom_808.wav\",\n \"tom_hi\": \"drums/tom/tom_hi.wav\",\n \"tom_lo\": \"drums/tom/tom_lo.wav\",\n \"tom_mid\": \"drums/tom/tom_mid.wav\",\n \"tongue\": \"foley/body/tongue.wav\",\n \"tongue_lo\": \"foley/body/tongue_lo.wav\",\n \"shatter\": \"foley/glass/shatter.wav\",\n \"metal\": \"foley/metal/metal.wav\",\n \"metal_lo\": \"foley/metal/metal_lo.wav\",\n \"wobble\": \"foley/plastic/wobble.wav\",\n \"wobble_02\": \"foley/plastic/wobble_02.wav\",\n \"door\": \"foley/wood/door.wav\",\n \"scrape\": \"foley/wood/scrape.wav\",\n \"scrape_01\": \"foley/wood/scrape_01.wav\",\n \"wood_hit\": \"foley/wood/wood_hit.wav\",\n \"wood_metal\": \"foley/wood/wood_metal.wav\",\n \"wood_plate\": \"foley/wood/wood_plate.wav\",\n \"bell\": \"idiophone/bell/bell.wav\",\n \"chimes\": \"idiophone/chimes/chimes.wav\",\n \"chimes_chord\": \"idiophone/chimes/chimes_chord.wav\",\n \"chimes_chord_01\": \"idiophone/chimes/chimes_chord_01.wav\",\n \"chimes_chord_02\": \"idiophone/chimes/chimes_chord_02.wav\",\n \"chimes_hi\": \"idiophone/chimes/chimes_hi.wav\",\n \"gong_hi\": \"idiophone/gong/gong_hi.wav\",\n \"gong_lo\": \"idiophone/gong/gong_lo.wav\",\n \"kalimba_a\": \"idiophone/kalimba/kalimba_a.wav\",\n \"kalimba_ab\": \"idiophone/kalimba/kalimba_ab.wav\",\n \"kalimba_cis\": \"idiophone/kalimba/kalimba_cis.wav\",\n \"kalimba_e\": \"idiophone/kalimba/kalimba_e.wav\",\n \"kalimba_g\": \"idiophone/kalimba/kalimba_g.wav\",\n \"bamboo_a\": \"idiophone/marimba-bamboo/bamboo_a.wav\",\n \"bamboo_c\": \"idiophone/marimba-bamboo/bamboo_c.wav\",\n \"bamboo_f\": \"idiophone/marimba-bamboo/bamboo_f.wav\",\n \"bamboo_g\": \"idiophone/marimba-bamboo/bamboo_g.wav\",\n \"bowl_hi\": \"idiophone/singing-bowl/bowl_hi.wav\",\n \"bowl_lo\": \"idiophone/singing-bowl/bowl_lo.wav\",\n \"bowl_mid\": \"idiophone/singing-bowl/bowl_mid.wav\",\n \"rhodes_8bit\": \"keys/pad/rhodes_8bit.wav\",\n \"piano_a\": \"keys/piano/piano_a.wav\",\n \"piano_b\": \"keys/piano/piano_b.wav\",\n \"piano_c\": \"keys/piano/piano_c.wav\",\n \"piano_d\": \"keys/piano/piano_d.wav\",\n \"piano_e\": \"keys/piano/piano_e.wav\",\n \"piano_f\": \"keys/piano/piano_f.wav\",\n \"piano_g\": \"keys/piano/piano_g.wav\",\n \"amen\": \"loops/breaks/amen.wav\",\n \"amen_alt\": \"loops/breaks/amen_alt.wav\",\n \"amen_break\": \"loops/breaks/amen_break.wav\",\n \"amen_fill\": \"loops/breaks/amen_fill.wav\",\n \"house\": \"loops/breaks/house.wav\",\n \"chimes_l\": \"loops/chimes/chimes_l.wav\",\n \"noise_c\": \"loops/noise/noise_c.wav\",\n \"noise_e\": \"loops/noise/noise_e.wav\",\n \"noise_e_01\": \"loops/noise/noise_e_01.wav\",\n \"noise_mw\": \"loops/noise/noise_mw.wav\",\n \"noise_p\": \"loops/noise/noise_p.wav\",\n \"noise_r\": \"loops/noise/noise_r.wav\",\n \"choir_01\": \"vocal/choir/choir_01.wav\",\n \"choir_02\": \"vocal/choir/choir_02.wav\",\n \"choir_03\": \"vocal/choir/choir_03.wav\",\n \"choir_o\": \"vocal/choir/choir_o.wav\",\n \"wiper\": \"loops/foley/car/wiper.wav\",\n \"wiper_out\": \"loops/foley/car/wiper_out.wav\",\n \"wood_l\": \"loops/foley/wood/wood_l.wav\",\n \"wood_l_01\": \"loops/foley/wood/wood_l_01.wav\",\n \"violin_a\": \"string/bowed/violin/violin_a.wav\",\n \"violin_b\": \"string/bowed/violin/violin_b.wav\",\n \"violin_c\": \"string/bowed/violin/violin_c.wav\",\n \"violin_d\": \"string/bowed/violin/violin_d.wav\",\n \"violin_e\": \"string/bowed/violin/violin_e.wav\",\n \"violin_f\": \"string/bowed/violin/violin_f.wav\",\n \"violin_g\": \"string/bowed/violin/violin_g.wav\",\n \"harp_down\": \"string/plucked/harp/harp_down.wav\",\n \"harp_up\": \"string/plucked/harp/harp_up.wav\",\n \"pluck_a\": \"string/plucked/violin/pluck_a.wav\",\n \"pluck_b\": \"string/plucked/violin/pluck_b.wav\",\n \"pluck_c\": \"string/plucked/violin/pluck_c.wav\",\n \"pluck_d\": \"string/plucked/violin/pluck_d.wav\",\n \"pluck_e\": \"string/plucked/violin/pluck_e.wav\",\n \"pluck_f\": \"string/plucked/violin/pluck_f.wav\",\n \"pluck_g\": \"string/plucked/violin/pluck_g.wav\"\n}\n");
|
|
17465
|
+
this.samples = JSON.parse("{\n \"_base\": \"https://raw.githubusercontent.com/tmhglnd/mercury-playground/main/public/assets/samples/\",\n \"noise_a\": \"noise/noise_a.wav\",\n \"drone_cymbal\": \"ambient/cymbal/drone_cymbal.wav\",\n \"drone_cymbal_01\": \"ambient/cymbal/drone_cymbal_01.wav\",\n \"clap_808\": \"drums/clap/clap_808.wav\",\n \"clap_808_short\": \"drums/clap/clap_808_short.wav\",\n \"clap_909\": \"drums/clap/clap_909.wav\",\n \"clap_min\": \"drums/clap/clap_min.wav\",\n \"hat_808\": \"drums/hat/hat_808.wav\",\n \"hat_808_open\": \"drums/hat/hat_808_open.wav\",\n \"hat_808_semi\": \"drums/hat/hat_808_semi.wav\",\n \"hat_909\": \"drums/hat/hat_909.wav\",\n \"hat_909_open\": \"drums/hat/hat_909_open.wav\",\n \"hat_909_open_short\": \"drums/hat/hat_909_open_short.wav\",\n \"hat_909_short\": \"drums/hat/hat_909_short.wav\",\n \"hat_click\": \"drums/hat/hat_click.wav\",\n \"hat_dub\": \"drums/hat/hat_dub.wav\",\n \"hat_min\": \"drums/hat/hat_min.wav\",\n \"hat_min_open\": \"drums/hat/hat_min_open.wav\",\n \"kick_808\": \"drums/kick/kick_808.wav\",\n \"kick_808_dist\": \"drums/kick/kick_808_dist.wav\",\n \"kick_909\": \"drums/kick/kick_909.wav\",\n \"kick_909_dist\": \"drums/kick/kick_909_dist.wav\",\n \"kick_909_dist_long\": \"drums/kick/kick_909_dist_long.wav\",\n \"kick_909_long\": \"drums/kick/kick_909_long.wav\",\n \"kick_deep\": \"drums/kick/kick_deep.wav\",\n \"kick_dub\": \"drums/kick/kick_dub.wav\",\n \"kick_house\": \"drums/kick/kick_house.wav\",\n \"kick_min\": \"drums/kick/kick_min.wav\",\n \"kick_sub\": \"drums/kick/kick_sub.wav\",\n \"kick_ua\": \"drums/kick/kick_ua.wav\",\n \"kick_vintage\": \"drums/kick/kick_vintage.wav\",\n \"block\": \"drums/perc/block.wav\",\n \"block_lo\": \"drums/perc/block_lo.wav\",\n \"bongo\": \"drums/perc/bongo.wav\",\n \"bongo_lo\": \"drums/perc/bongo_lo.wav\",\n \"clave_808\": \"drums/perc/clave_808.wav\",\n \"cowbell_808\": \"drums/perc/cowbell_808.wav\",\n \"cymbal_808\": \"drums/perc/cymbal_808.wav\",\n \"maracas_808\": \"drums/perc/maracas_808.wav\",\n \"snare_808\": \"drums/snare/snare_808.wav\",\n \"snare_909\": \"drums/snare/snare_909.wav\",\n \"snare_909_short\": \"drums/snare/snare_909_short.wav\",\n \"snare_ac\": \"drums/snare/snare_ac.wav\",\n \"snare_dnb\": \"drums/snare/snare_dnb.wav\",\n \"snare_dub\": \"drums/snare/snare_dub.wav\",\n \"snare_fat\": \"drums/snare/snare_fat.wav\",\n \"snare_hvy\": \"drums/snare/snare_hvy.wav\",\n \"snare_min\": \"drums/snare/snare_min.wav\",\n \"snare_rock\": \"drums/snare/snare_rock.wav\",\n \"snare_step\": \"drums/snare/snare_step.wav\",\n \"tabla_01\": \"drums/tabla/tabla_01.wav\",\n \"tabla_02\": \"drums/tabla/tabla_02.wav\",\n \"tabla_03\": \"drums/tabla/tabla_03.wav\",\n \"tabla_hi\": \"drums/tabla/tabla_hi.wav\",\n \"tabla_hi_long\": \"drums/tabla/tabla_hi_long.wav\",\n \"tabla_hi_short\": \"drums/tabla/tabla_hi_short.wav\",\n \"tabla_lo\": \"drums/tabla/tabla_lo.wav\",\n \"tabla_lo_long\": \"drums/tabla/tabla_lo_long.wav\",\n \"tabla_lo_short\": \"drums/tabla/tabla_lo_short.wav\",\n \"tabla_mid\": \"drums/tabla/tabla_mid.wav\",\n \"tabla_mid_long\": \"drums/tabla/tabla_mid_long.wav\",\n \"tabla_mid_short\": \"drums/tabla/tabla_mid_short.wav\",\n \"tom_808\": \"drums/tom/tom_808.wav\",\n \"tom_hi\": \"drums/tom/tom_hi.wav\",\n \"tom_lo\": \"drums/tom/tom_lo.wav\",\n \"tom_mid\": \"drums/tom/tom_mid.wav\",\n \"tongue\": \"foley/body/tongue.wav\",\n \"tongue_lo\": \"foley/body/tongue_lo.wav\",\n \"shatter\": \"foley/glass/shatter.wav\",\n \"metal\": \"foley/metal/metal.wav\",\n \"metal_lo\": \"foley/metal/metal_lo.wav\",\n \"wobble\": \"foley/plastic/wobble.wav\",\n \"wobble_02\": \"foley/plastic/wobble_02.wav\",\n \"door\": \"foley/wood/door.wav\",\n \"scrape\": \"foley/wood/scrape.wav\",\n \"scrape_01\": \"foley/wood/scrape_01.wav\",\n \"wood_hit\": \"foley/wood/wood_hit.wav\",\n \"wood_metal\": \"foley/wood/wood_metal.wav\",\n \"wood_plate\": \"foley/wood/wood_plate.wav\",\n \"bell\": \"idiophone/bell/bell.wav\",\n \"chimes\": \"idiophone/chimes/chimes.wav\",\n \"chimes_chord\": \"idiophone/chimes/chimes_chord.wav\",\n \"chimes_chord_01\": \"idiophone/chimes/chimes_chord_01.wav\",\n \"chimes_chord_02\": \"idiophone/chimes/chimes_chord_02.wav\",\n \"chimes_hi\": \"idiophone/chimes/chimes_hi.wav\",\n \"gong_hi\": \"idiophone/gong/gong_hi.wav\",\n \"gong_lo\": \"idiophone/gong/gong_lo.wav\",\n \"kalimba_a\": \"idiophone/kalimba/kalimba_a.wav\",\n \"kalimba_ab\": \"idiophone/kalimba/kalimba_ab.wav\",\n \"kalimba_cis\": \"idiophone/kalimba/kalimba_cis.wav\",\n \"kalimba_e\": \"idiophone/kalimba/kalimba_e.wav\",\n \"kalimba_g\": \"idiophone/kalimba/kalimba_g.wav\",\n \"bamboo_a\": \"idiophone/marimba-bamboo/bamboo_a.wav\",\n \"bamboo_c\": \"idiophone/marimba-bamboo/bamboo_c.wav\",\n \"bamboo_f\": \"idiophone/marimba-bamboo/bamboo_f.wav\",\n \"bamboo_g\": \"idiophone/marimba-bamboo/bamboo_g.wav\",\n \"bowl_hi\": \"idiophone/singing-bowl/bowl_hi.wav\",\n \"bowl_lo\": \"idiophone/singing-bowl/bowl_lo.wav\",\n \"bowl_mid\": \"idiophone/singing-bowl/bowl_mid.wav\",\n \"rhodes_8bit\": \"keys/pad/rhodes_8bit.wav\",\n \"piano_a\": \"keys/piano/piano_a.wav\",\n \"piano_b\": \"keys/piano/piano_b.wav\",\n \"piano_c\": \"keys/piano/piano_c.wav\",\n \"piano_d\": \"keys/piano/piano_d.wav\",\n \"piano_e\": \"keys/piano/piano_e.wav\",\n \"piano_f\": \"keys/piano/piano_f.wav\",\n \"piano_g\": \"keys/piano/piano_g.wav\",\n \"amen\": \"loops/breaks/amen.wav\",\n \"amen_alt\": \"loops/breaks/amen_alt.wav\",\n \"amen_break\": \"loops/breaks/amen_break.wav\",\n \"amen_fill\": \"loops/breaks/amen_fill.wav\",\n \"house\": \"loops/breaks/house.wav\",\n \"chimes_l\": \"loops/chimes/chimes_l.wav\",\n \"noise_c\": \"loops/noise/noise_c.wav\",\n \"noise_e\": \"loops/noise/noise_e.wav\",\n \"noise_e_01\": \"loops/noise/noise_e_01.wav\",\n \"noise_mw\": \"loops/noise/noise_mw.wav\",\n \"noise_p\": \"loops/noise/noise_p.wav\",\n \"noise_r\": \"loops/noise/noise_r.wav\",\n \"choir_01\": \"vocal/choir/choir_01.wav\",\n \"choir_02\": \"vocal/choir/choir_02.wav\",\n \"choir_03\": \"vocal/choir/choir_03.wav\",\n \"choir_o\": \"vocal/choir/choir_o.wav\",\n \"wiper\": \"loops/foley/car/wiper.wav\",\n \"wiper_out\": \"loops/foley/car/wiper_out.wav\",\n \"wood_l\": \"loops/foley/wood/wood_l.wav\",\n \"wood_l_01\": \"loops/foley/wood/wood_l_01.wav\",\n \"violin_a\": \"string/bowed/violin/violin_a.wav\",\n \"violin_b\": \"string/bowed/violin/violin_b.wav\",\n \"violin_c\": \"string/bowed/violin/violin_c.wav\",\n \"violin_d\": \"string/bowed/violin/violin_d.wav\",\n \"violin_e\": \"string/bowed/violin/violin_e.wav\",\n \"violin_f\": \"string/bowed/violin/violin_f.wav\",\n \"violin_g\": \"string/bowed/violin/violin_g.wav\",\n \"harp_down\": \"string/plucked/harp/harp_down.wav\",\n \"harp_up\": \"string/plucked/harp/harp_up.wav\",\n \"pluck_a\": \"string/plucked/violin/pluck_a.wav\",\n \"pluck_b\": \"string/plucked/violin/pluck_b.wav\",\n \"pluck_c\": \"string/plucked/violin/pluck_c.wav\",\n \"pluck_d\": \"string/plucked/violin/pluck_d.wav\",\n \"pluck_e\": \"string/plucked/violin/pluck_e.wav\",\n \"pluck_f\": \"string/plucked/violin/pluck_f.wav\",\n \"pluck_g\": \"string/plucked/violin/pluck_g.wav\"\n}\n");
|
|
17441
17466
|
|
|
17442
17467
|
// this.buffers = new Tone.ToneAudioBuffers();
|
|
17443
17468
|
// add the buffers via function
|
|
17444
17469
|
// this.addBuffers(['http://localhost:8080/mercury-engine/src/data/samples.json'])
|
|
17445
17470
|
|
|
17446
17471
|
// setting parameters
|
|
17447
|
-
this.bpm
|
|
17448
|
-
this.volume
|
|
17472
|
+
this.bpm;
|
|
17473
|
+
this.volume;
|
|
17474
|
+
this.lowPass;
|
|
17475
|
+
this.highPass;
|
|
17449
17476
|
|
|
17450
17477
|
// effects on main output for Tone
|
|
17451
17478
|
this.gain = new Tone.Gain(1);
|
|
17452
|
-
this.
|
|
17453
|
-
this.
|
|
17454
|
-
Tone.Destination.chain(this.
|
|
17479
|
+
this.lowPassF = new Tone.Filter(18000, 'lowpass');
|
|
17480
|
+
this.highPassF = new Tone.Filter(5, 'highpass');
|
|
17481
|
+
Tone.Destination.chain(this.lowPassF, this.highPassF, this.gain);
|
|
17455
17482
|
|
|
17456
17483
|
// a recorder for the sound
|
|
17457
17484
|
this.recorder = new Tone.Recorder({ mimeType: 'audio/webm' });
|
|
17458
17485
|
this.gain.connect(this.recorder);
|
|
17459
17486
|
|
|
17487
|
+
// default settings
|
|
17488
|
+
this.setBPM(100);
|
|
17489
|
+
this.setVolume(1);
|
|
17490
|
+
this.setHighPass(18000);
|
|
17491
|
+
this.setLowPass(5);
|
|
17492
|
+
this.setCrossFade(250);
|
|
17493
|
+
|
|
17494
|
+
// get the base url and add to the sample locations
|
|
17495
|
+
this.baseUrl = this.samples['_base'];
|
|
17496
|
+
delete this.samples['_base'];
|
|
17497
|
+
Object.keys(this.samples).forEach((s) => {
|
|
17498
|
+
this.samples[s] = this.baseUrl + this.samples[s];
|
|
17499
|
+
});
|
|
17500
|
+
// load the buffers from the github
|
|
17460
17501
|
this.buffers = new Tone.ToneAudioBuffers({
|
|
17461
17502
|
urls: this.samples,
|
|
17462
|
-
baseUrl: "https://raw.githubusercontent.com/tmhglnd/mercury-playground/main/public/assets/samples/",
|
|
17463
17503
|
onload: () => {
|
|
17464
|
-
console.log('Samples loaded', this.buffers);
|
|
17504
|
+
// console.log('Samples loaded', this.buffers);
|
|
17465
17505
|
// executes a callback from the class constructor
|
|
17506
|
+
// if a callback is provided
|
|
17466
17507
|
if (onload){ onload(); }
|
|
17467
17508
|
}
|
|
17468
17509
|
});
|
|
17510
|
+
// this.buffers = new Tone.ToneAudioBuffers();
|
|
17511
|
+
// this.addBuffers('https://raw.githubusercontent.com/tmhglnd/mercury-engine/main/src/data/samples.json', () => {
|
|
17512
|
+
// console.log('Samples loaded', this.buffers._buffers.keys());
|
|
17513
|
+
// });
|
|
17514
|
+
|
|
17515
|
+
// the midi status, inputs and outputs
|
|
17516
|
+
this.midi = { enabled: false, inputs: [], outputs: [] };
|
|
17517
|
+
|
|
17518
|
+
// WebMIDI Setup if supported by the browser
|
|
17519
|
+
// Else `midi` not supported in the Mercury code
|
|
17520
|
+
WebMidi.enable((error) => {
|
|
17521
|
+
if (error) {
|
|
17522
|
+
console.error(`WebMIDI not enabled: ${error}`);
|
|
17523
|
+
} else {
|
|
17524
|
+
this.midi.enabled = true;
|
|
17525
|
+
|
|
17526
|
+
console.log(`WebMIDI enabled`);
|
|
17527
|
+
if (WebMidi.inputs.length < 1){
|
|
17528
|
+
console.log(`No MIDI device detected`);
|
|
17529
|
+
} else {
|
|
17530
|
+
this.midi.inputs = WebMidi.inputs;
|
|
17531
|
+
this.midi.outputs = WebMidi.outputs;
|
|
17532
|
+
|
|
17533
|
+
WebMidi.inputs.forEach((device, index) => {
|
|
17534
|
+
console.log(`in ${index}: ${device.name}`);
|
|
17535
|
+
});
|
|
17536
|
+
WebMidi.outputs.forEach((device, index) => {
|
|
17537
|
+
console.log(`out ${index}: ${device.name}`);
|
|
17538
|
+
});
|
|
17539
|
+
}
|
|
17540
|
+
// execute a callback when midi is loaded if provided
|
|
17541
|
+
if (onmidi) { onmidi(); }
|
|
17542
|
+
}
|
|
17543
|
+
});
|
|
17469
17544
|
}
|
|
17470
17545
|
|
|
17471
17546
|
// resume webaudio and transport
|
|
@@ -17520,36 +17595,46 @@ class Mercury extends MercuryInterpreter {
|
|
|
17520
17595
|
|
|
17521
17596
|
// add files to the buffer from a single File Link
|
|
17522
17597
|
// an array or file paths, or a json of { name:file, ... }
|
|
17523
|
-
|
|
17598
|
+
// optional callback function called when all files are loaded
|
|
17599
|
+
addBuffers(uploads, callback){
|
|
17600
|
+
// make sure uploades is an array to iterate over
|
|
17601
|
+
uploads = Array.isArray(uploads)? uploads : [uploads];
|
|
17602
|
+
|
|
17603
|
+
let promises = [];
|
|
17604
|
+
|
|
17524
17605
|
// for every file from uploads
|
|
17525
|
-
uploads.forEach((
|
|
17526
|
-
let n =
|
|
17527
|
-
let url =
|
|
17528
|
-
if (
|
|
17606
|
+
uploads.forEach((file) => {
|
|
17607
|
+
let n = file;
|
|
17608
|
+
let url = file;
|
|
17609
|
+
if (file.name){
|
|
17529
17610
|
// get the filename from File object
|
|
17530
|
-
n =
|
|
17531
|
-
url = URL.createObjectURL(
|
|
17611
|
+
n = file.name;
|
|
17612
|
+
url = URL.createObjectURL(file);
|
|
17532
17613
|
}
|
|
17533
|
-
if (Array.isArray(
|
|
17614
|
+
if (Array.isArray(file)){
|
|
17534
17615
|
// if array use first value as the name
|
|
17535
|
-
n =
|
|
17536
|
-
url =
|
|
17616
|
+
n = file[0];
|
|
17617
|
+
url = file[1];
|
|
17537
17618
|
}
|
|
17538
17619
|
if (n.endsWith('.json')){
|
|
17539
17620
|
// read from json if loaded is a json file
|
|
17540
|
-
this.addBufferFromJson(url);
|
|
17621
|
+
promises.push(Promise.resolve(this.addBufferFromJson(url)));
|
|
17541
17622
|
} else {
|
|
17542
17623
|
// otherwise read the soundfile regularly
|
|
17543
|
-
this.addBufferFromURL(url, n);
|
|
17624
|
+
promises.push(Promise.resolve(this.addBufferFromURL(url, n)));
|
|
17544
17625
|
}
|
|
17545
17626
|
});
|
|
17627
|
+
|
|
17628
|
+
Promise.all(promises).then((values, reject) => {
|
|
17629
|
+
if (callback) { callback(); }
|
|
17630
|
+
});
|
|
17546
17631
|
}
|
|
17547
17632
|
|
|
17548
17633
|
// add a single file to the buffer from URL
|
|
17549
17634
|
// use the name as reference in the buffer
|
|
17550
17635
|
// if name is undefined it will be constructed from the URL
|
|
17551
17636
|
//
|
|
17552
|
-
addBufferFromURL(url, n){
|
|
17637
|
+
async addBufferFromURL(url, n){
|
|
17553
17638
|
// get file name from url string
|
|
17554
17639
|
n = n.split('\\').pop().split('/').pop();
|
|
17555
17640
|
// remove extension
|
|
@@ -17561,7 +17646,7 @@ class Mercury extends MercuryInterpreter {
|
|
|
17561
17646
|
|
|
17562
17647
|
// add to ToneAudioBuffers
|
|
17563
17648
|
this.buffers.add(n, url, () => {
|
|
17564
|
-
|
|
17649
|
+
Util.log(`sound added as: ${n}`);
|
|
17565
17650
|
URL.revokeObjectURL(url);
|
|
17566
17651
|
|
|
17567
17652
|
// also add soundfiles to menu for easy selection
|
|
@@ -17570,7 +17655,7 @@ class Mercury extends MercuryInterpreter {
|
|
|
17570
17655
|
// o.value = o.innerHTML = n;
|
|
17571
17656
|
// m.appendChild(o);
|
|
17572
17657
|
}, (e) => {
|
|
17573
|
-
|
|
17658
|
+
Util.log(`error adding sound from: ${n}`);
|
|
17574
17659
|
});
|
|
17575
17660
|
}
|
|
17576
17661
|
|
|
@@ -17608,19 +17693,21 @@ class Mercury extends MercuryInterpreter {
|
|
|
17608
17693
|
|
|
17609
17694
|
// set lowpass frequency cutoff and ramptime
|
|
17610
17695
|
setLowPass(f, t=0){
|
|
17696
|
+
this.lowPass = f;
|
|
17611
17697
|
if (t > 0){
|
|
17612
|
-
this.
|
|
17698
|
+
this.lowPassF.frequency.rampTo(f, t/1000, Tone.now());
|
|
17613
17699
|
} else {
|
|
17614
|
-
this.
|
|
17700
|
+
this.lowPassF.frequency.setValueAtTime(f, Tone.now());
|
|
17615
17701
|
}
|
|
17616
17702
|
}
|
|
17617
17703
|
|
|
17618
17704
|
// set highpass frequency cutoff and ramptime
|
|
17619
17705
|
setHighPass(f, t=0){
|
|
17706
|
+
this.highPass = f;
|
|
17620
17707
|
if (t > 0){
|
|
17621
|
-
this.
|
|
17708
|
+
this.highPassF.frequency.rampTo(f, t/1000, Tone.now());
|
|
17622
17709
|
} else {
|
|
17623
|
-
this.
|
|
17710
|
+
this.highPassF.frequency.setValueAtTime(f, Tone.now());
|
|
17624
17711
|
}
|
|
17625
17712
|
}
|
|
17626
17713
|
|
|
@@ -17658,7 +17745,7 @@ class Mercury extends MercuryInterpreter {
|
|
|
17658
17745
|
anchor.click();
|
|
17659
17746
|
}
|
|
17660
17747
|
} catch(e) {
|
|
17661
|
-
|
|
17748
|
+
Util.log(`Error starting/stopping recording ${e}`);
|
|
17662
17749
|
}
|
|
17663
17750
|
}
|
|
17664
17751
|
|
|
@@ -17668,5 +17755,5 @@ class Mercury extends MercuryInterpreter {
|
|
|
17668
17755
|
}
|
|
17669
17756
|
}
|
|
17670
17757
|
module.exports = { Mercury };
|
|
17671
|
-
},{"./interpreter":68,"tone":44}]},{},[69])(69)
|
|
17758
|
+
},{"./core/Util.js":66,"./interpreter":68,"tone":44,"webmidi":55}]},{},[69])(69)
|
|
17672
17759
|
});
|