Neale Pickett
·
2023-01-16
music.mjs
1/**
2 * @file Musical notes and frequencies
3 */
4
5/** One half step in equal temperament */
6const semitone = Math.pow(2, 1/12)
7const ln_semitone = Math.log(semitone)
8const A4_note = 69
9const A4_freq = 440
10const Cn1_note = 0
11const Cn1_freq = A4_freq / Math.pow(semitone, A4_note)
12
13const note_names = [
14 "C",
15 "C♯",
16 "D",
17 "E♭",
18 "E",
19 "F",
20 "F♯",
21 "G",
22 "A♭",
23 "A",
24 "B♭",
25 "B",
26]
27
28/**
29 * Convert a MIDI note to a frequency
30 *
31 * @param {Number} note MIDI note number
32 * @returns {Number} Frequency (Hz)
33 */
34function MIDINoteFrequency(note, precision=0) {
35 let freq = Cn1_freq * Math.pow(semitone, note)
36 return freq.toFixed(precision)
37}
38
39/**
40 * Return closest matching MIDI note to a frequency
41 *
42 * @param {Number} frequency Frequency (Hz)
43 * @returns {Number} Closest MIDI note
44 */
45function FrequencyMIDINote(frequency) {
46 return Math.round(Math.log(frequency/Cn1_freq) / ln_semitone)
47}
48
49function MIDINoteName(note) {
50 let octave = Math.floor(note / 12) - 1
51 return note_names[note % 12] + octave
52}
53
54export {
55 MIDINoteFrequency,
56 FrequencyMIDINote,
57 MIDINoteName,
58}