Skip to content

Instantly share code, notes, and snippets.

@JordanRickman
Last active March 7, 2019 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JordanRickman/a99f2497d391f412373c03dfcac1a503 to your computer and use it in GitHub Desktop.
Save JordanRickman/a99f2497d391f412373c03dfcac1a503 to your computer and use it in GitHub Desktop.
Sound in Space: Mono Assignment
<html>
<head>
<script src="https://unpkg.com/tone@13.4.9/build/Tone.js"></script>
<script src="sketch.js"></script>
</head>
<body>
<button id="playbutton">
Play
</button>
</body>
</html>
const LOWEST_FREQ_HZ = 20;
const HIGHEST_FREQ_HZ = 10000;
const RAMP_TIME_SEC = 30;
const BPM = 76;
const OCTAVES = [3, 4, 5, 6, 7, 8];
// First 60 sec of piece: glissando up then down over whole frequency range
let osc;
function playSlideUpDown() {
osc = new Tone.Oscillator(LOWEST_FREQ_HZ, 'sine');
osc.toMaster();
let now = Tone.now();
osc.start(now);
osc.frequency.setValueAtTime(LOWEST_FREQ_HZ, now);
osc.frequency.exponentialRampToValueAtTime(HIGHEST_FREQ_HZ, now + RAMP_TIME_SEC);
osc.frequency.setValueAtTime(HIGHEST_FREQ_HZ, now + RAMP_TIME_SEC);
const END_PART_1 = now + 2*RAMP_TIME_SEC;
osc.frequency.exponentialRampToValueAtTime(LOWEST_FREQ_HZ, END_PART_1);
osc.stop(END_PART_1);
}
Tone.Transport.bpm.value = BPM;
var slideEvent = new Tone.Event(playSlideUpDown).start(0);
const END_SLIDE = 2*RAMP_TIME_SEC;;
function SineSynth() {
return new Tone.Synth({
oscillator: {
type: 'sine'
}
});
}
let synth = new Tone.PolySynth(OCTAVES.length, SineSynth).toMaster();
function getNote(octaveNumber) {
return `C${octaveNumber}`;
}
function playNoteAtTime(octaveNumber, time, duration) {
const note = getNote(octaveNumber);
new Tone.Event(() => {
console.log(`play: ${note}`);
synth.triggerAttackRelease(note, duration);
}).start(time);
}
function startNoteAtTime(octaveNumber, time) {
const note = getNote(octaveNumber);
new Tone.Event(() => {
console.log(`start: ${note}`);
synth.triggerAttack(note);
}).start(time);
}
function stopNoteAtTime(octaveNumber, time) {
const note = getNote(octaveNumber);
new Tone.Event(() => {
console.log(`stop: ${note}`);
synth.triggerRelease(note);
}).start(time);
}
let offset = END_SLIDE;
const ONE_BEAT = new Tone.Time("4n").toSeconds();
OCTAVES.forEach(n => {
playNoteAtTime(n, offset, "4n");
offset += ONE_BEAT;
});
OCTAVES.slice(0, OCTAVES.length-1).reverse().forEach(n => {
playNoteAtTime(n, offset, "4n");
offset += ONE_BEAT;
});
offset += ONE_BEAT;
startNoteAtTime(OCTAVES[0], offset);
offset += 2*ONE_BEAT;
OCTAVES.slice(1, Math.ceil(OCTAVES.length/2)).forEach(n => {
startNoteAtTime(n, offset);
});
offset += 2*ONE_BEAT;
OCTAVES.slice(Math.ceil(OCTAVES.length/2), OCTAVES.length).forEach(n => {
startNoteAtTime(n, offset);
});
offset += 4*ONE_BEAT;
OCTAVES.slice().reverse().forEach(n => {
stopNoteAtTime(n, offset);
offset += ONE_BEAT / OCTAVES.length;
});
offset += 3*ONE_BEAT;
playNoteAtTime(OCTAVES[OCTAVES.length-1], offset, "16n");
var playing = false;
function play() {
Tone.Transport.start();
playing = true;
}
function reset() {
Tone.Transport.stop();
osc ? osc.stop() : null;
playing = false;
}
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('playbutton').addEventListener('click', () => {
Tone.start();
if (!playing) {
play();
document.getElementById('playbutton').innerHTML = 'Stop';
} else {
reset();
document.getElementById('playbutton').innerHTML = 'Play';
}
})
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment