-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
131 lines (103 loc) · 4.49 KB
/
app.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
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
129
130
131
// 1.0 Creating a module called "SynthPad"
// contains all the letiables and functions that are lerated to it
let SynthPad = (function() {
// 1.1 letiables (undefined -- to store the references to ley elements):
let myCanvas;
let frequencyLabel;
let volumeLabel;
let myAudioContext;
let oscillator;
let gainNode;
// 1.2 Notes:
let lowNote = 261.63; // C4
let highNote = 493.88; // B4
//
// put the rest of the code here
// 2.0 Constructor:
let SynthPad = function() {
myCanvas = document.getElementById('synth-pad');
frequencyLabel = document.getElementById('frequency');
volumeLabel = document.getElementById('volume');
// 2.1 Create an audio context:
// The AudioContext interface provide methods for creating audioNodes
// that represent audio sources, processing modules or the audio destination.
// it also manages how different AudioNodes are connected to each other.
window.AudioContext = window.AudioContext || window.webkitAudioContext;
myAudioContext = new window.AudioContext();
SynthPad.setupEventListeners();
};
// 3.0 Event Listeners:
SynthPad.setupEventListeners = function() {
// 3.1 Disables scrolling on touch devices
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
myCanvas.addEventListener('mousedown', SynthPad.playSound);
myCanvas.addEventListener('touchstart', SynthPad.playSound);
myCanvas.addEventListener('mouseup', SynthPad.stopSound);
document.addEventListener('mouseleave', SynthPad.stopSound);
myCanvas.addEventListener('touchend', SynthPad.stopSound);
};
// 4.0 Creating Sounds
// 4.1 play a note.
SynthPad.playSound = function(event) {
oscillator = myAudioContext.createOscillator(); // an oscillator node, audio source(e,g, guitar)
gainNode = myAudioContext.createGain(); // control the volume (e,g, effects pedal)
oscillator.type = "square"; // sine, square, sawtooth, triangle, custom
gainNode.connect(myAudioContext.destination); // (e,g, the amplifier)
// like adding thecables between the guitar, effects pedal and amp
oscillator.connect(gainNode);
SynthPad.updateFrequency(event); // set the note frequency and volume based on the position of the cursor on the pad
oscillator.start(0); // fires up the OscillatorNode
myCanvas.addEventListener('mousemove', SynthPad.updateFrequency);
myCanvas.addEventListener('touchmove', SynthPad.updateFrequency);
myCanvas.addEventListener('mouseout', SynthPad.stopSound);
};
// 5.0 Stopping sounds
// 5.1 stop the audio
SynthPad.stopSound = function(event) {
oscillator.stop(0);
myCanvas.removeEventListener('mousemove', SynthPad.updateFrequency);
myCanvas.removeEventListener('touchmove', SynthPad.updateFrequency);
myCanvas.removeEventListener('mouseout', SynthPad.stopSound);
};
// 6.0 Changing the Pith and volume
// 6.1 calculate the note frequency.
SynthPad.calculateNote = function(posX) {
let noteDifference = highNote - lowNote; // calculate therange between the highNote and lowNote variables
let noteOffset = (noteDifference / myCanvas.offsetWidth) * (posX - myCanvas.offsetLeft);
return lowNote + noteOffset;
};
// 6.2 calculate the volume.
SynthPad.calculateVolume = function(posY) {
let volumeLevel = 1 - (((100 / myCanvas.offsetHeight) * (posY - myCanvas.offsetTop)) / 100);
return volumeLevel;
};
// 6.3 fetch the new frequency and volume.
SynthPad.calculateFrequency = function(x, y) {
let noteValue = SynthPad.calculateNote(x); // get note values
let volumeValue = SynthPad.calculateVolume(y); // get volume values
oscillator.frequency.value = noteValue;
gainNode.gain.value = volumeValue;
frequencyLabel.innerHTML = Math.floor(noteValue) + 'Hz';
volumeLabel.innerHTML = Math.floor(volumeValue * 100) + '%';
};
// 6.4 update the note frequency
SynthPad.updateFrequency = function(event) {
if (event.type == 'mousedown' || event.type == 'mousemove') {
SynthPad.calculateFrequency(event.x, event.y);
} else if (event.type == 'touchstart' || event.type == 'touchmove') {
let touch = event.touches[0];
SynthPad.calculateFrequency(touch.pageX, touch.pageY);
}
};
// 2.2 Export SynthPad:
// when SynthPad is initialized elsewhere in the app the constructor will be called
return SynthPad;
//
}) ();
// 1.3 Initialize the page.
// attach an event listener to the window.onload
window.onload = function() {
let synthPad = new SynthPad();
}