-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmusic.js
98 lines (85 loc) · 2.55 KB
/
music.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
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
const NOTES_INFO = getNotesInfo();
function playNotes(notes){
return Promise.all(notes.map(n => playFreq(n.freq, n.duration)))
}
//plays a list of notes subsequently
async function playSong(notes){
const audioCtx = new AudioContext();
for(let n of notes){
console.log(`Playing Frequency: ${n.freq} Duration : ${n.duration}`);
await playFreq(n.freq, n.duration, audioCtx, audioCtx.destination)
}
}
/**
*
* @param {Number} frequency
* @param {Number} duration
* @returns
*/
function playFreq(frequency, duration = 500, audioCtx, destination){
if(frequency === 'SILENCE') playSilence(duration);
return new Promise((resolve, reject) => {
try{
// create Oscillator node
const oscillator = audioCtx.createOscillator();
oscillator.type = "square";
oscillator.frequency.setValueAtTime(frequency, audioCtx.currentTime); // value in hertz
oscillator.connect(destination);
oscillator.start();
setTimeout(() => {
oscillator.stop();
resolve()
}, duration)
}catch(e){reject(e)}
})
}
function playSilence(duration){
return new Promise((resolve, reject) => {
try{
setTimeout(() => {
resolve()
}, duration)
}catch(e){reject(e)}
})
}
function getFreqPerNote(note){
return NOTES_INFO.find(({name}) => name == note)?.freq;
}
function getNotesInfo(){
const DICT_KEYS = ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"]
const DICT_OCTAVES =[0,1,2,3,4,5,6,7,8]
let FREQ = 25.95654359874657 //starting point for G#-1
let KEYNB = 0 //sarting point for A0
return DICT_OCTAVES.map(function(v){
return DICT_KEYS.map(function(v2){
KEYNB++
FREQ = FREQ * Math.pow(2, 1/12)
return {
"keynb": KEYNB
, "freq": FREQ
, "name": v2+v
}
});
}).flat();
}
function textToNotes(text){
let notes;
try{
text = text.trim();
let arr = text.split('\n');
notes = arr.map(line => {
line = line.split(',');
let note = line[0].trim();
let freq;
if(!note) freq = 'SILENCE';
else freq = isNaN(note) ? getFreqPerNote(note) : note;
return {
freq,
duration : Number(line[1].trim())
}
});
}catch(e){
console.log('BAD DATA')
}
return notes;
}