coffee shop code
This commit is contained in:
87
index.html
Normal file
87
index.html
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/nexusui@latest/dist/NexusUI.js"></script>
|
||||||
|
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> -->
|
||||||
|
<title>Document</title>
|
||||||
|
<style>
|
||||||
|
.osc{
|
||||||
|
display: flex;
|
||||||
|
margin: 0px 30px 45px 30px;
|
||||||
|
}
|
||||||
|
.osc > * {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.row{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin:20px;
|
||||||
|
}
|
||||||
|
.row > *{
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="teal lighten-3">
|
||||||
|
<div id="name"> Oscillator 1</div>
|
||||||
|
<div class="osc">
|
||||||
|
<div class="row">
|
||||||
|
<div id="decay1">Decay</div>
|
||||||
|
<div id="attack1">Attack</div>
|
||||||
|
<div id="sustain1">Sustain</div>
|
||||||
|
<div id="release1">Release</div>
|
||||||
|
<div id="osc1"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div id="dist1">Distortion</div>
|
||||||
|
<div id="lfo1">LFO</div>
|
||||||
|
<div id="reverb1">Reverb</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="name"> Oscillator 2</div>
|
||||||
|
|
||||||
|
<div class="osc">
|
||||||
|
<div class="row">
|
||||||
|
<div id="decay2">Decay</div>
|
||||||
|
<div id="attack2">Attack</div>
|
||||||
|
<div id="sustain2">Sustain</div>
|
||||||
|
<div id="release2">Release</div>
|
||||||
|
<div id="osc2"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div id="dist2">Distortion</div>
|
||||||
|
<div id="lfo2">LFO</div>
|
||||||
|
<div id="reverb2">Reverb</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="target"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script
|
||||||
|
src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.7.62/Tone.js"
|
||||||
|
integrity="sha512-0Z5XeKr/hpHHUWlTlqTyJZahRipro3bBva1vPkK7w6h4C55TdLMZnvI0YNiAFXUYXRiJ2rMl4Xmn3pgviit3Ow=="
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script src="scripts/webmidi.min.js"></script>
|
||||||
|
|
||||||
|
<script src="scripts/scripts.js"></script>
|
||||||
|
<script src="scripts/osc1.js"></script>
|
||||||
|
<script src="scripts/osc2.js"></script>
|
||||||
|
<script src="scripts/midi.js"></script>
|
||||||
|
|
||||||
|
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> -->
|
||||||
|
|
||||||
|
</html>
|
||||||
34
scripts/midi.js
Normal file
34
scripts/midi.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
var midi, data;
|
||||||
|
// request MIDI access
|
||||||
|
if (navigator.requestMIDIAccess) {
|
||||||
|
navigator.requestMIDIAccess({
|
||||||
|
sysex: false
|
||||||
|
}).then(onMIDISuccess, onMIDIFailure);
|
||||||
|
} else {
|
||||||
|
alert("No MIDI support in your browser.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// midi functions
|
||||||
|
function onMIDISuccess(midiAccess) {
|
||||||
|
// when we get a succesful response, run this code
|
||||||
|
midi = midiAccess; // this is our raw MIDI data, inputs, outputs, and sysex status
|
||||||
|
|
||||||
|
var inputs = midi.inputs.values();
|
||||||
|
// loop over all available inputs and listen for any MIDI input
|
||||||
|
for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
|
||||||
|
// each time there is a midi message call the onMIDIMessage function
|
||||||
|
input.value.onmidimessage = onMIDIMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMIDIFailure(error) {
|
||||||
|
// when we get a failed response, run this code
|
||||||
|
console.log("No access to MIDI devices or your browser doesn't support WebMIDI API. Please use WebMIDIAPIShim " + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMIDIMessage(message) {
|
||||||
|
data = message.data; // this gives us our [command/channel, note, velocity] data.
|
||||||
|
console.log('MIDI data', data); // MIDI data [144, 63, 73]
|
||||||
|
midiNote(data[1], data[2]);
|
||||||
|
midiNote2(data[1], data[2]);
|
||||||
|
}
|
||||||
88
scripts/osc1.js
Normal file
88
scripts/osc1.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
var dist1_1;
|
||||||
|
var filter1_1;
|
||||||
|
var reverb1_1 = 1;
|
||||||
|
synth1 = new Tone.FMSynth({
|
||||||
|
oscillator: {
|
||||||
|
type: "sawtooth",
|
||||||
|
detune: 0,
|
||||||
|
},
|
||||||
|
envelope: {
|
||||||
|
attack: 0,
|
||||||
|
decay: 0,
|
||||||
|
sustain: 0,
|
||||||
|
release: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
}).toMaster();
|
||||||
|
|
||||||
|
piano.on('change',function(keyValue) {
|
||||||
|
if (keyValue.state == true) { // If Key is down
|
||||||
|
synth1.triggerAttackRelease(Tone.Frequency(keyValue.note, "midi").toNote()); // Play note
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Midi input
|
||||||
|
function midiNote(note, vel){
|
||||||
|
if(vel !=0){ // Skip Key up, If velocity is 0 then play
|
||||||
|
synth1.triggerAttackRelease(Tone.Frequency(note, "midi").toNote()); // Play note
|
||||||
|
piano.toggleKey(note, true)
|
||||||
|
}else{
|
||||||
|
piano.toggleKey(note, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//filters
|
||||||
|
function updateFilter1(){
|
||||||
|
var filter1 = new Tone.AutoFilter(filter1_1).start(); //LFO
|
||||||
|
var reverb1 = new Tone.Reverb(reverb1_1);
|
||||||
|
var distortion1 = new Tone.Distortion(dist1_1); //DIST
|
||||||
|
// connect the player to the filter, distortion and then to the master output
|
||||||
|
synth1.chain(filter1, distortion1, reverb1, Tone.Destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
var sus1_d = new Nexus.Dial('#sustain1', dial_settings1)
|
||||||
|
var dec1_d = new Nexus.Dial('#decay1', dial_settings1)
|
||||||
|
var atk1_d = new Nexus.Dial('#attack1', dial_settings1)
|
||||||
|
var rel1_d = new Nexus.Dial('#release1', dial_settings1)
|
||||||
|
// var tune1_d = new Nexus.Dial('#tune1', dial_settings1)
|
||||||
|
var select1 = new Nexus.Select('#osc1', dropdown_osc)
|
||||||
|
|
||||||
|
var dist1 = new Nexus.Dial('#dist1', distortion_settings)
|
||||||
|
var lfo1 = new Nexus.Dial('#lfo1', dial_settings1)
|
||||||
|
var reverb1_d = new Nexus.Dial('#reverb1', reverb_settings)
|
||||||
|
// When controls change
|
||||||
|
|
||||||
|
sus1_d.on('change',function(value) {
|
||||||
|
synth1.envelope.attack = value;
|
||||||
|
});
|
||||||
|
dec1_d.on('change',function(value) {
|
||||||
|
synth1.envelope.decay = value;
|
||||||
|
});
|
||||||
|
atk1_d.on('change',function(value) {
|
||||||
|
synth1.envelope.attack = value;
|
||||||
|
});
|
||||||
|
rel1_d.on('change',function(value) {
|
||||||
|
synth1.envelope.release = value;
|
||||||
|
});
|
||||||
|
// tune1_d.on('change',function(value) {
|
||||||
|
// synth1.oscillator.detune = value;
|
||||||
|
// });
|
||||||
|
select1.on('change',function(value) {
|
||||||
|
synth1.oscillator.type = value.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Effect knobs
|
||||||
|
dist1.on('change',function(value) {
|
||||||
|
dist1_1 = value.toFixed(1);
|
||||||
|
typewatch(function(){updateFilter1();}, 100 );
|
||||||
|
|
||||||
|
});
|
||||||
|
lfo1.on('change',function(value) {
|
||||||
|
filter1_1 = value.toFixed(1);
|
||||||
|
typewatch(function(){updateFilter1();}, 100 );
|
||||||
|
});
|
||||||
|
reverb1_d.on('change',function(value) {
|
||||||
|
reverb1_1 = value.toFixed(0);
|
||||||
|
typewatch(function(){updateFilter1();}, 100 );
|
||||||
|
});
|
||||||
84
scripts/osc2.js
Normal file
84
scripts/osc2.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
var dist2_2;
|
||||||
|
var filter2_2;
|
||||||
|
var reverb2_2 = 1;
|
||||||
|
synth2 = new Tone.FMSynth({
|
||||||
|
oscillator: {
|
||||||
|
type: "sawtooth",
|
||||||
|
detune: 0,
|
||||||
|
},
|
||||||
|
envelope: {
|
||||||
|
attack: 0,
|
||||||
|
decay: 0,
|
||||||
|
sustain: 0,
|
||||||
|
release: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
}).toMaster();
|
||||||
|
|
||||||
|
piano.on('change',function(keyValue) {
|
||||||
|
if (keyValue.state == true) { // If Key is down
|
||||||
|
synth2.triggerAttackRelease(Tone.Frequency(keyValue.note, "midi").toNote()); // Play note
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Midi input
|
||||||
|
function midiNote2(note, vel){
|
||||||
|
if(vel !=0){ // Skip Key up, If velocity is 0 then play
|
||||||
|
synth2.triggerAttackRelease(Tone.Frequency(note, "midi").toNote()); // Play note
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//filters
|
||||||
|
function updateFilter2(){
|
||||||
|
var filter2 = new Tone.AutoFilter(filter2_2).start(); //LFO
|
||||||
|
var reverb2 = new Tone.Reverb(reverb2_2);
|
||||||
|
var distortion2 = new Tone.Distortion(dist2_2); //DIST
|
||||||
|
// connect the player to the filter, distortion and then to the master output
|
||||||
|
synth2.chain(filter2, distortion2, reverb2, Tone.Destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
var sus2_d = new Nexus.Dial('#sustain2', dial_settings1)
|
||||||
|
var dec2_d = new Nexus.Dial('#decay2', dial_settings1)
|
||||||
|
var atk2_d = new Nexus.Dial('#attack2', dial_settings1)
|
||||||
|
var rel2_d = new Nexus.Dial('#release2', dial_settings1)
|
||||||
|
// var tune2_d = new Nexus.Dial('#tune2', dial_settings2)
|
||||||
|
var select2 = new Nexus.Select('#osc2', dropdown_osc)
|
||||||
|
|
||||||
|
var dist2 = new Nexus.Dial('#dist2', distortion_settings)
|
||||||
|
var lfo2 = new Nexus.Dial('#lfo2', dial_settings1)
|
||||||
|
var reverb2_d = new Nexus.Dial('#reverb2', reverb_settings)
|
||||||
|
// When controls change
|
||||||
|
|
||||||
|
sus2_d.on('change',function(value) {
|
||||||
|
synth2.envelope.attack = value;
|
||||||
|
});
|
||||||
|
dec2_d.on('change',function(value) {
|
||||||
|
synth2.envelope.decay = value;
|
||||||
|
});
|
||||||
|
atk2_d.on('change',function(value) {
|
||||||
|
synth2.envelope.attack = value;
|
||||||
|
});
|
||||||
|
rel2_d.on('change',function(value) {
|
||||||
|
synth2.envelope.release = value;
|
||||||
|
});
|
||||||
|
// tune2_d.on('change',function(value) {
|
||||||
|
// synth2.oscillator.detune = value;
|
||||||
|
// });
|
||||||
|
select2.on('change',function(value) {
|
||||||
|
synth2.oscillator.type = value.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Effect knobs
|
||||||
|
dist2.on('change',function(value) {
|
||||||
|
dist2_2 = value.toFixed(1);
|
||||||
|
typewatch(function(){updateFilter2();}, 100 );
|
||||||
|
|
||||||
|
});
|
||||||
|
lfo2.on('change',function(value) {
|
||||||
|
filter2_2 = value.toFixed(1);
|
||||||
|
typewatch(function(){updateFilter2();}, 100 );
|
||||||
|
});
|
||||||
|
reverb2_d.on('change',function(value) {
|
||||||
|
reverb2_2 = value.toFixed(0);
|
||||||
|
typewatch(function(){updateFilter2();}, 100 );
|
||||||
|
});
|
||||||
47
scripts/scripts.js
Normal file
47
scripts/scripts.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//Piano roll
|
||||||
|
var piano = new Nexus.Piano('#target',{
|
||||||
|
'size': [750,125],
|
||||||
|
'mode': 'button', // 'button', 'toggle', or 'impulse'
|
||||||
|
'lowNote': 24,
|
||||||
|
'highNote': 100
|
||||||
|
})
|
||||||
|
var dial_settings1 = {
|
||||||
|
'size': [50,50],
|
||||||
|
'interaction': 'radial',
|
||||||
|
'mode': 'relative',
|
||||||
|
'min': 0,
|
||||||
|
'max': 10,
|
||||||
|
'step': 0,
|
||||||
|
'value': 0
|
||||||
|
}
|
||||||
|
var dropdown_osc = {
|
||||||
|
'size': [100,30],
|
||||||
|
'options': ['sawtooth', 'sawtooth2', 'sawtooth3', 'sawtooth4','sine', 'sine2', 'sine3', 'sine4', 'square', 'square2', 'square3', 'square4', 'triangle', 'triangle2', 'triangle3', 'triangle4']
|
||||||
|
}
|
||||||
|
var distortion_settings = {
|
||||||
|
'size': [50,50],
|
||||||
|
'interaction': 'radial', // "radial", "vertical", or "horizontal"
|
||||||
|
'mode': 'relative', // "absolute" or "relative"
|
||||||
|
'min': 0,
|
||||||
|
'max': 1,
|
||||||
|
'step': 0.1,
|
||||||
|
'value': 0
|
||||||
|
}
|
||||||
|
var reverb_settings = {
|
||||||
|
'size': [50,50],
|
||||||
|
'interaction': 'radial', // "radial", "vertical", or "horizontal"
|
||||||
|
'mode': 'relative', // "absolute" or "relative"
|
||||||
|
'min': 1,
|
||||||
|
'max': 10,
|
||||||
|
'step': 0.1,
|
||||||
|
'value': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var typewatch = function(){
|
||||||
|
var timer = 0;
|
||||||
|
return function(callback, ms){
|
||||||
|
clearTimeout (timer);
|
||||||
|
timer = setTimeout(callback, ms);
|
||||||
|
}
|
||||||
|
}();
|
||||||
133
scripts/scripts_obs.js
Normal file
133
scripts/scripts_obs.js
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
const synth = new Tone.FMSynth().toMaster();
|
||||||
|
var sus1 = 0;
|
||||||
|
var atk1 = 0;
|
||||||
|
var wav = "sawtooth";
|
||||||
|
// var synth = new Tone.AMSynth({
|
||||||
|
// oscillator: {
|
||||||
|
// type: "square",
|
||||||
|
// },
|
||||||
|
// envelope: {
|
||||||
|
// attack: atk1,
|
||||||
|
// decay: 0.1,
|
||||||
|
// sustain: sus1,
|
||||||
|
// release: 0.1,
|
||||||
|
// },
|
||||||
|
// modulation: {
|
||||||
|
// type: "square",
|
||||||
|
// },
|
||||||
|
// }).toMaster();
|
||||||
|
// const synth = new Tone.FMSynth().toDestination();
|
||||||
|
// synth.type = "pwm";
|
||||||
|
|
||||||
|
var activeSynths = {};
|
||||||
|
const createPiano = (lowNote, highNote) => {
|
||||||
|
const newPiano = new Nexus.Piano("#target", {
|
||||||
|
size: [500, 125],
|
||||||
|
mode: "button",
|
||||||
|
lowNote,
|
||||||
|
highNote,
|
||||||
|
});
|
||||||
|
|
||||||
|
return newPiano;
|
||||||
|
};
|
||||||
|
|
||||||
|
let lowNote = 72;
|
||||||
|
let highNote = 84;
|
||||||
|
let piano = createPiano(lowNote, highNote);
|
||||||
|
|
||||||
|
synth.triggerRelease();
|
||||||
|
|
||||||
|
|
||||||
|
const keyMapper = {
|
||||||
|
a: 0,
|
||||||
|
w: 1,
|
||||||
|
s: 2,
|
||||||
|
e: 3,
|
||||||
|
d: 4,
|
||||||
|
f: 5,
|
||||||
|
t: 6,
|
||||||
|
g: 7,
|
||||||
|
y: 8,
|
||||||
|
h: 9,
|
||||||
|
u: 10,
|
||||||
|
j: 11,
|
||||||
|
k: 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
piano.on("change", (k) => {
|
||||||
|
if (k.state) {
|
||||||
|
if (!activeSynths[k.note]) {
|
||||||
|
activeSynths[k.note] = new Tone.AMSynth({
|
||||||
|
oscillator: {
|
||||||
|
type: wav,
|
||||||
|
},
|
||||||
|
envelope: {
|
||||||
|
attack: atk1,
|
||||||
|
decay: 0.1,
|
||||||
|
sustain: sus1,
|
||||||
|
release: 0.1,
|
||||||
|
},
|
||||||
|
modulation: {
|
||||||
|
type: wav,
|
||||||
|
},
|
||||||
|
}).toMaster();
|
||||||
|
}
|
||||||
|
activeSynths[k.note].triggerAttack(k.note);
|
||||||
|
document.querySelector(".innernote").innerHTML =
|
||||||
|
k.note + " - " + activeSynths[k.note].triggerAttack(k.note);
|
||||||
|
} else {
|
||||||
|
activeSynths[k.note].triggerRelease();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var sustain1 = new Nexus.Dial('#sus1',{
|
||||||
|
'size': [75,75],
|
||||||
|
'interaction': 'radial', // "radial", "vertical", or "horizontal"
|
||||||
|
'mode': 'relative', // "absolute" or "relative"
|
||||||
|
'min': 0,
|
||||||
|
'max': 1,
|
||||||
|
'step': 0,
|
||||||
|
'value': 0
|
||||||
|
})
|
||||||
|
|
||||||
|
sustain1.on('change',function(v) {
|
||||||
|
sus1 = v;
|
||||||
|
})
|
||||||
|
var attack1 = new Nexus.Dial('#attack1',{
|
||||||
|
'size': [75,75],
|
||||||
|
'interaction': 'radial', // "radial", "vertical", or "horizontal"
|
||||||
|
'mode': 'relative', // "absolute" or "relative"
|
||||||
|
'min': 0,
|
||||||
|
'max': 1,
|
||||||
|
'step': 0,
|
||||||
|
'value': 0
|
||||||
|
})
|
||||||
|
|
||||||
|
attack1.on('change',function(va) {
|
||||||
|
atk1 = va;
|
||||||
|
})
|
||||||
|
|
||||||
|
var select = new Nexus.Select('#waves',{
|
||||||
|
'size': [100,30],
|
||||||
|
'options': ['sine','sawtooth', 'square']
|
||||||
|
})
|
||||||
|
|
||||||
|
select.on('change',function(waves) {
|
||||||
|
wav = waves;
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener("keydown", (event) => {
|
||||||
|
const keyIndex = keyMapper[event.key];
|
||||||
|
keyIndex !== undefined && !piano.keys[keyIndex]._state.state
|
||||||
|
? piano.toggleIndex(keyIndex, true)
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("keyup", (event) => {
|
||||||
|
const keyIndex = keyMapper[event.key];
|
||||||
|
keyIndex !== undefined && piano.keys[keyIndex]._state.state
|
||||||
|
? piano.toggleIndex(keyIndex, false)
|
||||||
|
: null;
|
||||||
|
});
|
||||||
31
scripts/webmidi.min.js
vendored
Normal file
31
scripts/webmidi.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user