-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
73 lines (68 loc) · 2.31 KB
/
index.js
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
require('json5/lib/register');
const path = require('path');
const data = require(path.join(__dirname, 'data.json5'));
const note_parser = require('note-parser');
const readline = require('readline/promises');
function getToverTau(len, freq) {
// Standing wave frequency formula:
// f = 1/(2L) * sqrt(T/tau)
// T/tau = (2fL)^{2}
return 2 * Math.log(2 * len * freq);
}
const results = [];
for (const instrument in data) {
const item = data[instrument];
const notes = item.notes.map((s) => note_parser.parse(s, false, 442));
for (const size in item.len) {
for (let i = 0; i < notes.length; i++) {
const note = notes[i];
results.push({
instrument,
size,
note: note.pc,
freq: note.freq,
len: item.len[size],
value: getToverTau(item.len[size], note.freq),
});
}
}
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const run_default = async () => {
const instrument = await rl.question(`What instrument [${Object.keys(data).join(' ')}]? `);
const item = data[instrument.trim().toLowerCase()];
if (!item) {
console.log('Sorry, I don\'t know this instrument');
return false;
}
const size = await rl.question(`What size [${Object.keys(item.len).join(' ')}]? `);
const len = item.len[size];
if (!len) {
console.log('Sorry, I don\'t know this size');
return false;
}
const note_s = await rl.question('What note do you want to play on the desired open string [C#3, Gb4, etc.]? ');
const note = note_parser.parse(note_s, false, 442);
if (!note.freq) {
console.log('Sorry, I don\'t understand this note');
return false;
}
const value = getToverTau(len, note.freq);
const list = results.map((r) => ({ ...r, diff: Math.abs(r.value - value) }));
list.sort((a, b) => a.diff - b.diff);
console.log('Best matches:');
for (let i = 0; i < list.length; i++) {
const s = list[i];
if (s.diff > Math.log(3.5))
break;
const smaller = s.len < len;
const terr = `${s.value > value ? '+' : '-'}${Math.round((Math.exp(s.diff) - 1) * 100)}% error`;
const lerr = `${Math.round((s.len / len - 1) * 100)}% error`;
console.log(`${smaller ? '!' : ' '} ${s.size} ${s.instrument} ${s.note} string\t(tension: ${terr}) (length: ${lerr})`);
}
rl.close();
};
run_default();