diff --git a/lib/wave.js b/lib/wave.js index f92379d6..72437ed8 100644 --- a/lib/wave.js +++ b/lib/wave.js @@ -12,1446 +12,1738 @@ (function(){ var MODSELF, edide = {}; edide.global = (function (edide, mod_global) { -return typeof global !== 'undefined' ? global : window; + + return typeof global !== 'undefined' ? global : window; }).call(MODSELF={}, edide, MODSELF); + edide.set = (function (edide, set) {Object.defineProperty(this, 'module_name', {value:'set'}); -set = (...args) => new Set(args) -set.addArr = (s, arr) => { - var i, len - for (i = 0, len = arr.length; i < len; i++) { - s.add(arr[i]) + + set = (...args) => new Set(args) + + set.addArr = (s, arr) => { + var i, len + for (i = 0, len = arr.length; i < len; i++) { + s.add(arr[i]) + } } -} -set.map = (s, func) => Array.from(s).map(func) + + set.map = (s, func) => Array.from(s).map(func) return set; }).call(MODSELF={}, edide, MODSELF); + edide.membrameSynth = (function (edide, membrameSynth) {Object.defineProperty(this, 'module_name', {value:'membrameSynth'}); -this.startNote = 'A0'; -this.init = () => { - var bd, compressor, distortion, gain, reverb; - distortion = new Tone.Distortion({ - distortion: 0.1, - oversample: "4x" // none, 2x, 4x - }); - reverb = new Tone.Freeverb(0.75, 1000); - gain = new Tone.Gain(0.5); - compressor = new Tone.Compressor({ - ratio: 12, - threshold: -24, - release: 0.05, - attack: 0.003, - knee: 1 - }); - bd = new Tone.MembraneSynth({ - pitchDecay: 0.05, - octaves: 4, - envelope: { - attack: 0.01, - decay: 0.74, - sustain: 0.71, + this.startNote = 'A0'; + + this.init = () => { + var bd, compressor, distortion, gain, reverb; + distortion = new Tone.Distortion({ + distortion: 0.1, + oversample: "4x" // none, 2x, 4x + }); + reverb = new Tone.Freeverb(0.75, 1000); + gain = new Tone.Gain(0.5); + compressor = new Tone.Compressor({ + ratio: 12, + threshold: -24, release: 0.05, - attackCurve: "exponential" - } - }); - bd.chain(gain, distortion, reverb, compressor); - return [bd, compressor]; -}; + attack: 0.003, + knee: 1 + }); + bd = new Tone.MembraneSynth({ + pitchDecay: 0.05, + octaves: 4, + envelope: { + attack: 0.01, + decay: 0.74, + sustain: 0.71, + release: 0.05, + attackCurve: "exponential" + } + }); + bd.chain(gain, distortion, reverb, compressor); + return [bd, compressor]; + }; + return membrameSynth; }).call(MODSELF={}, edide, MODSELF); + edide.toneSynth = (function (edide, toneSynth) {Object.defineProperty(this, 'module_name', {value:'toneSynth'}); -this.startNote = 'C3'; -this.init = () => { - var ss; - return ss = new Tone.PolySynth(12, Tone.Synth, { - oscillator: { - type: 'sine' - }, - envelope: { - attack: 0.005, - decay: 0.1, - sustain: 0.3, - release: 1 - } - }); -}; + this.startNote = 'C3'; + + this.init = () => { + var ss; + return ss = new Tone.PolySynth(12, Tone.Synth, { + oscillator: { + type: 'sine' + }, + envelope: { + attack: 0.005, + decay: 0.1, + sustain: 0.3, + release: 1 + } + }); + }; + return toneSynth; }).call(MODSELF={}, edide, MODSELF); + edide.instrumentConfigs = (function (edide, instrumentConfigs) { -var configs = { - 'bass-electric': { - startNote: 'C#2', - notes: 8, // 16 - step: 3 - }, - 'cello': { - startNote: 'C2', - notes: 11, - step: 2, - skipNotes: edide.set('F#2', 'C4') - }, - 'drum-electric': edide.membrameSynth, - 'guitar-acoustic': { - startNote: 'D1', - notes: 26, // 36 - step: 2, - skipNotes: edide.set('E4', 'F#4', 'G#4', 'A#4', 'C5', 'D5', 'E5') - }, - 'guitar-electric': { - startNote: 'F#2', - notes: 15, // 15 - step: 3, - }, - 'piano': { - startNote: 'A1', - notes: 30, // 29 - step: 2, - baseUrl: "https://tonejs.github.io/examples/audio/salamander/" - }, - 'synth-simple': edide.toneSynth, - 'xylophone': { - startNote: 'G3', - notes: ['G3', 'C4', 'G4', 'C5', 'G5', 'C6', 'G6', 'C7'] + + var configs = { + 'bass-electric': { + startNote: 'C#2', + notes: 8, // 16 + step: 3 + }, + 'cello': { + startNote: 'C2', + notes: 11, + step: 2, + skipNotes: edide.set('F#2', 'C4') + }, + 'drum-electric': edide.membrameSynth, + 'guitar-acoustic': { + startNote: 'D1', + notes: 26, // 36 + step: 2, + skipNotes: edide.set('E4', 'F#4', 'G#4', 'A#4', 'C5', 'D5', 'E5') + }, + 'guitar-electric': { + startNote: 'F#2', + notes: 15, // 15 + step: 3, + }, + 'piano': { + startNote: 'A1', + notes: 30, // 29 + step: 2, + baseUrl: "https://tonejs.github.io/examples/audio/salamander/" + }, + 'synth-simple': edide.toneSynth, + 'xylophone': { + startNote: 'G3', + notes: ['G3', 'C4', 'G4', 'C5', 'G5', 'C6', 'G6', 'C7'] + } } -} -for (let inst in configs) { - configs[inst].name = inst -} -return configs + + for (let inst in configs) { + configs[inst].name = inst + } + return configs }).call(MODSELF={}, edide, MODSELF); + edide.objectFromArray = (function (edide, objectFromArray) { -var identity; -identity = function(el) { - return el; -}; -return (array, valFromEl, keyFromEl) => { - var el, i, ind, len, obj; - if (valFromEl == null) { - valFromEl = identity; - } - if (keyFromEl == null) { - keyFromEl = identity; - } - obj = {}; - for (ind = i = 0, len = array.length; i < len; ind = ++i) { - el = array[ind]; - obj[keyFromEl(el, ind)] = valFromEl(el, ind); - } - return obj; -}; + var identity; + + identity = function(el) { + return el; + }; + + return (array, valFromEl, keyFromEl) => { + var el, i, ind, len, obj; + if (valFromEl == null) { + valFromEl = identity; + } + if (keyFromEl == null) { + keyFromEl = identity; + } + obj = {}; + for (ind = i = 0, len = array.length; i < len; ind = ++i) { + el = array[ind]; + obj[keyFromEl(el, ind)] = valFromEl(el, ind); + } + return obj; + }; + }).call(MODSELF={}, edide, MODSELF); + edide.noteFreq = (function (edide, noteFreq) {Object.defineProperty(this, 'module_name', {value:'noteFreq'}); -var a4, noteMap, notesObj; -this.notes = [['C0', 16.35, 2109.89], ['C#0', 17.32, 1991.47], ['D0', 18.35, 1879.69], ['D#0', 19.45, 1774.20], ['E0', 20.60, 1674.62], ['F0', 21.83, 1580.63], ['F#0', 23.12, 1491.91], ['G0', 24.50, 1408.18], ['G#0', 25.96, 1329.14], ['A0', 27.50, 1254.55], ['A#0', 29.14, 1184.13], ['B0', 30.87, 1117.67], ['C1', 32.70, 1054.94], ['C#1', 34.65, 995.73], ['D1', 36.71, 939.85], ['D#1', 38.89, 887.10], ['E1', 41.20, 837.31], ['F1', 43.65, 790.31], ['F#1', 46.25, 745.96], ['G1', 49.00, 704.09], ['G#1', 51.91, 664.57], ['A1', 55.00, 627.27], ['A#1', 58.27, 592.07], ['B1', 61.74, 558.84], ['C2', 65.41, 527.47], ['C#2', 69.30, 497.87], ['D2', 73.42, 469.92], ['D#2', 77.78, 443.55], ['E2', 82.41, 418.65], ['F2', 87.31, 395.16], ['F#2', 92.50, 372.98], ['G2', 98.00, 352.04], ['G#2', 103.83, 332.29], ['A2', 110.00, 313.64], ['A#2', 116.54, 296.03], ['B2', 123.47, 279.42], ['C3', 130.81, 263.74], ['C#3', 138.59, 248.93], ['D3', 146.83, 234.96], ['D#3', 155.56, 221.77], ['E3', 164.81, 209.33], ['F3', 174.61, 197.58], ['F#3', 185.00, 186.49], ['G3', 196.00, 176.02], ['G#3', 207.65, 166.14], ['A3', 220.00, 156.82], ['A#3', 233.08, 148.02], ['B3', 246.94, 139.71], ['C4', 261.63, 131.87], ['C#4', 277.18, 124.47], ['D4', 293.66, 117.48], ['D#4', 311.13, 110.89], ['E4', 329.63, 104.66], ['F4', 349.23, 98.79], ['F#4', 369.99, 93.24], ['G4', 392.00, 88.01], ['G#4', 415.30, 83.07], ['A4', 440.00, 78.41], ['A#4', 466.16, 74.01], ['B4', 493.88, 69.85], ['C5', 523.25, 65.93], ['C#5', 554.37, 62.23], ['D5', 587.33, 58.74], ['D#5', 622.25, 55.44], ['E5', 659.25, 52.33], ['F5', 698.46, 49.39], ['F#5', 739.99, 46.62], ['G5', 783.99, 44.01], ['G#5', 830.61, 41.54], ['A5', 880.00, 39.20], ['A#5', 932.33, 37.00], ['B5', 987.77, 34.93], ['C6', 1046.50, 32.97], ['C#6', 1108.73, 31.12], ['D6', 1174.66, 29.37], ['D#6', 1244.51, 27.72], ['E6', 1318.51, 26.17], ['F6', 1396.91, 24.70], ['F#6', 1479.98, 23.31], ['G6', 1567.98, 22.00], ['G#6', 1661.22, 20.77], ['A6', 1760.00, 19.60], ['A#6', 1864.66, 18.50], ['B6', 1975.53, 17.46], ['C7', 2093.00, 16.48], ['C#7', 2217.46, 15.56], ['D7', 2349.32, 14.69], ['D#7', 2489.02, 13.86], ['E7', 2637.02, 13.08], ['F7', 2793.83, 12.35], ['F#7', 2959.96, 11.66], ['G7', 3135.96, 11.00], ['G#7', 3322.44, 10.38], ['A7', 3520.00, 9.80], ['A#7', 3729.31, 9.25], ['B7', 3951.07, 8.73], ['C8', 4186.01, 8.24], ['C#8', 4434.92, 7.78], ['D8', 4698.63, 7.34], ['D#8', 4978.03, 6.93], ['E8', 5274.04, 6.54], ['F8', 5587.65, 6.17], ['F#8', 5919.91, 5.83], ['G8', 6271.93, 5.50], ['G#8', 6644.88, 5.19], ['A8', 7040.00, 4.90], ['A#8', 7458.62, 4.63], ['B8', 7902.13, 4.37]]; -notesObj = null; -noteMap = () => { - if (notesObj) { - return notesObj; - } - return notesObj = edide.objectFromArray(this.notes, (val, ind) => { - return [ind, ...val]; - }, (key) => { - return key[0]; - }); -}; -this.findNote = (name) => { - return noteMap()[name]; -}; -a4 = this.findNote('A4'); -this.diffToA4 = (name) => { - var note; - note = this.findNote(name); - return note[0] - a4[0]; -}; -this.diff = (n1, n2) => { - return this.findNote(n2)[0] - this.findNote(n1)[0]; -}; + var a4, noteMap, notesObj; + + this.notes = [['C0', 16.35, 2109.89], ['C#0', 17.32, 1991.47], ['D0', 18.35, 1879.69], ['D#0', 19.45, 1774.20], ['E0', 20.60, 1674.62], ['F0', 21.83, 1580.63], ['F#0', 23.12, 1491.91], ['G0', 24.50, 1408.18], ['G#0', 25.96, 1329.14], ['A0', 27.50, 1254.55], ['A#0', 29.14, 1184.13], ['B0', 30.87, 1117.67], ['C1', 32.70, 1054.94], ['C#1', 34.65, 995.73], ['D1', 36.71, 939.85], ['D#1', 38.89, 887.10], ['E1', 41.20, 837.31], ['F1', 43.65, 790.31], ['F#1', 46.25, 745.96], ['G1', 49.00, 704.09], ['G#1', 51.91, 664.57], ['A1', 55.00, 627.27], ['A#1', 58.27, 592.07], ['B1', 61.74, 558.84], ['C2', 65.41, 527.47], ['C#2', 69.30, 497.87], ['D2', 73.42, 469.92], ['D#2', 77.78, 443.55], ['E2', 82.41, 418.65], ['F2', 87.31, 395.16], ['F#2', 92.50, 372.98], ['G2', 98.00, 352.04], ['G#2', 103.83, 332.29], ['A2', 110.00, 313.64], ['A#2', 116.54, 296.03], ['B2', 123.47, 279.42], ['C3', 130.81, 263.74], ['C#3', 138.59, 248.93], ['D3', 146.83, 234.96], ['D#3', 155.56, 221.77], ['E3', 164.81, 209.33], ['F3', 174.61, 197.58], ['F#3', 185.00, 186.49], ['G3', 196.00, 176.02], ['G#3', 207.65, 166.14], ['A3', 220.00, 156.82], ['A#3', 233.08, 148.02], ['B3', 246.94, 139.71], ['C4', 261.63, 131.87], ['C#4', 277.18, 124.47], ['D4', 293.66, 117.48], ['D#4', 311.13, 110.89], ['E4', 329.63, 104.66], ['F4', 349.23, 98.79], ['F#4', 369.99, 93.24], ['G4', 392.00, 88.01], ['G#4', 415.30, 83.07], ['A4', 440.00, 78.41], ['A#4', 466.16, 74.01], ['B4', 493.88, 69.85], ['C5', 523.25, 65.93], ['C#5', 554.37, 62.23], ['D5', 587.33, 58.74], ['D#5', 622.25, 55.44], ['E5', 659.25, 52.33], ['F5', 698.46, 49.39], ['F#5', 739.99, 46.62], ['G5', 783.99, 44.01], ['G#5', 830.61, 41.54], ['A5', 880.00, 39.20], ['A#5', 932.33, 37.00], ['B5', 987.77, 34.93], ['C6', 1046.50, 32.97], ['C#6', 1108.73, 31.12], ['D6', 1174.66, 29.37], ['D#6', 1244.51, 27.72], ['E6', 1318.51, 26.17], ['F6', 1396.91, 24.70], ['F#6', 1479.98, 23.31], ['G6', 1567.98, 22.00], ['G#6', 1661.22, 20.77], ['A6', 1760.00, 19.60], ['A#6', 1864.66, 18.50], ['B6', 1975.53, 17.46], ['C7', 2093.00, 16.48], ['C#7', 2217.46, 15.56], ['D7', 2349.32, 14.69], ['D#7', 2489.02, 13.86], ['E7', 2637.02, 13.08], ['F7', 2793.83, 12.35], ['F#7', 2959.96, 11.66], ['G7', 3135.96, 11.00], ['G#7', 3322.44, 10.38], ['A7', 3520.00, 9.80], ['A#7', 3729.31, 9.25], ['B7', 3951.07, 8.73], ['C8', 4186.01, 8.24], ['C#8', 4434.92, 7.78], ['D8', 4698.63, 7.34], ['D#8', 4978.03, 6.93], ['E8', 5274.04, 6.54], ['F8', 5587.65, 6.17], ['F#8', 5919.91, 5.83], ['G8', 6271.93, 5.50], ['G#8', 6644.88, 5.19], ['A8', 7040.00, 4.90], ['A#8', 7458.62, 4.63], ['B8', 7902.13, 4.37]]; + + notesObj = null; + + noteMap = () => { + if (notesObj) { + return notesObj; + } + return notesObj = edide.objectFromArray(this.notes, (val, ind) => { + return [ind, ...val]; + }, (key) => { + return key[0]; + }); + }; + + this.findNote = (name) => { + return noteMap()[name]; + }; + + a4 = this.findNote('A4'); + + this.diffToA4 = (name) => { + var note; + note = this.findNote(name); + return note[0] - a4[0]; + }; + + this.diff = (n1, n2) => { + return this.findNote(n2)[0] - this.findNote(n1)[0]; + }; + return noteFreq; }).call(MODSELF={}, edide, MODSELF); + edide.strRandom = (function (edide, strRandom) { -return (limit = 20) => { - return (Math.random() + '').slice(2, +(limit + 1) + 1 || 9e9); -}; + return (limit = 20) => { + return (Math.random() + '').slice(2, +(limit + 1) + 1 || 9e9); + }; + }).call(MODSELF={}, edide, MODSELF); + edide.inEditor = (function (edide, inEditor) {Object.defineProperty(this, 'module_name', {value:'inEditor'}); -inEditor = (inEditor === true) || false + inEditor = (inEditor === true) || false return inEditor; }).call(MODSELF={}, edide, MODSELF); + edide.edideNamespace = (function (edide, edideNamespace) { -return 'edide' + + return 'edide' }).call(MODSELF={}, edide, MODSELF); + edide.edideNs = (function (edide, edideNs) { -var base, name; -return (base = edide.global)[name = edide.edideNamespace] != null ? base[name] : base[name] = {}; + var base, name; + + return (base = edide.global)[name = edide.edideNamespace] != null ? base[name] : base[name] = {}; + }).call(MODSELF={}, edide, MODSELF); + edide.editorModule = (function (edide, editorModule) { -var editorModule; -editorModule = edide.inEditor ? edide.edideNs : null; + var editorModule; + + editorModule = edide.inEditor ? edide.edideNs : null; + return editorModule; }).call(MODSELF={}, edide, MODSELF); + edide.keep = (function (edide, keep) {Object.defineProperty(this, 'module_name', {value:'keep'}); -var keep; -keep = (prop) => { - return prop; -}; + var keep; + + keep = (prop) => { + return prop; + }; + return keep; }).call(MODSELF={}, edide, MODSELF); + edide.logProd = (function (edide, logProd) { -return (...args) => { - var console, ref, ref1; - console = (ref = (ref1 = edide.editorModule) != null ? ref1.console : void 0) != null ? ref : edide.global.console; - return console.log(...args); -}; + return (...args) => { + var console, ref, ref1; + console = (ref = (ref1 = edide.editorModule) != null ? ref1.console : void 0) != null ? ref : edide.global.console; + return console.log(...args); + }; + }).call(MODSELF={}, edide, MODSELF); + edide.onUnload = (function (edide, onUnload) { -var ref, ref1; -return (ref = (ref1 = edide.editorModule) != null ? ref1.unload.add : void 0) != null ? ref : () => {}; + var ref, ref1; + + return (ref = (ref1 = edide.editorModule) != null ? ref1.unload.add : void 0) != null ? ref : () => {}; + }).call(MODSELF={}, edide, MODSELF); + edide.var = (function (edide, mod_var) { -var clearVar, currentReact, debugging, dependees, dependsOn, depsRequired, inInitCall, infinityCheck, initSetter, loopLimit, newVar, parent, setLinks, setters, updateVar, values; -values = edide.keep(new Map); // #edide.keep if clearVar added again.. -setters = edide.keep(new Map); // varName => setter:func -dependees = edide.keep(new Map); // varName => deps: -setLinks = edide.keep(new Map); // for reactiveGraph, show setters inside reactive/setter:s -debugging = false; //edide.editorModule? -depsRequired = new Map; // varName : dependsOn -inInitCall = false; // TODO use dependsOn? instead -dependsOn = new Set(); // remove -initSetter = (name, setter) => { - var debugName, err, parent, ref, val; - debugName = (ref = setter.type) != null ? ref : name; - if ((setters.get(name)) != null) { - throw Error(`Reactive for '${debugName}' already exists`); - } - setters.set(name, setter); - if (inInitCall) { - throw Error(`can't create reactive setter (for '${debugName}') inside reactive context`); - } - inInitCall = name; - dependsOn.clear(); // TODO clear => new Set - try { - val = setter(); // TODO: some day add revar and unvar as params; helps with multiple reactives to keep the separated - } catch (error) { - err = error; - inInitCall = false; - err.message = `Reactive initialization of '${debugName}' failed: ${err.message}`; - throw err; - } - parent = null; - dependsOn.forEach((depName) => { - var deps; - if ((deps = dependees.get(depName)) == null) { - dependees.set(depName, deps = new Set); + var clearVar, currentReact, debugging, dependees, dependsOn, depsRequired, inInitCall, infinityCheck, initSetter, loopLimit, newVar, parent, setLinks, setters, updateVar, values; + + values = edide.keep(new Map); // #edide.keep if clearVar added again.. + + setters = edide.keep(new Map); // varName => setter:func + + dependees = edide.keep(new Map); // varName => deps: + + setLinks = edide.keep(new Map); // for reactiveGraph, show setters inside reactive/setter:s + + debugging = false; //edide.editorModule? + + depsRequired = new Map; // varName : dependsOn + + inInitCall = false; // TODO use dependsOn? instead + + dependsOn = new Set(); // remove + + initSetter = (name, setter) => { + var debugName, err, parent, ref, val; + debugName = (ref = setter.type) != null ? ref : name; + if ((setters.get(name)) != null) { + throw Error(`Reactive for '${debugName}' already exists`); } - return deps.add(name); - }); - inInitCall = false; - return val; -}; -loopLimit = 0; -infinityCheck = new Map; //edide.keep -parent = null; -updateVar = function(name, val) { - var ref, ref1, type; - if (arguments.length === 1) { //unless val? - val = setters.get(name)(); - if (debugging && (type = setters.get(name).type)) { - edide.logProd(`running ${(setters.get(name).type)}`); + setters.set(name, setter); + if (inInitCall) { + throw Error(`can't create reactive setter (for '${debugName}') inside reactive context`); } - } - if (typeof name !== 'string') { // symbol ~ react function - return; - } - if (values.get(name) === val && typeof val !== 'object') { - return; - } - if (infinityCheck.get(name) > loopLimit) { - infinityCheck.forEach((k) => { - return edide.logProd(k); + inInitCall = name; + dependsOn.clear(); // TODO clear => new Set + try { + val = setter(); // TODO: some day add revar and unvar as params; helps with multiple reactives to keep the separated + } catch (error) { + err = error; + inInitCall = false; + err.message = `Reactive initialization of '${debugName}' failed: ${err.message}`; + throw err; + } + parent = null; + dependsOn.forEach((depName) => { + var deps; + if ((deps = dependees.get(depName)) == null) { + dependees.set(depName, deps = new Set); + } + return deps.add(name); }); - edide.logProd(name); - if ((ref = edide.editorModule) != null) { - if (typeof ref.reactiveGraph === "function") { - ref.reactiveGraph(); + inInitCall = false; + return val; + }; + + loopLimit = 0; + + infinityCheck = new Map; //edide.keep + + parent = null; + + updateVar = function(name, val) { + var ref, ref1, type; + if (arguments.length === 1) { //unless val? + val = setters.get(name)(); + if (debugging && (type = setters.get(name).type)) { + edide.logProd(`running ${(setters.get(name).type)}`); } } - throw Error("Inifinite loop in \:var dependencies"); - } - if (debugging) { - edide.logProd(`updating ${name}`); - } - values.set(name, val); - if (!inInitCall) { - infinityCheck.set(name, (infinityCheck.get(name) || 0) + 1); - if ((ref1 = dependees.get(name)) != null) { - ref1.forEach((depName) => { - return updateVar(depName); - }); + if (typeof name !== 'string') { // symbol ~ react function + return; } - infinityCheck.delete(name); - } - return val; -}; -currentReact = []; -newVar = function(name, setter) { - var context, contextSet, err; - if (arguments.length === 1) { - if (typeof name === 'string') { - if (inInitCall) { - dependsOn.add(name); + if (values.get(name) === val && typeof val !== 'object') { + return; + } + if (infinityCheck.get(name) > loopLimit) { + infinityCheck.forEach((k) => { + return edide.logProd(k); + }); + edide.logProd(name); + if ((ref = edide.editorModule) != null) { + if (typeof ref.reactiveGraph === "function") { + ref.reactiveGraph(); + } + } + throw Error("Inifinite loop in \:var dependencies"); + } + if (debugging) { + edide.logProd(`updating ${name}`); + } + values.set(name, val); + if (!inInitCall) { + infinityCheck.set(name, (infinityCheck.get(name) || 0) + 1); + if ((ref1 = dependees.get(name)) != null) { + ref1.forEach((depName) => { + return updateVar(depName); + }); + } + infinityCheck.delete(name); + } + return val; + }; + + currentReact = []; + + newVar = function(name, setter) { + var context, contextSet, err; + if (arguments.length === 1) { + if (typeof name === 'string') { + if (inInitCall) { + dependsOn.add(name); + edide.onUnload(() => { + return clearVar(name); // TODO make specific clear? + }); + } + return values.get(name); + } else { + setter = name; + name = Symbol(); + values.set(name, name); // for debugging (showing react/dom funcs in graph) edide.onUnload(() => { return clearVar(name); // TODO make specific clear? }); } - return values.get(name); - } else { - setter = name; - name = Symbol(); - values.set(name, name); // for debugging (showing react/dom funcs in graph) + } + if (currentReact.length) { // and debugging + context = currentReact[currentReact.length - 1]; + if (!(contextSet = setLinks.get(context))) { + setLinks.set(context, contextSet = new Set); + } + contextSet.add(name); + } + currentReact.push(name); + if (values.get(name) == null) { edide.onUnload(() => { - return clearVar(name); // TODO make specific clear? + return clearVar(name); }); } - } - if (currentReact.length) { // and debugging - context = currentReact[currentReact.length - 1]; - if (!(contextSet = setLinks.get(context))) { - setLinks.set(context, contextSet = new Set); + if (typeof setter === 'function') { + setter = initSetter(name, setter); // setter becomes value } - contextSet.add(name); - } - currentReact.push(name); - if (values.get(name) == null) { - edide.onUnload(() => { - return clearVar(name); - }); - } - if (typeof setter === 'function') { - setter = initSetter(name, setter); // setter becomes value - } - if (typeof name === 'string') { - try { - updateVar(name, setter); - } catch (error) { - err = error; - infinityCheck.clear(); - throw err; + if (typeof name === 'string') { + try { + updateVar(name, setter); + } catch (error) { + err = error; + infinityCheck.clear(); + throw err; + } } - } - currentReact.pop(); - return setter; -}; -clearVar = (name) => { - var i, len, map, ref; - ref = [values, setters, dependees, setLinks]; - for (i = 0, len = ref.length; i < len; i++) { - map = ref[i]; - map.delete(name); - } -}; -Object.assign(newVar, {dependees, values, setters, setLinks}); -return newVar; -}).call(MODSELF={}, edide, MODSELF); -edide.reactiveWithFilters = (function (edide, reactiveWithFilters) { -return (initialVars = {}, filters = {}) => { - var handler, id, key, react, revar, todoMap, unvar, val; - id = edide.strRandom(); - handler = { - get: (map, prop) => { - var ref; - if ((ref = edide.editorModule) != null ? ref.editor_inspector.inspectingNow : void 0) { - console.log('IN inspector? Find out is it possible to end up here form inside setter'); - return edide.var.values.get(`${id}.${prop}`); - } - return edide.var(`${id}.${prop}`); - }, - set: (map, prop, value) => { - if ((filters[prop] != null) && !filters[prop](value)) { - throw Error(`Illegal reactive (${prop}: ${value})`); - } - edide.var(`${id}.${prop}`, value); - return true; // Proxy set must return true if set is successfull; In the future use Reflect.set, which returns true automatically? + currentReact.pop(); + return setter; + }; + + clearVar = (name) => { + var i, len, map, ref; + ref = [values, setters, dependees, setLinks]; + for (i = 0, len = ref.length; i < len; i++) { + map = ref[i]; + map.delete(name); } }; - revar = new Proxy((todoMap = new Map), handler); // NOTE: map is not used yet - unvar = new Proxy(todoMap, { - get: (map, prop) => { - return edide.var.values.get(`${id}.${prop}`); - }, - set: (map, prop, value) => { - return edide.var.values.set(`${id}.${prop}`, value); - } - }); - for (key in initialVars) { - val = initialVars[key]; - revar[key] = val; - } - react = (nameOrFunc, func) => { - if (func != null) { - func.type = nameOrFunc; - } else { - func = nameOrFunc; - func.type = 'react'; // for debugging - } - return edide.var(func); - }; - return { - react, - revar, - unvar, - un: unvar, - re: revar // , dom - }; -}; -}).call(MODSELF={}, edide, MODSELF); -edide.mmState = (function (edide, mmState) {Object.defineProperty(this, 'module_name', {value:'mmState'}); -var filters, instruments; -this.defaults = { - playing: false, - recorderOn: false, - fullSheet: '', - sheet: '', // selected/play part of fullSheet - diffText: '', - note: null, // currently playing note - pace: 400, // -> bpm -> beatDelay - bpm: 400, // deprecate - beatDelay: (1 / 400) * 60 * 1000, // silly! unify with pace as one statestate variable - balance: 0, - volume: 0, - detune: 0, - blur: 0, - itch: 0, - instrumentsLoading: 0, - instrument: 'guitar-electric', - scale: 'pentatonic', - root: 'C3', - highlight: null, - keyboardInd: 0 // TODO --> keyboard -}; -instruments = Object.keys(edide.instrumentConfigs); -filters = { - scale: (val) => { - return ['pentatonic', 'minor', 'major'].includes(val); - }, - instrument: (val) => { - return instruments.includes(val); - }, - root: (val) => { - return edide.noteFreq.findNote(val); - } -}; -this.react = null; -this.init = (startingProps = {}) => { - var props; - if (this.react != null) { - return this; - } - props = Object.assign({}, this.defaults, startingProps); - ({react: this.react, revar: this.revar, unvar: this.unvar} = edide.reactiveWithFilters(props, filters)); - return this; -}; -return mmState; -}).call(MODSELF={}, edide, MODSELF); -edide.mmEffects = (function (edide, mmEffects) {Object.defineProperty(this, 'module_name', {value:'mmEffects'}); -({revar: this.revar} = edide.mmState.init()); -this.maxLowpass = 10000; -this.maxDistortion = 3; -this.revar.lowpass = () => { - var blur; - ({blur} = this.revar); - return this.maxLowpass - blur * (this.maxLowpass - 200); -}; -this.revar.distortion = () => { - var itch; - ({itch} = this.revar); - return this.maxDistortion * itch; -}; -return mmEffects; -}).call(MODSELF={}, edide, MODSELF); -edide.clone = (function (edide, clone) { -return (...objects) => { - if (Array.isArray(objects[0])) { - return Object.assign([], ...objects); - } else { - return Object.assign({}, ...objects); - } -}; -}).call(MODSELF={}, edide, MODSELF); -edide.strParsesToNumber = (function (edide, strParsesToNumber) {Object.defineProperty(this, 'module_name', {value:'strParsesToNumber'}); -var strParsesToNumber; -strParsesToNumber = (str) => { - return !Number.isNaN(parseInt(str)); -}; -return strParsesToNumber; -}).call(MODSELF={}, edide, MODSELF); -edide.mmConfigs = (function (edide, mmConfigs) {Object.defineProperty(this, 'module_name', {value:'mmConfigs'}); -var defaultVars, mutatingProp, mutatingVars, stateVars, vars; -vars = {}; // varName: config object -mutatingVars = {}; -stateVars = edide.set('itch', 'blur', 'instrument', 'bpm', 'pace', 'beatDelay', 'scale', 'root', 'balance', 'detune', 'volume'); -this.hasVar = (varName) => { - var ref, ref1; - return !!((ref = (ref1 = vars[varName]) != null ? ref1 : mutatingVars[varName]) != null ? ref : stateVars.has(varName)); -}; -this.activateVar = (name, value) => { - var configs; - if (value != null) { - configs = stateVars.has(name) ? { - [`${name}`]: value - } : mutatingVars[name] != null ? edide.clone(mutatingVars[name]) : void 0; - if (edide.strParsesToNumber(value)) { - value = parseFloat(value); - } - configs[mutatingProp(configs)] = value; - return this.activate(configs); - } else { - return this.activate(vars[name]); - } -}; -mutatingProp = (configs) => { - var name, val; - for (name in configs) { - val = configs[name]; - if (val === '*') { - return name; - } - } - return false; -}; -this.activate = (conf) => { - if (conf.name != null) { - return; // throw warning? - } - return Object.assign(edide.mmState.revar, conf); -}; -this.reset = () => { - stateVars.forEach((name) => { - return edide.mmState.revar[name] = edide.mmState.defaults[name]; - }); -}; -this.addVar = (varName, config) => { // , activate=true - if (mutatingProp(config)) { - return mutatingVars[varName] = config; - } else { - return vars[varName] = config; - } -}; -defaultVars = { - bass: { - "instrument": "bass-electric" - }, - cello: { - "instrument": "cello" - }, - guitar: { - "instrument": "guitar-acoustic" - }, - eguitar: { - "instrument": "guitar-electric" - }, - piano: { - "instrument": "piano" - }, - synth: { - "instrument": "synth-simple" - }, - xylophone: { - "instrument": "xylophone" - }, - pentatonic: { - "scale": "pentatonic" - }, - major: { - "scale": "major" - }, - minor: { - "scale": "minor" - } -}; -this.init = () => { - var conf, name; - vars = {}; - for (name in defaultVars) { - conf = defaultVars[name]; - this.addVar(name, conf, false); - } -}; -this.init(); -return mmConfigs; -}).call(MODSELF={}, edide, MODSELF); -edide.setTimeout = (function (edide, mod_setTimeout) { -var nativeSetTimeout, ref; -nativeSetTimeout = edide.global.nativeSetTimeout = (ref = edide.global.nativeSetTimeout) != null ? ref : edide.global.setTimeout; -return function(arg1, arg2) { - var fun, id, num; - [fun, num] = typeof arg2 === 'function' ? [arg2, arg1] : [arg1, arg2]; - id = nativeSetTimeout(fun, num); - edide.onUnload(() => { - return clearTimeout(id); - }); - return id; -}; -}).call(MODSELF={}, edide, MODSELF); -edide.musicScales = (function (edide, musicScales) {Object.defineProperty(this, 'module_name', {value:'musicScales'}); -this.full = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']; -this.scaleSteps = { - pentatonic: [ - 0, - 3, - 2, - 2, - 3 // hidden 2 # "pentatonicMinor" - ], - major: [ - 0, - 2, - 2, - 1, - 2, - 2, - 2 // hidden to beginning: 1 # "naturalMajor" - ], - minor: [ - 0, - 2, - 1, - 2, - 2, - 1, - 2 // hidden to beginning: 2 # "naturalMinor" - ] -}; -this.triadSteps = { - major: [ - 0, - 4, - 3 // positive valence - ], - minor: [0, 3, 4] -}; -this.triadCombinations = { - protagonism: 'M2M', - outerSpace: 'M6M', - fantastical: 'M8M', - sadness: 'M4m', - romantic: 'M5m', // and middle eastern - wonder: 'm5M', // and trancendence - mystery: 'm2M', // and dark comedy - dramatic: 'm11M', - antagonismDanger: 'm6m', // less character based - antagonismEvil: 'm8m' // cahracter based -}; -return musicScales; -}).call(MODSELF={}, edide, MODSELF); -edide.mathOp = (function (edide, mathOp) {Object.defineProperty(this, 'module_name', {value:'mathOp'}); -this.sum = function(a, b) { - return a + b; -}; -this.multiply = function(a, b) { - return a * b; -}; -return mathOp; -}).call(MODSELF={}, edide, MODSELF); -edide.mmKeyboard = (function (edide, mmKeyboard) {Object.defineProperty(this, 'module_name', {value:'mmKeyboard'}); -var A, a, char, chari, i, j, len, len1, noncaps, qwertyChar, qwertyRows, revar, row, rowi, space, unvar; -({revar, unvar} = edide.mmState.init()); -revar.scaleSteps = () => { - return edide.musicScales.scaleSteps[revar.scale]; -}; -this.special = { - rest: '.', - long: '=', - comment: '#', - var: ':', - confStart: '{', - confEnd: '}' -}; -this.specialKeyCodes = new Set(Object.values(this.special).map((s) => { - return s.charCodeAt(0); -})); -this.specialChars = new Set(Object.values(this.special)); -this.isPauseKey = (keyCode) => { - return this.specialKeyCodes.has(keyCode); -}; -this.isSpecialChar = (char) => { - return this.specialChars.has(char); -}; -this.isPauseChar = this.isSpecialChar; // not really... -this.keyboards = ['qwerty', 'abc']; -a = 'a'.charCodeAt(0); -A = 'A'.charCodeAt(0); -space = ' '.charCodeAt(0); -this.isCaps = (key) => { - return A <= key && key < a; -}; -this.capsDiff = a - A; -noncaps = (key) => { - if (this.isCaps(key)) { - return key + this.capsDiff; - } else { - return key; - } -}; -this.getNoteInd = (key) => { - var maxInstrumentNoteInd, noteBaseInd, noteInd, notes, startNote, step; - ({startNote, notes, step} = unvar.instrumentConf); - startNote = unvar.root; - noteBaseInd = edide.noteFreq.findNote(startNote)[0]; - noteInd = this[this.keyboards[unvar.keyboardInd]](noncaps(key), noteBaseInd); - maxInstrumentNoteInd = noteBaseInd + notes * step; - while (noteInd > maxInstrumentNoteInd) { - noteInd -= 2 * 12; - } - return noteInd; -}; -this.abc = (key, baseInd) => { - var fromLowest, noteInd, stepsFromClosestOctave; - fromLowest = key - a; - stepsFromClosestOctave = fromLowest % revar.scaleSteps.length; - noteInd = 0; - noteInd += revar.scaleSteps.slice(0, +stepsFromClosestOctave + 1 || 9e9).reduce(edide.mathOp.sum); - noteInd += 12 * Math.floor(fromLowest / revar.scaleSteps.length); - return baseInd + noteInd; -}; -qwertyRows = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm']; -qwertyChar = {}; -for (rowi = i = 0, len = qwertyRows.length; i < len; rowi = ++i) { - row = qwertyRows[rowi]; - for (chari = j = 0, len1 = row.length; j < len1; chari = ++j) { - char = row[chari]; - qwertyChar[char.charCodeAt(0)] = [rowi, chari]; - } -} -this.qwerty = (key, baseInd) => { - var charSteps, halfSteps, noteInd, octave, rowchar; - if (!(rowchar = qwertyChar[key])) { - return; - } - [row, char] = rowchar; - octave = qwertyRows.length - 1 - row + Math.floor(char / unvar.scaleSteps.length); - char = char % revar.scaleSteps.length; - charSteps = revar.scaleSteps.slice(0, +char + 1 || 9e9).reduce((a, b) => { - return a + b; - }); - halfSteps = 12 * octave + charSteps; - return noteInd = baseInd + halfSteps; -}; -return mmKeyboard; -}).call(MODSELF={}, edide, MODSELF); -edide.chars = (function (edide, chars) {Object.defineProperty(this, 'module_name', {value:'chars'}); -this.space = ' '; -this.nonBreakingSpace = ' '; -this.enter = "\n"; -return chars; -}).call(MODSELF={}, edide, MODSELF); -edide.showError = (function (edide, showError) { -var error; -error = (err) => { - if (edide.inEditor) { - return edide.editorModule.editor_error.show(err); - } else if (typeof edide.global.require === 'object' && (edide.global[edide.edideNamespace].prodErrorPrinter != null)) { - return edide.global[edide.edideNamespace].prodErrorPrinter.showError(err); - } else { - return console.error(err); - } -}; -return (err) => { - var err2; - if (err != null ? err.stack : void 0) { - return error(err); // create error to capture stack trace - } else { - try { - throw Error(err); - } catch (error1) { - err2 = error1; - return error(err2); - } - } -}; -}).call(MODSELF={}, edide, MODSELF); -edide.mmParserSpecial = (function (edide, mmParserSpecial) {Object.defineProperty(this, 'module_name', {value:'mmParserSpecial'}); -this.config = (trackStr, ts = {}) => { - var endInd, err, name; - endInd = trackStr.search('}') || trackStr.length; - try { - ts.conf = JSON.parse(trackStr.slice(0, +endInd + 1 || 9e9)); - if (ts.conf.name != null) { - ({name} = ts.conf); - delete ts.conf.name; - edide.mmConfigs.addVar(name, ts.conf); - } else { - edide.mmConfigs.activate(ts.conf); // add variable if exists - } - } catch (error) { - err = error; - ts.skip = true; // could be used to show error highlighting in editor - edide.showError(err); // remove this if error highlighting implemented - } - return endInd; -}; -this.var = (track, trackState) => { - var err, i, value, varLength, varName, varStr; - ({i} = trackState); - varLength = track.slice(i + 1).indexOf(edide.mmKeyboard.special.var); - if (varLength === -1) { - return false; - } - varStr = track.slice(i + 1, +(i + varLength) + 1 || 9e9); - [varName, value] = varStr.split(' '); - if (!edide.mmConfigs.hasVar(varName)) { - return false; - } - try { - edide.mmConfigs.activateVar(varName, value); - trackState.i += varLength + 2; - return true; - } catch (error) { - err = error; - return false; - } -}; -return mmParserSpecial; -}).call(MODSELF={}, edide, MODSELF); -edide.mmNote = (function (edide, mmNote) {Object.defineProperty(this, 'module_name', {value:'mmNote'}); -this.fromChar = (char) => { - return this.fromKeyCode(char.charCodeAt(0)); -}; -this.fromKeyCode = (key) => { - var noteInd, ref; - if (typeof (noteInd = edide.mmKeyboard.getNoteInd(key)) === 'number') { - return (ref = edide.noteFreq.notes[noteInd]) != null ? ref[0] : void 0; - } -}; -return mmNote; -}).call(MODSELF={}, edide, MODSELF); -edide.mmParser = (function (edide, mmParser) {Object.defineProperty(this, 'module_name', {value:'mmParser'}); -var getNoteLength, nonBreakingSpace, processTrack, revar, space, unvar; -({revar, unvar} = edide.mmState); -getNoteLength = (row, noteInd) => { - var char, length; - length = 1; - while (char = row[++noteInd]) { - if (char === edide.mmKeyboard.special.long) { - length++; - } else { - break; - } - } - return length; -}; -({space, nonBreakingSpace} = edide.chars); -processTrack = (track, ccs, ts) => { - var bef, chord, groupingChars, keyCode, lastSpace, note, repeat, repeatStart; - if (!track[ts.i]) { - return; - } - if (ts.skip) { // comment or erroneous chars - return; - } - switch (track[ts.i]) { - case '{': - return ts.i += edide.mmParserSpecial.config(track.slice(ts.i), ts); // parseConfigs - case '*': - if (ts.repeat != null) { - ts.repeat--; - if (ts.repeat > 0) { - ts.i = ts.iStart = ts.repeatStart; // repeats done - } else { - ts.repeat = ts.repeatStart = null; - ts.i++; // step over '*' so won't end up starting repeats again - } - } else { - if (isNaN(repeat = parseInt(track.slice(ts.i + 1)))) { - ts.i++; // unable to parse number of repeats, skip them - } else { - ts.repeat = repeat - 1; - bef = track.slice(0, ts.i); - groupingChars = ['(', space, nonBreakingSpace, '*']; - lastSpace = Math.max(...groupingChars.map((c) => { - return bef.lastIndexOf(c); - })); - repeatStart = lastSpace !== -1 ? lastSpace + 1 : 0; // beginning of row if no grouping char found - ts.i = ts.iStart = ts.repeatStart = repeatStart; - } - } - return processTrack(track, ccs, ts); - case '[': - ccs.chord = []; - ts.i++; - return processTrack(track, ccs, ts); - case ']': - ts.i++; - ({chord} = ccs); - if (!chord) { // illegal - missing beginning [ - return processTrack(track, ccs, ts); - } - ccs.chord = null; - if (chord.length) { - if (!unvar.preprocessing) { - revar.playNote = [chord, getNoteLength(track, ts.i)]; - } - ccs.played = true; - } else { - processTrack(track, ccs, ts); - } - return; - case edide.mmKeyboard.special.var: - if (edide.mmParserSpecial.var(track, ts)) { - processTrack(track, ccs, ts); // recursive, since next char could be another var, e.g. \:bass::minor: - } else { - ts.skip = true; // parse error - } - return; - case edide.mmKeyboard.special.comment: - return ts.skip = true; - } - if (!(keyCode = track.charCodeAt(ts.i))) { - return; - } - ts.i++; - if (note = edide.mmNote.fromKeyCode(keyCode)) { - if (ccs.chord) { - ccs.chord.push(note); - processTrack(track, ccs, ts); - } else { - if (!unvar.preprocessing) { - revar.playNote = [note, getNoteLength(track, ts.i)]; - } - ccs.played = true; - } - } else if (edide.mmKeyboard.isPauseKey(keyCode)) { - ccs.played = true; // "play silence" - } else { - processTrack(track, ccs, ts); - } -}; -this.splitSections = (str) => { - var i, j, prevInd, ref, row, section, sections; - str = str.replace('&\n', ''); // TODO fix row tracking with &\n - sections = []; - section = null; - row = 0; - prevInd = 0; - for (i = j = 0, ref = str.length; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) { - if (!(str[i] === '\n' || i === str.length)) { - continue; - } - if (str[i - 1] === '\n') { - if (section != null) { - sections.push(section); - } - section = null; - } - if (i > prevInd) { - if (section == null) { - section = { - row: row, - tracks: [] - }; - } - section.tracks.push(str.slice(prevInd, i)); - } - row++; - prevInd = i + 1; - } - if (section != null) { - sections.push(section); - } - sections.row = 0; - return sections; -}; -this.play = (song, sectionInd, trackStates) => { - var ccs, section; - if (!unvar.playing) { - return; - } - revar.highlight = null; - sectionInd = sectionInd || 0; - if (typeof song === 'string') { - song = this.splitSections(song); - } - section = song[sectionInd]; - if (!section) { // song finished - if (!unvar.preprocessing) { - revar.playing = false; - } - return; - } - if (!Array.isArray(trackStates)) { - trackStates = section.tracks.map(() => { - return { - i: 0 // initi track indices on first call to section - }; - }); - } - ccs = {}; // chord, played # TODO change back to chord: [C3, D3] and [].played = true - section.tracks.forEach((track, tInd) => { - var conf, i, iStart; - if (conf = trackStates[tInd].conf) { - return edide.mmConfigs.activate(conf); - } else { - trackStates[tInd].iStart = trackStates[tInd].i; - processTrack(track, ccs, trackStates[tInd]); - ({iStart, i} = trackStates[tInd]); - if (i > iStart) { - return revar.highlight = [ - section.row + tInd, - iStart, - i - 1 // song.row+ - ]; - } - } - }); - if (ccs.played) { - if (unvar.preprocessing) { - this.play(song, sectionInd, trackStates); - } else { - edide.setTimeout(() => { - return this.play(song, sectionInd, trackStates); - }, unvar.beatDelay); - } - } else { - this.play(song, sectionInd + 1); - } -}; -return mmParser; -}).call(MODSELF={}, edide, MODSELF); -edide.mmPipe = (function (edide, mmPipe) {Object.defineProperty(this, 'module_name', {value:'mmPipe'}); -var dist, lowpass, panner, react, revar, reverber, unvar; -({revar, unvar, react} = edide.mmState.init()); -dist = lowpass = reverber = panner = null; -this.initPipe = () => { - lowpass = new Tone.Filter(unvar.lowpass, 'lowpass', -12); - dist = new Tone.Distortion(unvar.distortion); - panner = new Tone.Panner(); - panner.connect(dist); - dist.connect(lowpass); - lowpass.toMaster(); - this.output = lowpass; - revar.pipeReady = true; - return edide.onUnload(() => { - if (dist != null) { - if (typeof dist.dipose === "function") { - dist.dipose(); - } - } - if (lowpass != null) { - if (typeof lowpass.dispose === "function") { - lowpass.dispose(); - } - } - return panner != null ? typeof panner.dispose === "function" ? panner.dispose() : void 0 : void 0; - }); -}; -this.initInstrument = (instrument) => { - instrument.connect(panner); - edide.onUnload(() => { - return instrument != null ? instrument.disconnect() : void 0; - }); - return instrument; -}; -revar.panner = () => { - return revar.balance; -}; -react('panner', () => { - revar.panner; - return panner != null ? panner.pan.value = revar.panner : void 0; -}); -react('pipe distortion', () => { - var ref; - revar.distortion; - revar.lowpass; - if (dist != null) { - dist.distortion = revar.distortion; - } - return lowpass != null ? (ref = lowpass.frequency) != null ? ref.linearRampTo(revar.lowpass, 0) : void 0 : void 0; -}); -return mmPipe; -}).call(MODSELF={}, edide, MODSELF); -edide.moduleGate = (function (edide, moduleGate) {Object.defineProperty(this, 'module_name', {value:'moduleGate'}); -if (!edide.inEditor) { - return this; -} -this.root; // module that is edited in root -this.rootName; -this.active; // module that is currently being edited (can be root or in window) -this.activeName; -this.executing; -this.executingName; -return moduleGate; -}).call(MODSELF={}, edide, MODSELF); -edide.rejectIfRecompiled = (function (edide, rejectIfRecompiled) { -if (!edide.inEditor) { - return () => {}; -} -return (promise) => { - var recompiled, rootName; - ({rootName} = edide.moduleGate); - recompiled = false; - edide.editorModule.editor_events.on('before_recompile', () => { - return recompiled = true; - }); - return promise.then(function(arg) { - if (recompiled || rootName !== edide.moduleGate.rootName) { // root module changed - return Promise.reject(); // quiet rejection; no need to show error - } else { - return arg; // arg get wrapped in promise - } - }); -}; -}).call(MODSELF={}, edide, MODSELF); -edide.promise = (function (edide, promise) {Object.defineProperty(this, 'module_name', {value:'promise'}); -var localPromise, ref; -localPromise = edide.global.origPromise = (ref = edide.global.origPromise) != null ? ref : edide.global.Promise; -this.new = function(cb) { - if (edide.inEditor) { - return edide.rejectIfRecompiled(new Promise(cb)); // don't fire cb if code has been re-executed in the meantime - } else { - return new Promise(cb); - } -}; -this.all = function(cbArray) { - if (edide.inEditor) { // check that after resolved, still editing same module - return edide.rejectIfRecompiled(Promise.all(cbArray)); - } else { - return Promise.all(cbArray); - } -}; -this.resolve = Promise.resolve.bind(Promise); -this.reject = Promise.reject.bind(Promise); -return promise; -}).call(MODSELF={}, edide, MODSELF); -edide.qs = (function (edide, qs) { -return (selector, el = document) => { - return el.querySelector(selector); -}; -}).call(MODSELF={}, edide, MODSELF); -edide.scriptContainer = (function (edide, scriptContainer) { -var createContainer, ref; -createContainer = () => { - var s; - s = document.createElement('div'); - s.id = 'scripts'; - return s; -}; -return (ref = edide.qs('#scripts')) != null ? ref : document.body.appendChild(createContainer()); -}).call(MODSELF={}, edide, MODSELF); -edide.requireScript = (function (edide, requireScript) { -var base; -if ((base = edide.global).requireScriptPromises == null) { - base.requireScriptPromises = new Map; -} -return (scriptSrc) => { - var promise; - if (promise = requireScriptPromises.get(scriptSrc)) { - return promise; - } else { - requireScriptPromises.set(scriptSrc, promise = edide.promise.new((resolve) => { - var el; - console.log('adding promised', scriptSrc); - el = document.createElement('script'); - edide.scriptContainer.appendChild(el); - el.onload = resolve; //load_ready - el.type = 'application/javascript'; - return el.src = scriptSrc; - })); - return promise.catch((err) => { - edide.showError(err); - return requireScriptPromises.delete(scriptSrc); - }); - } -}; -}).call(MODSELF={}, edide, MODSELF); -edide.mmInstruments = (function (edide, mmInstruments) {Object.defineProperty(this, 'module_name', {value:'mmInstruments'}); -var defaultUrl = 'https://nbrosowsky.github.io/tonejs-instruments/samples/' -var { revar, unvar, react } = edide.mmState -var defaultInstrument = 'electric-guitar' -this.initInstrument = async (resolve) => { - await edide.requireScript('https://cdnjs.cloudflare.com/ajax/libs/tone/13.8.9/Tone.js') - edide.mmPipe.initPipe() -} -var instrumentCache = edide.keep({}) -this.createNew = () => { - var {name} = unvar.instrumentConf - var instrument, endOfPipe - var instrumentConf = this.instruments[name] - if (instrumentConf.module_name) { - var res = instrumentConf.init() - if (Array.isArray(res)) { - instrument = res[0] - endOfPipe = res[1] - } else { - instrument = endOfPipe = res - } - } else if (instrumentCache[name]) { - instrument = endOfPipe = instrumentCache[name] - } else { - var noteFiles = buildNotes(instrumentConf) - revar.instrumentsLoading++ - var inst = new Tone.Sampler(noteFiles, { //edide.mmInstrumentssAll[name] - "release" : 1, - "baseUrl" : instrumentConf.url || defaultUrl + name + '/', - "onload" : () => revar.instrumentsLoading-- - }) - inst.soundFontInstrument = true - instrument = endOfPipe = instrumentCache[name] = inst //[inst, inst] - } - edide.mmPipe.initInstrument(endOfPipe) - return instrument -} -this.isReady = () => { - var { current } = this - return current && (typeof current.loaded == 'undefined' || current.loaded === true) -} -function buildNotes({startNote, notes, step, skipNotes}) { - var [startInd] = edide.noteFreq.findNote(startNote) - var noteFiles = {} - if (Array.isArray(notes)) { - notes.forEach(note => { - noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]' - }) - } else { - for (let i=0; i < notes*step; i+=step) { - let note = edide.noteFreq.notes[startInd + i][0]; - if (skipNotes && skipNotes.has(note)) - continue - noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]' - } - } - return noteFiles -} -this.instruments = edide.instrumentConfigs -this.instrumentList = Object.values(this.instruments) -react('active instrument config', () => { - revar.instrumentConf = this.instruments[revar.instrument] // conf -}) -return mmInstruments; -}).call(MODSELF={}, edide, MODSELF); -edide.cloneSibling = (function (edide, cloneSibling) { -return (srcObj) => { - var o; - o = Object.create(Object.getPrototypeOf(srcObj)); - Object.assign(o, srcObj); - return o; -}; -}).call(MODSELF={}, edide, MODSELF); -edide.times = (function (edide, times) { -return (timesNum, action) => { - while (timesNum-- > 0) { - action(timesNum + 1); - } -}; -}).call(MODSELF={}, edide, MODSELF); -edide.sleep = (function (edide, sleep) { -var sleep; -sleep = (ms) => { - var resolve, timeout; - timeout = resolve = null; - return edide.promise.new((res) => { - resolve = res; - return timeout = edide.setTimeout(ms, res); - }); -}; -return sleep; -}).call(MODSELF={}, edide, MODSELF); -edide.mmInstrument = (function (edide, mmInstrument) {Object.defineProperty(this, 'module_name', {value:'mmInstrument'}); -var cloneOrCreateInstrument, getInstruments, instruments, play, react, revar, unvar, updateVolAndTune; -instruments = {}; // name: [instrument instances...] -({unvar, revar, react} = edide.mmState); -revar.bpm = () => { - return revar.pace; -}; -revar.beatDelay = () => { - return (1 / revar.bpm) * 60 * 1000; -}; -react(() => {}); -updateVolAndTune = (inst) => { - var detune, volume; - ({volume, detune} = unvar); - if ((detune != null) && (inst.detune != null)) { - inst.set("detune", detune); - } - if ((volume != null) && (inst.volume != null)) { - return inst.set("volume", volume); - } -}; -react(() => { - var inst, insts, j, len, name; - revar.volume; - revar.detune; - for (name in instruments) { - insts = instruments[name]; - for (j = 0, len = insts.length; j < len; j++) { - inst = insts[j]; - updateVolAndTune(inst); - } - } -}); -react('create first instrument', () => { - var name, ref; - if (!(name = (ref = revar.instrumentConf) != null ? ref.name : void 0)) { // e.g. illegal instrument name - return edide.showError(`Unknown instrument: ${unvar.instrument}`); - } - if (revar.pipeReady && !instruments[name]) { - return instruments[name] = [edide.mmInstruments.createNew()]; - } -}); -cloneOrCreateInstrument = (name) => { - var inst; - inst = instruments[name][0].soundFontInstrument ? (inst = edide.cloneSibling(instruments[name][0]), inst.isPlaying = false, inst) : edide.mmInstruments.createNew(); - updateVolAndTune(inst); - return inst; -}; -getInstruments = (n) => { - var all, free, name; - ({name} = unvar.instrumentConf); - all = instruments[name]; - free = all.filter((i) => { - return !i.isPlaying; - }); - edide.times(n - free.length, () => { - var inst; - free.push(inst = cloneOrCreateInstrument(name)); - return all.push(inst); - }); - return free.slice(0, n); -}; -this.playChord = (chord, noteLength = 1) => {}; -this.playNote = (chord, noteLength = 1) => { - var ind, inst, insts, j, len, ref; - if (!Array.isArray(chord)) { - chord = [chord]; - } - ref = insts = getInstruments(chord.length); - for (ind = j = 0, len = ref.length; j < len; ind = ++j) { - inst = ref[ind]; - play(inst, chord[ind], noteLength); - } -}; -play = async(instrument, note, length) => { - var err; - instrument.isPlaying = note; // true - try { - instrument.triggerAttackRelease(note, (length * unvar.beatDelay) / 1000); - } catch (error) { - err = error; - err.message = `Error in playing note ${note}, '${unvar.instrumentConf.name}' probably not loaded yet`; - edide.showError(err); - } - revar.note = note; - await edide.sleep(unvar.nextDelay); - return instrument.isPlaying = false; -}; -return mmInstrument; -}).call(MODSELF={}, edide, MODSELF); -edide.mmPlayer = (function (edide, mmPlayer) {Object.defineProperty(this, 'module_name', {value:'mmPlayer'}); -var react, revar, unvar; -({revar, unvar, react} = edide.mmState.init()); -this.play = (str) => { - revar.sheet = str; - return revar.playing = true; -}; -react('play from sheet', () => { - if (!revar.playing) { - return; - } - edide.mmConfigs.init(); - revar.preprocessing = true; - return edide.setTimeout(() => { // infinite revar.playing loop - edide.mmParser.play(unvar.sheet); - return revar.preprocessing = 'done'; - }); -}); -react('play notes/chords', () => { - var chord, playNote, playing, preprocessing, time; - ({playNote, playing, preprocessing} = revar); - if (!(playNote && playing && preprocessing === false)) { - return; - } - [chord, time] = revar.playNote; - return edide.mmInstrument.playNote(chord, time); -}); -this.toggle = () => { - return revar.playing = !unvar.playing; -}; -revar.instrumentsLoading; -react('play after preprocess', () => { - var instrumentsLoading, preprocessing; - ({instrumentsLoading, preprocessing} = revar); - if (!(preprocessing === 'done' && instrumentsLoading === 0)) { - return; - } - unvar.preprocessing = false; - edide.mmConfigs.reset(); - return edide.mmParser.play(unvar.sheet); -}); -return mmPlayer; -}).call(MODSELF={}, edide, MODSELF); -edide.waves = (function (edide, waves) {Object.defineProperty(this, 'module_name', {value:'waves'}); -edide.global.music = this -edide.mmEffects -var { revar, unvar, react } = edide.mmState -var playQueue = [] -this.play = (str) => { - if (!unvar.pipeReady) return playQueue.push(str) - revar.playing = true - edide.mmPlayer.play(str) -} -this.stop = () => revar.playing = false -edide.mmInstruments.initInstrument() -react(() => { - if(!revar.pipeReady) return - edide.mmConfigs.reset() - this.play(playQueue.join("\n\n")) // JSON.stringify(initialSettings) -}) -return waves; -}).call(MODSELF={}, edide, MODSELF); -edide.wave = (function (edide, wave) { -var parent = { - play: function(){ - edide.waves.play(this.sheet) - return this - }, - stop: function(){ - edide.waves.stop(this.sheet) - return this - }, - blur: function(val){ - this.sheet = `:blur ${val}:` + this.sheet - return this - }, - itch: function(val){ - this.sheet = `:itch ${val}:` + this.sheet - return this - }, - long: function(val){ // note delay in seconds - this.sheet = `:beatDelay ${val*1000}:` + this.sheet - return this - }, - pace: function(val) { // note delay in beats per minute - this.sheet = `:pace ${val}:` + this.sheet - return this - }, - vary: function(val){ - this.sheet = `:detune ${val}:` + this.sheet - return this - }, - loud: function(val){ // increase (>0) or decrease (<0) amplitude in decibels - this.sheet = `:volume ${val}:` + this.sheet - return this - }, - balance: function(val){ - this.sheet = `:balance ${val}:` + this.sheet - return this - } -} -return edide.global.wave = (str) => { - edide.mmConfigs.reset() - var obj = Object.create(parent) - obj.sheet = str - return obj -} -edide.mmState.unvar.panner + + Object.assign(newVar, {dependees, values, setters, setLinks}); + + return newVar; + }).call(MODSELF={}, edide, MODSELF); +edide.reactiveWithFilters = (function (edide, reactiveWithFilters) { + return (initialVars = {}, filters = {}) => { + var handler, id, key, react, revar, todoMap, unvar, val; + id = edide.strRandom(); + handler = { + get: (map, prop) => { + var ref; + if ((ref = edide.editorModule) != null ? ref.editor_inspector.inspectingNow : void 0) { + console.log('IN inspector? Find out is it possible to end up here form inside setter'); + return edide.var.values.get(`${id}.${prop}`); + } + return edide.var(`${id}.${prop}`); + }, + set: (map, prop, value) => { + if ((filters[prop] != null) && !filters[prop](value)) { + throw Error(`Illegal reactive (${prop}: ${value})`); + } + edide.var(`${id}.${prop}`, value); + return true; // Proxy set must return true if set is successfull; In the future use Reflect.set, which returns true automatically? + } + }; + revar = new Proxy((todoMap = new Map), handler); // NOTE: map is not used yet + unvar = new Proxy(todoMap, { + get: (map, prop) => { + return edide.var.values.get(`${id}.${prop}`); + }, + set: (map, prop, value) => { + return edide.var.values.set(`${id}.${prop}`, value); + } + }); + for (key in initialVars) { + val = initialVars[key]; + revar[key] = val; + } + react = (nameOrFunc, func) => { + if (func != null) { + func.type = nameOrFunc; + } else { + func = nameOrFunc; + func.type = 'react'; // for debugging + } + return edide.var(func); + }; + return { + react, + revar, + unvar, + un: unvar, + re: revar // , dom + }; + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.mmState = (function (edide, mmState) {Object.defineProperty(this, 'module_name', {value:'mmState'}); + var filters, instruments; + + this.defaults = { + playing: false, + recorderOn: false, + fullSheet: '', + sheet: '', // selected/play part of fullSheet + diffText: '', + note: null, // currently playing note + // state properties + pace: 400, // -> bpm -> beatDelay + bpm: 400, // deprecate + beatDelay: (1 / 400) * 60 * 1000, // silly! unify with pace as one statestate variable + balance: 0, + volume: 0, + detune: 0, + blur: 0, + itch: 0, + instrumentsLoading: 0, + // dropdowns + instrument: 'guitar-electric', + scale: 'pentatonic', + root: 'C3', + highlight: null, + keyboardInd: 0 // TODO --> keyboard + }; + + instruments = Object.keys(edide.instrumentConfigs); + + filters = { + scale: (val) => { + return ['pentatonic', 'minor', 'major'].includes(val); + }, + instrument: (val) => { + return instruments.includes(val); + }, + root: (val) => { + return edide.noteFreq.findNote(val); + } + }; + + this.react = null; + + this.init = (startingProps = {}) => { + var props; + if (this.react != null) { + return this; + } + props = Object.assign({}, this.defaults, startingProps); + ({react: this.react, revar: this.revar, unvar: this.unvar} = edide.reactiveWithFilters(props, filters)); + return this; + }; + +return mmState; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmEffects = (function (edide, mmEffects) {Object.defineProperty(this, 'module_name', {value:'mmEffects'}); + ({revar: this.revar} = edide.mmState.init()); + + this.maxLowpass = 10000; + + this.maxDistortion = 3; + + this.revar.lowpass = () => { + var blur; + ({blur} = this.revar); + return this.maxLowpass - blur * (this.maxLowpass - 200); + }; + + this.revar.distortion = () => { + var itch; + ({itch} = this.revar); + return this.maxDistortion * itch; + }; + +return mmEffects; +}).call(MODSELF={}, edide, MODSELF); + +edide.clone = (function (edide, clone) { + return (...objects) => { + if (Array.isArray(objects[0])) { + return Object.assign([], ...objects); + } else { + return Object.assign({}, ...objects); + } + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.strParsesToNumber = (function (edide, strParsesToNumber) {Object.defineProperty(this, 'module_name', {value:'strParsesToNumber'}); + var strParsesToNumber; + + strParsesToNumber = (str) => { + return !Number.isNaN(parseInt(str)); + }; + +return strParsesToNumber; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmConfigs = (function (edide, mmConfigs) {Object.defineProperty(this, 'module_name', {value:'mmConfigs'}); + var defaultVars, mutatingProp, mutatingVars, stateVars, vars; + + vars = {}; // varName: config object + + mutatingVars = {}; + + stateVars = edide.set('itch', 'blur', 'instrument', 'bpm', 'pace', 'beatDelay', 'scale', 'root', 'balance', 'detune', 'volume'); + + this.hasVar = (varName) => { + var ref, ref1; + return !!((ref = (ref1 = vars[varName]) != null ? ref1 : mutatingVars[varName]) != null ? ref : stateVars.has(varName)); + }; + + this.activateVar = (name, value) => { + var configs; + if (value != null) { + configs = stateVars.has(name) ? { + [`${name}`]: value + } : mutatingVars[name] != null ? edide.clone(mutatingVars[name]) : void 0; + if (edide.strParsesToNumber(value)) { + value = parseFloat(value); + } + configs[mutatingProp(configs)] = value; + return this.activate(configs); + } else { + return this.activate(vars[name]); + } + }; + + mutatingProp = (configs) => { + var name, val; + for (name in configs) { + val = configs[name]; + if (val === '*') { + return name; + } + } + return false; + }; + + this.activate = (conf) => { + if (conf.name != null) { + return; // throw warning? + } + return Object.assign(edide.mmState.revar, conf); + }; + + this.reset = () => { + stateVars.forEach((name) => { + return edide.mmState.revar[name] = edide.mmState.defaults[name]; + }); + }; + + this.addVar = (varName, config) => { // , activate=true + if (mutatingProp(config)) { + return mutatingVars[varName] = config; + } else { + return vars[varName] = config; + } + }; + + defaultVars = { + bass: { + "instrument": "bass-electric" + }, + cello: { + "instrument": "cello" + }, + guitar: { + "instrument": "guitar-acoustic" + }, + eguitar: { + "instrument": "guitar-electric" + }, + piano: { + "instrument": "piano" + }, + synth: { + "instrument": "synth-simple" + }, + xylophone: { + "instrument": "xylophone" + }, + pentatonic: { + "scale": "pentatonic" + }, + major: { + "scale": "major" + }, + minor: { + "scale": "minor" + } + }; + + this.init = () => { + var conf, name; + vars = {}; + for (name in defaultVars) { + conf = defaultVars[name]; + this.addVar(name, conf, false); + } + }; + + this.init(); + +return mmConfigs; +}).call(MODSELF={}, edide, MODSELF); + +edide.setTimeout = (function (edide, mod_setTimeout) { + var nativeSetTimeout, ref; + + nativeSetTimeout = edide.global.nativeSetTimeout = (ref = edide.global.nativeSetTimeout) != null ? ref : edide.global.setTimeout; + + return function(arg1, arg2) { + var fun, id, num; + [fun, num] = typeof arg2 === 'function' ? [arg2, arg1] : [arg1, arg2]; + id = nativeSetTimeout(fun, num); + edide.onUnload(() => { + return clearTimeout(id); + }); + return id; + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.musicScales = (function (edide, musicScales) {Object.defineProperty(this, 'module_name', {value:'musicScales'}); + this.full = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']; + + this.scaleSteps = { + // rock + // 0, 3, 2, 2, 3, (2) + pentatonic: [ + 0, + 3, + 2, + 2, + 3 // hidden 2 # "pentatonicMinor" + ], + //pentatonicMajor: ['C, D, E, G, A'] + // blues: minor penta + + // whole – whole – half – whole – whole – whole – half + major: [ + 0, + 2, + 2, + 1, + 2, + 2, + 2 // hidden to beginning: 1 # "naturalMajor" + ], + // whole – half – whole – whole – half – whole – whole + minor: [ + 0, + 2, + 1, + 2, + 2, + 1, + 2 // hidden to beginning: 2 # "naturalMinor" + ] + }; + // http://whatmusicreallyis.com/papers/sacred_sounds_scale.html + this.triadSteps = { + major: [ + 0, + 4, + 3 // positive valence + ], + minor: [0, 3, 4] + }; + + // M = major triad + // m = minor triar + // i = number of (half) steps from first triad to second + // (source: https://www.youtube.com/watch?v=YSKAt3pmYBs) + this.triadCombinations = { + protagonism: 'M2M', + outerSpace: 'M6M', + fantastical: 'M8M', + sadness: 'M4m', + romantic: 'M5m', // and middle eastern + wonder: 'm5M', // and trancendence + mystery: 'm2M', // and dark comedy + dramatic: 'm11M', + antagonismDanger: 'm6m', // less character based + antagonismEvil: 'm8m' // cahracter based + }; + +return musicScales; +}).call(MODSELF={}, edide, MODSELF); + +edide.mathOp = (function (edide, mathOp) {Object.defineProperty(this, 'module_name', {value:'mathOp'}); + this.sum = function(a, b) { + return a + b; + }; + + this.multiply = function(a, b) { + return a * b; + }; + +return mathOp; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmKeyboard = (function (edide, mmKeyboard) {Object.defineProperty(this, 'module_name', {value:'mmKeyboard'}); + var A, a, char, chari, i, j, len, len1, noncaps, qwertyChar, qwertyRows, revar, row, rowi, space, unvar; + + ({revar, unvar} = edide.mmState.init()); + + revar.scaleSteps = () => { + return edide.musicScales.scaleSteps[revar.scale]; + }; + + this.special = { + rest: '.', + long: '=', + comment: '#', + var: ':', + confStart: '{', + confEnd: '}' + }; + + this.specialKeyCodes = new Set(Object.values(this.special).map((s) => { + return s.charCodeAt(0); + })); + + this.specialChars = new Set(Object.values(this.special)); + + this.isPauseKey = (keyCode) => { + return this.specialKeyCodes.has(keyCode); + }; + + this.isSpecialChar = (char) => { + return this.specialChars.has(char); + }; + + this.isPauseChar = this.isSpecialChar; // not really... + + this.keyboards = ['qwerty', 'abc']; + + a = 'a'.charCodeAt(0); + + A = 'A'.charCodeAt(0); + + space = ' '.charCodeAt(0); + + this.isCaps = (key) => { + return A <= key && key < a; + }; + + this.capsDiff = a - A; + + noncaps = (key) => { + if (this.isCaps(key)) { + return key + this.capsDiff; + } else { + return key; + } + }; + + this.getNoteInd = (key) => { + var maxInstrumentNoteInd, noteBaseInd, noteInd, notes, startNote, step; + ({startNote, notes, step} = unvar.instrumentConf); + startNote = unvar.root; + noteBaseInd = edide.noteFreq.findNote(startNote)[0]; + noteInd = this[this.keyboards[unvar.keyboardInd]](noncaps(key), noteBaseInd); + maxInstrumentNoteInd = noteBaseInd + notes * step; + while (noteInd > maxInstrumentNoteInd) { + noteInd -= 2 * 12; + } + return noteInd; + }; + + this.abc = (key, baseInd) => { + var fromLowest, noteInd, stepsFromClosestOctave; + fromLowest = key - a; + stepsFromClosestOctave = fromLowest % revar.scaleSteps.length; + noteInd = 0; + noteInd += revar.scaleSteps.slice(0, +stepsFromClosestOctave + 1 || 9e9).reduce(edide.mathOp.sum); + noteInd += 12 * Math.floor(fromLowest / revar.scaleSteps.length); + return baseInd + noteInd; + }; + + qwertyRows = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm']; + + qwertyChar = {}; + + for (rowi = i = 0, len = qwertyRows.length; i < len; rowi = ++i) { + row = qwertyRows[rowi]; + for (chari = j = 0, len1 = row.length; j < len1; chari = ++j) { + char = row[chari]; + qwertyChar[char.charCodeAt(0)] = [rowi, chari]; + } + } + + this.qwerty = (key, baseInd) => { + var charSteps, halfSteps, noteInd, octave, rowchar; + if (!(rowchar = qwertyChar[key])) { + return; + } + [row, char] = rowchar; + octave = qwertyRows.length - 1 - row + Math.floor(char / unvar.scaleSteps.length); + char = char % revar.scaleSteps.length; + charSteps = revar.scaleSteps.slice(0, +char + 1 || 9e9).reduce((a, b) => { + return a + b; + }); + halfSteps = 12 * octave + charSteps; + return noteInd = baseInd + halfSteps; + }; + +return mmKeyboard; +}).call(MODSELF={}, edide, MODSELF); + +edide.chars = (function (edide, chars) {Object.defineProperty(this, 'module_name', {value:'chars'}); + this.space = ' '; + + this.nonBreakingSpace = ' '; + + this.enter = "\n"; + +return chars; +}).call(MODSELF={}, edide, MODSELF); + +edide.showError = (function (edide, showError) { + var error; + + error = (err) => { + if (edide.inEditor) { + return edide.editorModule.editor_error.show(err); + } else if (typeof edide.global.require === 'object' && (edide.global[edide.edideNamespace].prodErrorPrinter != null)) { + return edide.global[edide.edideNamespace].prodErrorPrinter.showError(err); + } else { + return console.error(err); + } + }; + + return (err) => { + var err2; + if (err != null ? err.stack : void 0) { + return error(err); // create error to capture stack trace + } else { + try { + throw Error(err); + } catch (error1) { + err2 = error1; + return error(err2); + } + } + }; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmParserSpecial = (function (edide, mmParserSpecial) {Object.defineProperty(this, 'module_name', {value:'mmParserSpecial'}); + // parse config { .. } and variable : .. : syntaxes + this.config = (trackStr, ts = {}) => { + var endInd, err, name; + endInd = trackStr.search('}') || trackStr.length; + try { + ts.conf = JSON.parse(trackStr.slice(0, +endInd + 1 || 9e9)); + if (ts.conf.name != null) { + ({name} = ts.conf); + delete ts.conf.name; + edide.mmConfigs.addVar(name, ts.conf); + } else { + edide.mmConfigs.activate(ts.conf); // add variable if exists + } + } catch (error) { + err = error; + ts.skip = true; // could be used to show error highlighting in editor + edide.showError(err); // remove this if error highlighting implemented + } + return endInd; + }; + + // parse variable from curren track row + // returns false if parsing fails + this.var = (track, trackState) => { + var err, i, value, varLength, varName, varStr; + ({i} = trackState); + varLength = track.slice(i + 1).indexOf(edide.mmKeyboard.special.var); + if (varLength === -1) { + return false; + } + varStr = track.slice(i + 1, +(i + varLength) + 1 || 9e9); + [varName, value] = varStr.split(' '); + if (!edide.mmConfigs.hasVar(varName)) { + // TODO: with errors shown in UI the following check could be removed: + return false; + } + try { + edide.mmConfigs.activateVar(varName, value); + trackState.i += varLength + 2; + return true; + } catch (error) { + err = error; + //throw err if edide.inEditor + return false; + } + }; + +return mmParserSpecial; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmNote = (function (edide, mmNote) {Object.defineProperty(this, 'module_name', {value:'mmNote'}); + this.fromChar = (char) => { + return this.fromKeyCode(char.charCodeAt(0)); + }; + + this.fromKeyCode = (key) => { + var noteInd, ref; + if (typeof (noteInd = edide.mmKeyboard.getNoteInd(key)) === 'number') { + return (ref = edide.noteFreq.notes[noteInd]) != null ? ref[0] : void 0; + } + }; + +return mmNote; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmParser = (function (edide, mmParser) {Object.defineProperty(this, 'module_name', {value:'mmParser'}); + var getNoteLength, nonBreakingSpace, processTrack, revar, space, unvar; + + ({revar, unvar} = edide.mmState); + + getNoteLength = (row, noteInd) => { + var char, length; + length = 1; + while (char = row[++noteInd]) { + if (char === edide.mmKeyboard.special.long) { + length++; + } else { + break; + } + } + return length; + }; + + ({space, nonBreakingSpace} = edide.chars); + + // Processes one char in a track, and iteratively calls itself if needed. + // ccs - "current column state" - inline chord + played? + // ts - track state: char index, configs + processTrack = (track, ccs, ts) => { + var bef, chord, groupingChars, keyCode, lastSpace, note, repeat, repeatStart; + if (!track[ts.i]) { + return; + } + if (ts.skip) { // comment or erroneous chars + return; + } + // bracket chords + switch (track[ts.i]) { + case '{': + return ts.i += edide.mmParserSpecial.config(track.slice(ts.i), ts); // parseConfigs + case '*': + if (ts.repeat != null) { + // inside a repeating pattern + ts.repeat--; + if (ts.repeat > 0) { + // still repeats left to do, start from the beginning + ts.i = ts.iStart = ts.repeatStart; // repeats done + } else { + ts.repeat = ts.repeatStart = null; + ts.i++; // step over '*' so won't end up starting repeats again + } + } else { + if (isNaN(repeat = parseInt(track.slice(ts.i + 1)))) { + ts.i++; // unable to parse number of repeats, skip them + } else { + // initialize new repeating patter (-1 because repeat pattern already played once) + ts.repeat = repeat - 1; + // search for beginning of repeat group + bef = track.slice(0, ts.i); + groupingChars = ['(', space, nonBreakingSpace, '*']; + lastSpace = Math.max(...groupingChars.map((c) => { + return bef.lastIndexOf(c); + })); + repeatStart = lastSpace !== -1 ? lastSpace + 1 : 0; // beginning of row if no grouping char found + // set track state at the beginning of repeats + ts.i = ts.iStart = ts.repeatStart = repeatStart; + } + } + return processTrack(track, ccs, ts); + case '[': + ccs.chord = []; + ts.i++; + return processTrack(track, ccs, ts); + case ']': + ts.i++; + ({chord} = ccs); + if (!chord) { // illegal - missing beginning [ + return processTrack(track, ccs, ts); + } + ccs.chord = null; + if (chord.length) { + if (!unvar.preprocessing) { + revar.playNote = [chord, getNoteLength(track, ts.i)]; + } + //edide.mmInstrument.playNote chord, getNoteLength track, ts.i + ccs.played = true; + } else { + processTrack(track, ccs, ts); + } + return; + case edide.mmKeyboard.special.var: + if (edide.mmParserSpecial.var(track, ts)) { + processTrack(track, ccs, ts); // recursive, since next char could be another var, e.g. \:bass::minor: + } else { + ts.skip = true; // parse error + } + return; + case edide.mmKeyboard.special.comment: + return ts.skip = true; + } + // TODO: merge switch and bottom code OR put them in a different functions + if (!(keyCode = track.charCodeAt(ts.i))) { + return; + } + ts.i++; + if (note = edide.mmNote.fromKeyCode(keyCode)) { + if (ccs.chord) { + ccs.chord.push(note); + processTrack(track, ccs, ts); + } else { + if (!unvar.preprocessing) { + revar.playNote = [note, getNoteLength(track, ts.i)]; + } + //edide.mmInstrument.playNote note, getNoteLength track, ts.i + ccs.played = true; + } + } else if (edide.mmKeyboard.isPauseKey(keyCode)) { + ccs.played = true; // "play silence" + // meaningless char + } else { + processTrack(track, ccs, ts); + } + }; + + // TODO figure sheetStart != 0 -- maybe makes more sense to remove textarea first + this.splitSections = (str) => { + var i, j, prevInd, ref, row, section, sections; + str = str.replace('&\n', ''); // TODO fix row tracking with &\n + sections = []; + section = null; + row = 0; + prevInd = 0; + for (i = j = 0, ref = str.length; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) { + if (!(str[i] === '\n' || i === str.length)) { + continue; + } + if (str[i - 1] === '\n') { + if (section != null) { + sections.push(section); + } + section = null; + } + if (i > prevInd) { + if (section == null) { + section = { + row: row, + tracks: [] + }; + } + section.tracks.push(str.slice(prevInd, i)); + } + row++; + prevInd = i + 1; + } + if (section != null) { + sections.push(section); + } + sections.row = 0; + return sections; + }; + + this.play = (song, sectionInd, trackStates) => { + var ccs, section; + if (!unvar.playing) { + return; + } + revar.highlight = null; + sectionInd = sectionInd || 0; + if (typeof song === 'string') { + song = this.splitSections(song); + } + section = song[sectionInd]; + if (!section) { // song finished + if (!unvar.preprocessing) { + revar.playing = false; + } + return; + } + if (!Array.isArray(trackStates)) { + trackStates = section.tracks.map(() => { + return { + i: 0 // initi track indices on first call to section + }; + }); + } + // init @play ccs + ccs = {}; // chord, played # TODO change back to chord: [C3, D3] and [].played = true + // OR: why not just ts.chord? + section.tracks.forEach((track, tInd) => { + var conf, i, iStart; + if (conf = trackStates[tInd].conf) { + // config row and already parsed (NOTE: config row can only have one config object and nothing else) + return edide.mmConfigs.activate(conf); + } else { + trackStates[tInd].iStart = trackStates[tInd].i; + processTrack(track, ccs, trackStates[tInd]); + ({iStart, i} = trackStates[tInd]); + if (i > iStart) { + return revar.highlight = [section.row + tInd, iStart, i - 1]; + } + } + }); + if (ccs.played) { + if (unvar.preprocessing) { + this.play(song, sectionInd, trackStates); + } else { + edide.setTimeout(() => { + return this.play(song, sectionInd, trackStates); + }, unvar.beatDelay); + } + } else { + // using timeout fixes bug where revar.playing is set false in same exec where it's set true (infinite loop) + this.play(song, sectionInd + 1); + } + }; + +return mmParser; +}).call(MODSELF={}, edide, MODSELF); + +edide.moduleGate = (function (edide, moduleGate) {Object.defineProperty(this, 'module_name', {value:'moduleGate'}); + if (!edide.inEditor) { + return this; + } + + this.root; // module that is edited in root + + this.rootName; + + this.active; // module that is currently being edited (can be root or in window) + + this.activeName; + + this.executing; + + this.executingName; + +return moduleGate; +}).call(MODSELF={}, edide, MODSELF); + +edide.rejectIfRecompiled = (function (edide, rejectIfRecompiled) { + if (!edide.inEditor) { + return () => {}; + } + + return (promise) => { + var recompiled, rootName; + ({rootName} = edide.moduleGate); + recompiled = false; + edide.editorModule.editor_events.on('before_recompile', () => { + return recompiled = true; + }); + return promise.then(function(arg) { + if (recompiled || rootName !== edide.moduleGate.rootName) { // root module changed + return Promise.reject(); // quiet rejection; no need to show error + } else { + return arg; // arg get wrapped in promise + } + }); + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.promise = (function (edide, promise) {Object.defineProperty(this, 'module_name', {value:'promise'}); + var localPromise, ref; + + localPromise = edide.global.origPromise = (ref = edide.global.origPromise) != null ? ref : edide.global.Promise; + + this.new = function(cb) { + if (edide.inEditor) { + return edide.rejectIfRecompiled(new Promise(cb)); // don't fire cb if code has been re-executed in the meantime + } else { + return new Promise(cb); + } + }; + + this.all = function(cbArray) { + if (edide.inEditor) { // check that after resolved, still editing same module + return edide.rejectIfRecompiled(Promise.all(cbArray)); + } else { + return Promise.all(cbArray); + } + }; + + this.resolve = Promise.resolve.bind(Promise); + + this.reject = Promise.reject.bind(Promise); + +return promise; +}).call(MODSELF={}, edide, MODSELF); + +edide.qs = (function (edide, qs) { + return (selector, el = document) => { + return el.querySelector(selector); + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.scriptContainer = (function (edide, scriptContainer) { + var createContainer, ref; + + createContainer = () => { + var s; + s = document.createElement('div'); + s.id = 'scripts'; + return s; + }; + return (ref = edide.qs('#scripts')) != null ? ref : document.body.appendChild(createContainer()); + +}).call(MODSELF={}, edide, MODSELF); + +edide.scriptAdd = (function (edide, scriptAdd) { + return (src, cb) => { + var el; + el = document.createElement('script'); + edide.scriptContainer.appendChild(el); + if (cb) { + el.onload = cb; + } + el.type = 'application/javascript'; + el.src = src; + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.requireScript = (function (edide, requireScript) { + var base; + + if ((base = edide.global).requireScriptPromises == null) { + base.requireScriptPromises = new Map; + } + + return (scriptSrc) => { + var promise; + if (promise = requireScriptPromises.get(scriptSrc)) { + return promise; + } else { + requireScriptPromises.set(scriptSrc, promise = edide.promise.new((resolve) => { + return edide.scriptAdd(scriptSrc, resolve); + })); + return promise.catch((err) => { + edide.showError(err); + return requireScriptPromises.delete(scriptSrc); + }); + } + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.mmPipe = (function (edide, mmPipe) {Object.defineProperty(this, 'module_name', {value:'mmPipe'}); + var dist, lowpass, panner, react, revar, reverber, unvar; + + ({revar, unvar, react} = edide.mmState.init()); + + dist = lowpass = reverber = panner = null; + + this.initPipe = () => { + lowpass = new Tone.Filter(unvar.lowpass, 'lowpass', -12); + dist = new Tone.Distortion(unvar.distortion); + panner = new Tone.Panner(); + panner.connect(dist); + dist.connect(lowpass); + lowpass.toMaster(); + this.output = lowpass; + revar.pipeReady = true; + return edide.onUnload(() => { + if (dist != null) { + if (typeof dist.dipose === "function") { + dist.dipose(); + } + } + if (lowpass != null) { + if (typeof lowpass.dispose === "function") { + lowpass.dispose(); + } + } + return panner != null ? typeof panner.dispose === "function" ? panner.dispose() : void 0 : void 0; + }); + }; + + this.initInstrument = (instrument) => { + instrument.connect(panner); + edide.onUnload(() => { + return instrument != null ? instrument.disconnect() : void 0; + }); + return instrument; + }; + + revar.panner = () => { + return revar.balance; + }; + + react('panner', () => { + revar.panner; + return panner != null ? panner.pan.value = revar.panner : void 0; + }); + + react('pipe distortion', () => { + var ref; + revar.distortion; + revar.lowpass; + if (dist != null) { + dist.distortion = revar.distortion; + } + return lowpass != null ? (ref = lowpass.frequency) != null ? ref.linearRampTo(revar.lowpass, 0) : void 0 : void 0; + }); + +return mmPipe; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmInstruments = (function (edide, mmInstruments) {Object.defineProperty(this, 'module_name', {value:'mmInstruments'}); + + var defaultUrl = 'https://nbrosowsky.github.io/tonejs-instruments/samples/' + + var { revar, unvar, react } = edide.mmState + + var defaultInstrument = 'electric-guitar' + + this.initInstrument = async (resolve) => { + await edide.requireScript('https://cdnjs.cloudflare.com/ajax/libs/tone/13.8.9/Tone.js') + edide.mmPipe.initPipe() + } + + var instrumentCache = edide.keep({}) + + this.createNew = () => { + + var {name} = unvar.instrumentConf + var instrument, endOfPipe + var instrumentConf = this.instruments[name] + + if (instrumentConf.module_name) { + var res = instrumentConf.init() + if (Array.isArray(res)) { + instrument = res[0] + endOfPipe = res[1] + } else { + instrument = endOfPipe = res + } + } else if (instrumentCache[name]) { + instrument = endOfPipe = instrumentCache[name] + } else { + var noteFiles = buildNotes(instrumentConf) + revar.instrumentsLoading++ + var inst = new Tone.Sampler(noteFiles, { //edide.mmInstrumentssAll[name] + "release" : 1, + "baseUrl" : instrumentConf.url || defaultUrl + name + '/', + "onload" : () => revar.instrumentsLoading-- + }) + inst.soundFontInstrument = true + instrument = endOfPipe = instrumentCache[name] = inst //[inst, inst] + } + + edide.mmPipe.initInstrument(endOfPipe) + + return instrument + } + + this.isReady = () => { + var { current } = this + return current && (typeof current.loaded == 'undefined' || current.loaded === true) + } + + function buildNotes({startNote, notes, step, skipNotes}) { + var [startInd] = edide.noteFreq.findNote(startNote) + var noteFiles = {} + if (Array.isArray(notes)) { + notes.forEach(note => { + noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]' + }) + } else { + for (let i=0; i < notes*step; i+=step) { + let note = edide.noteFreq.notes[startInd + i][0]; + if (skipNotes && skipNotes.has(note)) + continue + noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]' + } + } + return noteFiles + } + + this.instruments = edide.instrumentConfigs + + this.instrumentList = Object.values(this.instruments) + + react('active instrument config', () => { + revar.instrumentConf = this.instruments[revar.instrument] // conf + }) + +return mmInstruments; +}).call(MODSELF={}, edide, MODSELF); + +edide.cloneSibling = (function (edide, cloneSibling) { + return (srcObj) => { + var o; + o = Object.create(Object.getPrototypeOf(srcObj)); + Object.assign(o, srcObj); + return o; + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.times = (function (edide, times) { + return (timesNum, action) => { + while (timesNum-- > 0) { + action(timesNum + 1); + } + }; + +}).call(MODSELF={}, edide, MODSELF); + +edide.sleep = (function (edide, sleep) { + var sleep; + + sleep = (ms) => { + var resolve, timeout; + timeout = resolve = null; + return edide.promise.new((res) => { + resolve = res; + return timeout = edide.setTimeout(ms, res); + }); + }; + + return sleep; + +}).call(MODSELF={}, edide, MODSELF); + +edide.mmInstrument = (function (edide, mmInstrument) {Object.defineProperty(this, 'module_name', {value:'mmInstrument'}); + var cloneOrCreateInstrument, getInstruments, instruments, play, react, revar, unvar, updateVolAndTune; + + instruments = {}; // name: [instrument instances...] + + ({unvar, revar, react} = edide.mmState); + + revar.bpm = () => { + return revar.pace; + }; + + revar.beatDelay = () => { + return (1 / revar.bpm) * 60 * 1000; + }; + + react(() => {}); + + updateVolAndTune = (inst) => { + var detune, volume; + ({volume, detune} = unvar); + if ((detune != null) && (inst.detune != null)) { + inst.set("detune", detune); + } + if ((volume != null) && (inst.volume != null)) { + return inst.set("volume", volume); + } + }; + + react(() => { + var inst, insts, j, len, name; + revar.volume; + revar.detune; + for (name in instruments) { + insts = instruments[name]; + for (j = 0, len = insts.length; j < len; j++) { + inst = insts[j]; + updateVolAndTune(inst); + } + } + }); + + react('create first instrument', () => { + var name, ref; + if (!(name = (ref = revar.instrumentConf) != null ? ref.name : void 0)) { // e.g. illegal instrument name + return edide.showError(`Unknown instrument: ${unvar.instrument}`); + } + if (revar.pipeReady && !instruments[name]) { + return instruments[name] = [edide.mmInstruments.createNew()]; + } + }); + + cloneOrCreateInstrument = (name) => { + var inst; + inst = instruments[name][0].soundFontInstrument ? (inst = edide.cloneSibling(instruments[name][0]), inst.isPlaying = false, inst) : edide.mmInstruments.createNew(); + updateVolAndTune(inst); + return inst; + }; + + getInstruments = (n) => { + var all, free, name; + ({name} = unvar.instrumentConf); + all = instruments[name]; + free = all.filter((i) => { + return !i.isPlaying; + }); + edide.times(n - free.length, () => { + var inst; + free.push(inst = cloneOrCreateInstrument(name)); + return all.push(inst); + }); + return free.slice(0, n); + }; + + this.playChord = (chord, noteLength = 1) => {}; + + this.playNote = (chord, noteLength = 1) => { + var ind, inst, insts, j, len, ref; + if (!Array.isArray(chord)) { + chord = [chord]; + } + ref = insts = getInstruments(chord.length); + for (ind = j = 0, len = ref.length; j < len; ind = ++j) { + inst = ref[ind]; + play(inst, chord[ind], noteLength); + } + }; + + play = async(instrument, note, length) => { + var err; + instrument.isPlaying = note; // true + try { + instrument.triggerAttackRelease(note, (length * unvar.beatDelay) / 1000); + } catch (error) { + err = error; + err.message = `Error in playing note ${note}, '${unvar.instrumentConf.name}' probably not loaded yet`; + edide.showError(err); + } + revar.note = note; + await edide.sleep(unvar.nextDelay); + return instrument.isPlaying = false; + }; + +return mmInstrument; +}).call(MODSELF={}, edide, MODSELF); + +edide.mmPlayer = (function (edide, mmPlayer) {Object.defineProperty(this, 'module_name', {value:'mmPlayer'}); + var react, revar, unvar; + + ({revar, unvar, react} = edide.mmState.init()); + + this.play = (str) => { + revar.sheet = str; + return revar.playing = true; + }; + + react('play from sheet', () => { + if (!revar.playing) { + return; + } + edide.mmConfigs.init(); + revar.preprocessing = true; + return edide.setTimeout(() => { // infinite revar.playing loop + edide.mmParser.play(unvar.sheet); + return revar.preprocessing = 'done'; + }); + }); + + react('play notes/chords', () => { + var chord, playNote, playing, preprocessing, time; + ({playNote, playing, preprocessing} = revar); + if (!(playNote && playing && preprocessing === false)) { + return; + } + [chord, time] = revar.playNote; + return edide.mmInstrument.playNote(chord, time); + }); + + this.toggle = () => { + return revar.playing = !unvar.playing; + }; + + revar.instrumentsLoading; + + react('play after preprocess', () => { + var instrumentsLoading, preprocessing; + ({instrumentsLoading, preprocessing} = revar); + if (!(preprocessing === 'done' && instrumentsLoading === 0)) { + return; + } + unvar.preprocessing = false; + edide.mmConfigs.reset(); + return edide.mmParser.play(unvar.sheet); + }); + +return mmPlayer; +}).call(MODSELF={}, edide, MODSELF); + +edide.waves = (function (edide, waves) {Object.defineProperty(this, 'module_name', {value:'waves'}); + + edide.global.music = this + + edide.mmEffects + + var { revar, unvar, react } = edide.mmState + + var playQueue = [] + + this.play = (str) => { + if (!unvar.pipeReady) return playQueue.push(str) + revar.playing = true + + edide.mmPlayer.play(str) + } + + this.stop = () => revar.playing = false + + edide.mmInstruments.initInstrument() + + react(() => { + if(!revar.pipeReady) return + edide.mmConfigs.reset() + this.play(playQueue.join("\n\n")) // JSON.stringify(initialSettings) + }) +return waves; +}).call(MODSELF={}, edide, MODSELF); + +edide.wave = (function (edide, wave) { + + var parent = { + play: function(){ + edide.waves.play(this.sheet) + return this + }, + stop: function(){ + edide.waves.stop(this.sheet) + return this + }, + blur: function(val){ + this.sheet = `:blur ${val}:` + this.sheet + return this + }, + itch: function(val){ + this.sheet = `:itch ${val}:` + this.sheet + return this + }, + long: function(val){ // note delay in seconds + this.sheet = `:beatDelay ${val*1000}:` + this.sheet + return this + }, + pace: function(val) { // note delay in beats per minute + this.sheet = `:pace ${val}:` + this.sheet + return this + }, + vary: function(val){ + this.sheet = `:detune ${val}:` + this.sheet + return this + }, + loud: function(val){ // increase (>0) or decrease (<0) amplitude in decibels + this.sheet = `:volume ${val}:` + this.sheet + return this + }, + balance: function(val){ + this.sheet = `:balance ${val}:` + this.sheet + return this + } + } + + return edide.global.wave = (str) => { + edide.mmConfigs.reset() + var obj = Object.create(parent) + obj.sheet = str + return obj + } + +}).call(MODSELF={}, edide, MODSELF); edide.global.wave = edide.wave; })() \ No newline at end of file