-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathui.js
98 lines (80 loc) · 2.49 KB
/
ui.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
Mike.on('error', function(e) {
console.log('Uncaught error:', e);
});
var wheel = document.querySelector('.tuner .wheel'),
c = document.querySelector('.tuner .freq').childNodes[0],
flat = document.querySelector('.tuner .flat'),
sharp = document.querySelector('.tuner .sharp'),
arrow = document.querySelector('.tuner .arrow'),
pitch = null;
wheel.rotate = function (angle) {
var prefixes = ['webkitT', 'MozT', 'msT', 'OT', 't'];
for (var i=0; i<prefixes.length; i++) {
this.style[prefixes[i] + 'ransform'] = 'rotate(' + angle + 'rad)';
}
};
function toggleClass (elem, cls, add) {
if (elem.classList) {
elem[add ? 'add' : 'remove'](cls);
} else if (typeof elem.className === 'string') {
elem.className = elem.className.replace(cls, '') +
(add ? ' ' + cls : '');
} else if (typeof elem.className === 'object') {
elem.className.baseVal = elem.className.baseVal.replace(cls, '') +
(add ? ' ' + cls : '');
}
}
var mike = new Mike({
swfPath: 'vendor/mike.swf',
parentElement: document.querySelector('.tuner'),
settings: {
codec: Mike.SoundCodec.NELLYMOSER,
sampleRate: 44100
}
});
mike.on('ready', function() {
pitch = new PitchAnalyzer(44100);
this.setMicrophone();
this.start();
if (!this.getParam('muted')) {
this.hide();
}
});
mike.on('statechange', function(e) {
this.hide();
})
mike.on('error', function(e) {
console.log(e);
});
mike.on('data', function(data) {
pitch.input(data);
pitch.process();
var tone = pitch.findTone();
if (tone) {
var freq = tone.freq,
note = getNote(freq),
angle = -getAngle(note + 3),
detune = note - Math.round(note),
isFlat = detune < -0.01,
isSharp = detune > 0.01,
inTune = !isFlat && !isSharp;
wheel.rotate(angle);
c.textContent = Math.round(freq);
toggleClass(flat, 'highlighted', isFlat);
toggleClass(sharp, 'highlighted', isSharp);
toggleClass(arrow, 'highlighted', inTune);
// TODO
// 1. octave indicators
}
});
function getNote(frequency, reference) {
if (!frequency) return null;
reference = reference || 440;
return 69 + 12 * Math.log(frequency / reference) / Math.LN2;
}
function getAngle(midiNote) {
return midiNote ? Math.PI * (midiNote % 12) / 6 : 0;
}
function getOctave (midiNote) {
return ~~(midiNote / 12);
}