Step-o-matic CSS

  Bài viết hay nhất1
HTML:

<section id="save-code-modal" class="modal">
<div>
<header>
<p>Copy the code below and save it for later. When you want to load it, press the "Load" button and paste this in the dialog.</p>
</header>
<textarea readonly></textarea>
<footer>
<button id="close-save-code-modal">Close</button>
</footer>
</div>
</section>
<section id="load-code-modal" class="modal">
<div>
<header>
<p>Paste your saved code below and hit "Load".</p>
</header>
<textarea autofocus></textarea>
<footer>
<button id="load-code-from-modal">Load It</button>
<button id="close-load-code-modal">Cancel</button>
</footer>
</div>
</section>

<main id="step-o-matic">
<header>
<section>
<div>
<label for="play">On</label>
<input id="play" checked type="checkbox" />
<label id="playing" for="play"></label>
</div>
<div>
<h1>Step-o-matic</h1>
</div>
<div>
<button id="save-code">Save</button>
<button id="load-code">Load</button>
</div>
</section>
<section>
<div>
<label for="key">Key</label>
<select id="key">
<optgroup label="Major">
<option value="C" selected>C</option>
<option value="Db">C♯</option>
<option value="D">D</option>
<option value="Eb">E♭</option>
<option value="E">E</option>
<option value="F">F</option>
<option value="Gb">F♯</option>
<option value="G">G</option>
<option value="Ab">A♭</option>
<option value="A">A</option>
<option value="Bb">B♭</option>
<option value="B">B</option>
</optgroup>
<optgroup label="Minor">
<option value="Cm">Cm</option>
<option value="Dbm">C♯m</option>
<option value="Dm">Dm</option>
<option value="Ebm">E♭m</option>
<option value="Em">Em</option>
<option value="Fm">Fm</option>
<option value="Gbm">F♯m</option>
<option value="Gm">Gm</option>
<option value="Abm">A♭m</option>
<option value="Am">Am</option>
<option value="Bbm">B♭m</option>
<option value="Bm">Bm</option>
</optgroup>
</select>
</div>
<div>
<label for="kit">Kit</label>
<select id="kit">
<option value="808" selected>TR-808</option>
<option value="606">Cassette</option>
<option value="ana">Crunch</option>
</select>
</div>
<div>
<label for="tempo">Tempo</label>
<input id="tempo" type="range" step="1" min="60" max="120" value="90" />
</div>
<div>
<label for="pulse">Beats</label>
<select id="pulse">
<option value="3">3</option>
<option value="4" selected>4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
</select>
</div>
</section>
</header>
<section id="stepper-1"></section>
<section id="stepper-3"></section>
<div id="buffering">Buffering</div>
</main>





@import url(https://fonts.googleapis.com/css?family=Courgette);

html, body {
height: 100%;
overflow: hidden;
text-rendering: optimizeLegibility;
}

body {
background: #777064;
min-width: 650px;
}

$count: 32;
$beat-h: 1.8rem;
$beat-space: 0.6rem;
$c-inst: #FFBB00;
$c-header: #222;
$c-drum: darken($c-inst, 15%);
$c-drum: $c-header;
$ui-corner: 4px;
$c-play: #FFBB00;
$depth: 12px;
$shine: 4px;
$depth-half: $depth / 2;

.modal {
position: fixed;
display: none;
&.active {
display: block;
}
z-index: 10;
top: 0; right: 0; bottom: 0; left: 0;
background: rgba(0,0,0,0.Cool;
div {
background: $c-header;
color: white;
width: 95%;
max-width: 600px;
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
padding: 2rem;
border-radius: $ui-corner * 2;
text-align: center;
}
p {
margin: 0;
}
textarea {
width: 100%;
height: 200px;
padding: 1rem;
margin: 1rem 0;
font-size: 0.75em;
box-sizing: border-box;
font-family: "Andale Mono", monospace;
border: 1px solid darken(#444, 15%);
border-radius: $ui-corner;
color: $c-header;
}
button {
width: 100px;
}
#load-code-from-modal {
background: $c-inst;
}
}

button {
border-radius: $ui-corner;
border: 1px solid;
color: white;
background: #444;
border-color: darken(#444, 5%);
}

#step-o-matic {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
> header, > section {
margin: 0 auto;
position: relative;
padding: 1rem 2rem;
width: 50%;
}
@for $i from 3 through 7 {
@if ($i == 3) {
&.pulse-#{$i} > header h1 {
font-size: 2.2rem;
}
}
&.pulse-#{$i} > header,
&.pulse-#{$i} > section {
width: $beat-h * 4 * $i;
}
}
> header {
height: 100%;
transform: translateZ(0);
background: $c-header;
border-radius: $ui-corner * 2 $ui-corner * 2 0 0;
box-shadow:
0px 0px 0px $shine lighten($c-header, 2%),
0px 0px 0px $depth darken($c-header, 4%);

h1, button {
color: white;
}
h1 {
text-align: center;
font-family: Courgette, sans-serif;
}
h1 {
font-size: 3rem;
text-align: center;
margin: 0 0 0.5rem;
}
label, button {
font-family: Helvetica, sans-serif;
font-size: 0.75em;
text-transform: uppercase;
letter-spacing: 0.0125em;
}
label {
color: #999;
text-shadow: -1px -1px 0px black;
}
button {
display: block;
+ button {
margin-top: 0.5rem;
}
}
#save-code {
background: $c-play;
border-color: darken($c-play, 5%);
}
#load-code {

}
section {
display: flex;
div {
flex: 2;
&:last-child { flex: 1; }
text-align: center;
padding: 0 0.5rem;
input, select, button {
width: 100%;
}
}
&:first-of-type {
margin-bottom: 0.5rem;
div { flex: 8; }
div:first-child { flex: 1; }
div:last-child { flex: 1; }
}
label {
display: block;
margin-bottom: 0.5em;
}
#playing {
display: block;
height: 1rem; width: 1rem;
border-radius: 50%;
border: 2px solid darken($c-play, 20%);
background: darken($c-play, 30%);
margin: 0 auto;
cursor: pointer;
}
#play {
position: absolute;
pointer-events: none;
opacity: 0;
}
#play:checked + #playing {
border: 2px solid $c-play;
background: lighten($c-play, 10%);
box-shadow: 0px 0px 12px $c-play;
}
}
}
> section {
position: relative;
z-index: 9;
background: $c-inst;
box-shadow:
$shine 0px 0px 0px lighten($c-inst, 5%),
-$shine 0px 0px 0px lighten($c-inst, 5%),
$depth 0px 0px darken($c-inst, 5%),
-$depth 0px 0px darken($c-inst, 5%);
&:last-of-type {
z-index: 8;
background: $c-drum;
box-shadow:
0px 0px 0px $shine lighten($c-drum, 2%),
0px 0px 0px $depth darken($c-drum, 4%);
border-radius: 0 0 $ui-corner $ui-corner;
}
}

#buffering {
z-index: 11;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 1rem;
border-radius: $ui-corner;
color: white;
background: $c-header;
display: none;
&.active {
display: block;
}
}

.note {
display: flex;
}

.beat {
position: relative;
flex: 1;
height: $beat-h;
&::after {
content: "";
border-radius: $ui-corner;
position: absolute;
top: $beat-space / 2;
right: $beat-space / 2;
bottom: $beat-space / 2;
left: $beat-space / 2;
transform-origin: 50% 50%;
transition: transform 200ms ease-in-out,
background 100ms ease-in-out,
box-shadow 100ms ease-in-out;
background: rgba(255,255,255,0.5);
}
&.active::after {
background: rgba(255,255,255,1);
box-shadow: 0px 0px 12px rgba(255,255,255,1);
}
}

// cornering the pad groups
.note:first-child {
@for $i from 1 through $count {
@if (($i + 3) % 8 == 0) {
.beat:nth-child(#{$i}) { border-radius: $ui-corner 0 0 0; }
}
@if ($i % 8 == 0) {
.beat:nth-child(#{$i}) { border-radius: 0 $ui-corner 0 0; }
}
}
}
.note:last-child {
@for $i from 1 through $count {
@if (($i + 3) % 8 == 0) {
.beat:nth-child(#{$i}) { border-radius: 0 0 0 $ui-corner; }
}
@if ($i % 8 == 0) {
.beat:nth-child(#{$i}) { border-radius: 0 0 $ui-corner 0; }
}
}
}

@for $i from 1 through $count {
// coloring the pad groups
$index-4: ceil($i / 4);
@if ($index-4 % 2 == 0) {
.beat:nth-child(#{$i}) {
background: rgba(255,255,255,0.2);
}
}
// styling playing beat / playing note
@for $i from 1 through $count {
&.step-#{$i - 1} .beat:nth-child(#{$i}) {
&::after {
background: rgba(255,255,255,0.Cool;
transform: scale(0.9);
}
&.active::after {
background: rgba(255,255,255,1);
transform: scale(1.1);
}
}
}
}


}



JS:

// console.clear();

var synth = new Stepper({
container: document.getElementById("stepper-1"),
note_count: 11,
octave: 4
});

var drum = new Stepper({
container: document.getElementById("stepper-3"),
notes: ["oh", "ch", "sd", "kd"],
sampler: true
});

var clock = new Clock({
container: document.getElementById("step-o-matic"),
play_el: document.getElementById("play"),
key_el: document.getElementById("key"),
kit_el: document.getElementById("kit"),
pulse_el: document.getElementById("pulse"),
tempo_el: document.getElementById("tempo"),
save_code_el: document.getElementById("save-code"),
load_code_el: document.getElementById("load-code"),
load_code_modal: document.getElementById("load-code-modal"),
save_code_modal: document.getElementById("save-code-modal"),
load_code_from_modal: document.getElementById("load-code-from-modal"),
close_load_code_modal: document.getElementById("close-load-code-modal"),
close_save_code_modal: document.getElementById("close-save-code-modal"),
buffering: document.getElementById("buffering"),
key: "C",
synth: "Britey",
kit: "808",
pulse: 4,
tempo: 90,
steppers: {
synth: synth,
drum: drum
}
});


clock.start();


/********************
CLOCK
contains many steppers that can be played
as the clock progresses
********************/

function Clock(params) {
var C = {};

init();

return C;

function init() {
setGlobals();
setSteppers();
setEvents();
}

/**********
setters
**********/

function setGlobals() {
C.container = params.container;
C.play_el = params.play_el;
C.key_el = params.key_el;
C.pulse_el = params.pulse_el;
C.tempo_el = params.tempo_el;
C.kit_el = params.kit_el;
C.save_code_el = params.save_code_el;
C.load_code_el = params.load_code_el;
C.load_code_modal = params.load_code_modal;
C.save_code_modal = params.save_code_modal;
C.load_code_from_modal = params.load_code_from_modal;
C.close_load_code_modal = params.close_load_code_modal;
C.close_save_code_modal = params.close_save_code_modal;
C.buffering = params.buffering;


C.current_beat = 0;
C.playing = false;
C.buffered = false;

C.start = start;
C.stop = stop;
C.loadCode = loadCode;
C.updateKit = updateKit;
C.updateSynth = updateSynth;
}

function setSteppers() {
C.steppers = params.steppers;
updateKey(params.key);
updateTempo(params.tempo);
updatePulse(params.pulse);
C.kit = new Kit();
C.synth = new Synth();
updateKit(params.kit);
updateSynth(params.synth);
}

function setEvents() {

C.key_el.addEventListener("click", pause);
C.pulse_el.addEventListener("click", pause);
C.kit_el.addEventListener("click", pause);

C.play_el.addEventListener("change", function() {
if(this.checked) { C.start(); } else { C.stop(); }
});

C.kit_el.addEventListener("change", function() {
updateKit(this.value);
unpause();
});
C.key_el.addEventListener("change", function() {
updateKey(this.value);
unpause();
});
C.pulse_el.addEventListener("change", function() {
updatePulse(parseInt(this.value));
unpause();
});
C.tempo_el.addEventListener("change", function() {
updateTempo(parseInt(this.value));
});

C.save_code_el.addEventListener("click", openSaveCodeModal);
C.load_code_el.addEventListener("click", openLoadCodeModal);
C.close_save_code_modal.addEventListener("click", function() {
C.save_code_modal.className = C.save_code_modal.className.replace(" active", "");
});
C.load_code_from_modal.addEventListener("click", function() {
C.load_code_modal.className = C.load_code_modal.className.replace(" active", "");
var value = C.load_code_modal.querySelector("textarea").value;
if(value) loadCode(value);
});
C.close_load_code_modal.addEventListener("click", function() {
C.load_code_modal.className = C.load_code_modal.className.replace(" active", "");
});
}

/**********
updating
**********/

// update the drum kit
function updateKit(kit) {
C.buffered = false;
C.buffering.className = "active";
C.kit_el.value = kit;
C.kit.updateKit(kit);
C.steppers.drum.updateInstrument(C.kit.kit);
Tone.Buffer.on("load", function() {
C.buffering.className = "";
C.buffered = true;
});
}

// update the synth
function updateSynth(name) {
C.synth.updateSynth(name);
C.steppers.synth.updateInstrument(C.synth.synth);
}

// update the tempo clock
function updateTempo(tempo) {
C.tempo_el.value = tempo;
C.tempo = tempo;
Tone.Transport.bpm.value = C.tempo;
}

// update the beat count for each stepper
function updatePulse(pulse) {
C.pulse_el.value = pulse;
C.pulse = pulse;
var denom = pulse > 5 ? 8 : 4;
Tone.Transport.timeSignature = [pulse, denom];
C.beats = pulse * 4;
var name = C.container.className;
C.container.className = name.match("pulse-") ? name.replace(/pulse-\d\d?/, "pulse-" + pulse) : "pulse-" + pulse;
C.steppers.synth.updateBeats(C.beats);
C.steppers.drum.updateBeats(C.beats);
}

// update the key for each non sampler stepper
function updateKey(key) {
C.key = key;
C.key_el.value = key;
C.steppers.synth.updateKey(key);
C.steppers.drum.updateKey(key);
}

/**********
modals
**********/

// save code by generating new encode string
function openSaveCodeModal() {
C.save_code_modal.className += " active";
var s = JSON.stringify({
steps: {
synth: C.steppers.synth.steps,
drum: C.steppers.drum.steps
},
synth: C.synth.name,
kit: C.kit.name,
tempo: C.tempo,
key: C.key,
pulse: C.pulse
});
var encoded = s;
var textarea = C.save_code_modal.querySelector("textarea");
textarea.value = encoded;
textarea.focus();
}

// open the load modal
function openLoadCodeModal(string) {
var textarea = C.load_code_modal.querySelector("textarea");
textarea.value = "";
textarea.focus();
C.load_code_modal.className += " active";
}

// load code by reading encoded string
function loadCode(string) {
var decoded = string;
var parsed = JSON.parse(decoded);
if(parsed) {
updateKey(parsed.key);
updateTempo(parsed.tempo);
updatePulse(parsed.pulse);
updateSynth(parsed.synth);
updateKit(parsed.kit);
C.steppers.synth.updateSteps(parsed.steps.synth);
C.steppers.drum.updateSteps(parsed.steps.drum);
} else {
alert("That code bad, yo.");
}
}

/**********
play events
**********/

// start playing
function start() {
C.playing = true;
C.play_el.setAttribute("checked", true);

Tone.Transport.bpm.value = C.tempo;
Tone.Transport.scheduleRepeat(player, "16n");
Tone.Transport.start();

function player(time) {
if(C.buffered) {
C.container.className = "pulse-" + C.pulse + " step-" + C.current_beat;
C.steppers.synth.playNotes(C.current_beat, time);
C.steppers.drum.playNotes(C.current_beat, time);

if(C.current_beat >= C.beats - 1) {
C.current_beat = 0;
} else {
C.current_beat++;
}
}
}
}

// unpause paused state
function unpause() {
if(C.playing)
start();
}

// temporarily pause wihtout changing play state
function pause() {
if(C.playing)
Tone.Transport.cancel();
}

// stop all playing
function stop() {
if(C.playing) {
C.play_el.removeAttribute("checked");
C.play_el.checked = false;
C.playing = false;
Tone.Transport.cancel();
}
}

}



/********************
STEPPER
has its own instrument and array of note step sequences
that can be played on a clock
********************/

function Stepper(params) {
var S = {};

init();

function init() {
setGlobals();
setEvents();
}

return S;

/**********
setters
**********/

function setGlobals() {
S.container = params.container;

if(params.notes) {
S.notes = params.notes;
} else {
S.notes_lib = setNotesLib();
}

S.sampler = params.sampler || false;
S.hoverable = false;
S.hover_on = true;
S.octave = params.octave;
S.note_count = params.note_count;

S.updateBeats = updateBeats;
S.playNotes = playNotes;
S.getActiveNotes = getActiveNotes;
S.updateSteps = updateSteps;
S.updateHovers = updateHovers;
S.updateKey = updateKey;
S.updateInstrument = updateInstrument;
}

function setEvents() {
S.container.addEventListener("mouseup", mouseup);
S.container.addEventListener("mouseenter", function(e) {
if(S.hoverable) mouseup(e);
});
}

// set the steps to be an array of binary play switches for each note
function setSteps() {
S.steps = [];
for(var r = 0; r < S.notes.length; r++) {
// create an array sequence of binary on/off players
var sequence = [];
for(var b = 0; b < S.beats; b++) {
sequence.push(0);
}
// add the row to steps
S.steps.push(sequence);
}
S.max_step = S.steps.length;
}

// set a notes library
function setNotesLib() {
var notes = [];
for(var i = 2; i < 8; i++) {
var n = "C Db D Eb E F Gb G Ab A Bb B".split(" ");
for(var x = 0; x < n.length; x++) {
notes.push(n[x] + i);
}
}
return notes;
}


/**********
updates
**********/

// set the instrument to the Tone.js object that is passed in
function updateInstrument(instrument) {
S.instrument = instrument;
}

// update hoverable to account for click and dragging
function updateHovers(hoverable) {
S.hoverable = hoverable;
}

// update quarter note length beat count
function updateBeats(beats) {
if(!S.steps) {
S.beats = beats;
setSteps();
}
adjustBeats(S.beats - beats);
S.beats = beats;
drawBeats();
}

// update the steps to match an existing array
function updateSteps(steps) {
for(var s = 0; s < steps.length; s++) {
if(s < S.steps[s].length) {
S.steps[s] = steps[s];
}
}
drawBeats();
}

// update the key
function updateKey(key) {
if(!S.sampler) {
S.key = key;
var minor = key.match(/m$/) ? true : false;
if(minor) key = key.replace("m", "");
var jumps = minor ? [0,2,3,7,8] : [0,2,4,7,9];
var start = S.notes_lib.indexOf(key + S.octave);
var start_octave = S.octave;
var array = [];
for(var o = 0; o < S.note_count; o++) {
var index = start + jumps[o % jumps.length] + (Math.floor(o / jumps.length) * 12);
var note = S.notes_lib[index];
array.push(note);
}
array.reverse();
S.notes = array;
}
}

/**********
helpers
**********/

// adjust the notes beat sequences to be less or more than existing
function adjustBeats(amount) {
if(amount === 0) return;
for(var n = 0; n < S.steps.length; n++) {
var step = S.steps[n];
if(amount > 0) {
step.splice(step.length - amount, amount);
} else {
for(var i = 0; i < (amount * -1); i++)
step.push(0);
}
}
}

// draw beat elements to the dom
function drawBeats() {
S.container.innerHTML = "";

// draw each step sequence
for(var s = 0; s < S.steps.length; s++) {
var el = document.createElement("div");
el.className = "note";
for(var b = 0; b < S.beats; b++) {
var beat = S.steps[s][b];
var b_el = document.createElement("a");
b_el.className = "beat";
if(beat) b_el.className += " active";
b_el.setAttribute("data-index", s + "," + b);
b_el.addEventListener("mousedown", mousedown);
b_el.addEventListener("mouseenter", mouseenter);
el.appendChild(b_el);
}
S.container.appendChild(el);
}
}

/**********
events
**********/

// toggle the beat on or off
function mousedown(e) {
e.preventDefault();
S.hoverable = true;
var el = e.target,
index = el.getAttribute("data-index").split(","),
row = parseInt(index[0]), beat = parseInt(index[1]);
var b = S.steps[row][beat];
S.hover_on = b === 0;
toggleElement(e.target);
}

// disable hoverable on mouseup
function mouseup(e) {
e.preventDefault();
S.hoverable = false;
}

// detect hover and do somestuff if mouse is being held down
function mouseenter(e) {
e.preventDefault();
if(!S.hoverable) return;
toggleElement(e.target, true);
}

function toggleElement(el, hovering) {
var index = el.getAttribute("data-index").split(","),
row = parseInt(index[0]), beat = parseInt(index[1]);
var b = S.steps[row][beat];
if(b === 1) {
if(hovering && S.hover_on) return;
S.steps[row][beat] = 0;
el.className = el.className.replace(/ active/g, "");
} else {
if(hovering && !S.hover_on) return;
S.steps[row][beat] = 1;
el.className += " active";
}
}

// play all active notes
function playNotes(beat, time) {
var notes = S.getActiveNotes(beat);
if(!notes.length) return;
if(S.sampler) {
for(var n = 0; n < notes.length; n++) {
S.instrument.triggerAttackRelease(notes[n], "8n", time);
}
} else {
S.instrument.triggerAttackRelease(notes, "16n", time);
}
}

// get all notes for each step that should play at beat position
function getActiveNotes(beat) {
var active_notes = [];
for(var s = 0; s < S.steps.length; s++) {
if(S.steps[s][beat]) active_notes.push(S.notes[s]);
}
return active_notes;
}

return S;
}



/*********
Kit provides different pre-programmed samplers thanks to Tone.js
*********/

function Kit() {
var D = {};

init();

return D;

function init() {
D.updateKit = updateKit;
}

function updateKit(name) {
D.name = name;
var path = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/111863/";
var kd = path + "kd-" + name + ".wav",
sd = path + "sd-" + name + ".wav",
ch = path + "ch-" + name + ".wav",
oh = path + "oh-" + name + ".wav";
D.kit = new Tone.Sampler({
oh: oh, ch: ch, sd: sd, kd: kd
});

var gains = {
808: 0.8,
606: 0.4,
ana: 0.9
};

var gain = new Tone.Gain(gains[name]);
gain.toMaster();


var multiband = new Tone.MultibandCompressor({
lowFrequency: 200,
highFrequency: 1300,
low: {
threshold: -12
}
});

var distortion = new Tone.Distortion();
distortion.wet.value = 0.3;

multiband.connect(gain);
distortion.connect(multiband);
if(name === "ana") {
D.kit.connect(distortion);
} else {
D.kit.connect(multiband);
}
}
}



/*********
Synth provides different pre-programmed synthesizers thanks to Tone.js
*********/

function Synth() {

var S = {};

init();

return S;

function init() {
loadFX();
loadSynths();
S.updateSynth = updateSynth;
}

function updateSynth(name) {
S.name = name;
useSynth(name);
}

function loadFX() {
S.FX = {
multiband: new Tone.MultibandCompressor({
lowFrequency: 200,
highFrequency: 1300,
low: {
threshold: -12
}
}),
reverb: new Tone.Freeverb(),
delay: new Tone.PingPongDelay("16n", 0.2),
long_delay: new Tone.PingPongDelay("32n", 0.3)
};

S.FX.reverb.roomSize.value = 0.6;
S.FX.reverb.wet.value = 0.2;

S.FX.delay.wet.value = 0.4;

S.FX.long_delay.wet.value = 0.4;
}

// load up all the synths
function loadSynths() {
S.synths = {
// Haunty: Haunty(),
// Belly: Belly(),
Britey: Britey()
};
}

// initial load of haunty synth
function Haunty() {
var synth = new Tone.PolySynth(16, Tone.SimpleAM);
synth.set({
envelope: {
attack: 0.5,
release: 0.5
}
});
synth.set("carrier", {
volume: -4,
oscillator: {
partials: [1, 0.2, 0.01]
},
envelope: {
attack: 0.05, decay: 0.02,
sustain: 0.6, release: 0.8
}
});
synth.set("modulator", {
volume: -12,
oscillator: {
partials: [1, 0.2, 0.01],
detune: 0, phase: 90,
},
envelope: {
attack: 0.05, decay: 0.01,
sustain: 1, release: 1
}
});

synth.chain(S.FX.delay, S.FX.reverb, S.FX.multiband, Tone.Master);
return synth;
}

// initial load of britey synth
function Britey() {
var synth = new Tone.PolySynth(16, Tone.SimpleAM);
synth.set({
envelope: {
attack: 0.5,
release: 0.5
}
});
synth.set("carrier", {
volume: -4,
oscillator: {
type: "triangle"
},
envelope: {
attack: 0.05, decay: 0.02,
sustain: 0.6, release: 0.8
}
});
synth.set("modulator", {
volume: -16,
oscillator: {
type: "triangle"
},
envelope: {
attack: 0.05, decay: 0.01,
sustain: 1, release: 1
}
});

synth.chain(S.FX.long_delay, S.FX.multiband, Tone.Master);
return synth;
}

// initial load of belly synth
function Belly() {
var synth = new Tone.PolySynth(16, Tone.SimpleFM);
synth.set("harmonicity", 3);
synth.set("modulationIndex", 10);
synth.set("carrier", {
volume: -20,
portamento: 0,
oscillator: {
type: "sine"
},
envelope: {
attack: 0.01,
decay: 0,
sustain: 1,
release: 0.5
}
});
synth.set("modulator", {
volume: -20,
portamento: 0,
oscillator:{
type: "triangle"
},
envelope: {
attack: 0.01,
decay: 0,
sustain: 1,
release: 0.5
}
});

synth.chain(S.FX.multiband, Tone.Master);
return synth;
}

// take a name and return a synth
function useSynth(name) {
switch(name) {
case "Haunty":
S.synth = S.synths.Haunty;
break;
case "Belly":
S.synth = S.synths.Belly;
break;
case "Britey":
S.synth = S.synths.Britey;
break;
default:
S.synth = S.synths.Belly;
}
}
}

Bạn không có quyền trả lời bài viết