-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
128 lines (115 loc) · 3.8 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { Midi } from "@tonejs/midi";
import * as Tone from "tone";
import { Frequency, Synth } from "tone";
import { convertMelody, saveFile } from "./arduino";
const [playSymbol, stopSymbol] = [
`
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg>
`,
`
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"></path><path d="M6 6h12v12H6z"></path></svg>
`,
];
const trackSelector = document.getElementById("tracks") as HTMLSelectElement;
const playPauseBtn = document.getElementById(
"play-toggle"
) as HTMLButtonElement;
const codeTextArea = document.getElementById(
"arduinoCode"
) as HTMLTextAreaElement;
const downloadBtn = document.getElementById("downloadBtn");
const errorTxt = document.getElementById("error");
const renderError = (msg: string) => {
errorTxt.innerText = msg;
};
if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
document.querySelector("#FileDrop #Text").textContent =
"Reading files not supported by this browser";
} else {
const fileDrop = document.querySelector("#FileDrop");
fileDrop.addEventListener("dragover", () => fileDrop.classList.add("Hover"));
fileDrop.addEventListener("dragleave", () =>
fileDrop.classList.remove("Hover")
);
fileDrop.addEventListener("drop", () => fileDrop.classList.remove("Hover"));
const fileInput = document.querySelector(
"#FileDrop input"
) as HTMLInputElement;
fileInput.addEventListener("change", (e) => {
//get the files
const target = e.target as HTMLInputElement;
const files = target.files;
if (files.length > 0) {
const file = files[0];
document.querySelector("#FileDrop #Text").textContent = file.name;
parseFile(file);
}
});
}
let currentMidi: Midi;
let fileName = "";
let code = "";
const renderTracks = () => {
let options = ``;
currentMidi.tracks.forEach((track, i) => {
options += `<option value=${i}> ${i + 1}. ${track.name} </option>`;
});
trackSelector.innerHTML = options;
};
const generateCode = () => {
const selectedTrack = +trackSelector.value;
const tracks = currentMidi.tracks[selectedTrack].notes;
code = convertMelody(tracks);
codeTextArea.value = code;
downloadBtn.removeAttribute("disabled");
};
downloadBtn.addEventListener("click", () => {
saveFile(fileName, code);
});
// update code when user changes selection
trackSelector.addEventListener("change", generateCode);
function parseFile(file: File) {
//read the file
const reader = new FileReader();
reader.onload = function (e) {
//@ts-ignore
try {
const midi = new Midi(e.target.result);
playPauseBtn.removeAttribute("disabled");
currentMidi = midi;
renderTracks();
generateCode();
fileName = file.name.split(".")[0] + ".ino";
errorTxt.innerText = "";
} catch (err) {
renderError("Error in parsing " + err);
}
};
reader.readAsArrayBuffer(file);
}
const synths: Synth[] = [];
playPauseBtn.addEventListener("click", () => {
if (currentMidi && !synths.length) {
playPauseBtn.innerHTML = stopSymbol;
const now = Tone.now();
//create a synth for each track
const track = currentMidi.tracks[+trackSelector.value];
const synth = new Tone.Synth().toDestination();
synths.push(synth);
// synth.onsilence = () => {
// playPauseBtn.innerText = playSymbol;
// };
track.notes.forEach((note) => {
try {
synth.triggerAttackRelease(note.name, note.duration, note.time + now);
} catch (err) {
console.error(err);
}
});
} else {
//dispose the synth and make a new one
const synth = synths.shift();
synth.dispose();
playPauseBtn.innerHTML = playSymbol;
}
});