Skip to content

Instantly share code, notes, and snippets.

@walfie
Last active March 7, 2020 22:32
Show Gist options
  • Save walfie/8b4458a1f957473eae689397b4ac4d73 to your computer and use it in GitHub Desktop.
Save walfie/8b4458a1f957473eae689397b4ac4d73 to your computer and use it in GitHub Desktop.
Animal Crossing Tune Player
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animal Crossing Tune Maker</title>
</head>
<body>
<input id="input" value="g-a-bgab-gab-c-b" maxlength="16"></input>
<button id="start">Start</button>
<button id="stop">Stop</button>
<hr>
Notes:
<pre>
gabcdefGABCDE
z Rest
- Hold
? Random
</pre>
<script>
const freqs = {
"g": 392.00,
"a": 440.00,
"b": 493.88,
"c": 523.25,
"d": 587.33,
"e": 659.25,
"f": 698.46,
"G": 783.99,
"A": 880.00,
"B": 987.77,
"C": 1046.50,
"D": 1174.66,
"E": 1318.51,
};
const delay = 0.2;
const allNotes = Object.values(freqs);
let audioContext = null;
let gainNode = null;
let currentOscillator = null;
const play = (notes, delay) => {
if (audioContext === null) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
gainNode = audioContext.createGain();
gainNode.connect(audioContext.destination);
gainNode.gain.value = 0.1;
}
const osc = audioContext.createOscillator();
osc.type = 'sine';
osc.connect(gainNode);
if (currentOscillator) {
currentOscillator.stop();
currentOscillator.disconnect(audioContext);
}
currentOscillator = osc;
const startTime = audioContext.currentTime;
notes.split('').reduce((acc, currentNote) => {
let note = 0;
switch (currentNote) {
case "z":
note = 0;
break;
case "-":
note = acc.prevNote;
break;
case "?":
note = allNotes[Math.floor(Math.random() * allNotes.length)];
break;
default:
note = freqs[currentNote] || 0;
break;
}
osc.frequency.setValueAtTime(note, startTime + acc.noteNumber * delay);
return { prevNote: note, noteNumber: acc.noteNumber + 1 }
}, { prevNote: 0, noteNumber: 0 });
osc.start();
osc.stop(startTime + notes.length * delay);
};
const stop = () => {
if (currentOscillator) {
currentOscillator.stop();
}
};
document.querySelector("#start").onclick = event => {
const notes = document.querySelector("#input").value;
play(notes, delay);
};
document.querySelector("#stop").onclick = event => {
stop();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment