Initial import.
[featherfall2.git] / tools / composer / composer.js
1 "use strict";
2
3 function titleCase (text) {
4 return text.replace("_", " ").replace(/\w\S*/g, function (word) {
5 return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
6 });
7 }
8
9 function setOptions (select, dict) {
10 yf.irange.call(select, select.remove, select.options.length - 1, -1, -1);
11 yf.each(function (name) {
12 var opt = document.createElement("option");
13 opt.text = titleCase(name);
14 opt.id = name;
15 select.appendChild(opt);
16 }, Object.keys(dict).sort());
17 }
18
19 window.addEventListener("load", function () {
20 var playing;
21
22 yuu.init({}).then(function () {
23 setOptions(document.getElementById("instrument"), yuu.Instruments);
24 setOptions(document.getElementById("scale"), yuu.Scales);
25 });
26
27 function play () {
28 if (playing)
29 playing.disconnect();
30 var instruments = document.getElementById("instrument");
31 var scales = document.getElementById("scale");
32 var instrument = yuu.Instruments[
33 instruments.options[instruments.selectedIndex].id];
34 var scale = yuu.Scales[
35 scales.options[scales.selectedIndex].id];
36 var score = yuu.parseScore(
37 document.getElementById("score").value,
38 scale, document.getElementById("tonic").value);
39 var bps = +document.getElementById("tempo").value / 60;
40 playing = yuu.audio.createGain();
41 playing.gain.value = 0.5;
42 var t = yuu.audio.currentTime + 0.25;
43 yf.each(function (note) {
44 instrument.createSound(
45 yuu.audio,
46 t + note.time / bps,
47 note.hz,
48 1.0,
49 note.duration / bps
50 ).connect(playing);
51 }, score);
52 playing.connect(yuu.audio.destination);
53 }
54
55 function jam (key) {
56 if (key === "`")
57 key = "0";
58 else if (key === "0")
59 key = "10";
60 var instruments = document.getElementById("instrument");
61 var scales = document.getElementById("scale");
62 var tonic = document.getElementById("tonic").value;
63 var instrument = yuu.Instruments[
64 instruments.options[instruments.selectedIndex].id];
65 var scale = yuu.Scales[scales.options[scales.selectedIndex].id];
66 var note = yuu.parseScore(key, scale, tonic)[0];
67 var bps = +document.getElementById("tempo").value / 60;
68 if (note)
69 instrument.createSound(
70 yuu.audio,
71 yuu.audio.currentTime + 0.01,
72 note.hz,
73 1.0,
74 note.duration / bps
75 ).connect(yuu.audio.destination);
76 }
77
78 document.getElementById("play").addEventListener("click", play);
79
80 document.getElementById("jam")
81 .addEventListener("keydown", function (event) {
82 jam(yuu.keyEventName(event));
83 });
84 });
85