-
Notifications
You must be signed in to change notification settings - Fork 1
/
sketch.js
160 lines (131 loc) · 4.5 KB
/
sketch.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// The muse client.
let client;
// The fft object.
let fft;
// How many samples do we analyze at a time with the FFT.
let fftBufferSize = 256;
// The amount of samples per second provided by the Muse.
let samplingFrequencyHz = 256;
// The electrode that we are interested in.
let electrode = 0;
// The sample buffer for the electrode above.
// We will keep accumulating up to fftBufferSize, then remove those and analyze them.
let samples = [];
let totalSamplesProcessed = 0;
let alpha = 0;
let beta = 0;
let theta = 0;
let delta = 0;
function setup() {
createCanvas(1024, 400);
client = new muse.musejs.MuseClient();
fft = new FFT(fftBufferSize, samplingFrequencyHz);
setupGui();
}
function draw() {
background(0);
// The spectrum here will be broken up into fftBufferSize / 2 bands.
// The center frequencies of each band are noted below.
// To caculate the amount of "alpha" waves, you will want to pay attention
// to the total activity in the 9-14 Hz bands (for instance). Here we just
// add up the contributions in each of the ranges.
alpha = 0;
beta = 0;
theta = 0;
delta = 0;
// If a spectrum has been clalculated ...
// The spectrum is the power in each frequency bin.
let boxWidth = width / fft.spectrum.length;
let x = 0;
let y = height;
let peak = fft.peak; // The value of the max peak.
let peakBand = fft.peakBand; // The index with the max peak.
for (let i = 0; i < fft.spectrum.length; i++) {
let w = boxWidth;
let x = i * w;
let h = map(fft.spectrum[i], 0, peak, 0, height);
// Pick the box fill color based on if it is the max peak.
if (i == peakBand) fill("red");
else fill("blue");
// Negative height to draw upward.
rect(x, y, w, -h);
let bandCenterFrequency = fft.getBandFrequency(i);
push();
translate(x + w / 2, y - 10);
rotate(PI / 2);
fill("white");
textSize(8);
textAlign(RIGHT);
text(bandCenterFrequency + " Hz", 0, 0);
pop();
if (bandCenterFrequency >= 1 && bandCenterFrequency <= 3) {
delta += fft.spectrum[i];
} else if (bandCenterFrequency >= 4 && bandCenterFrequency <= 8) {
theta += fft.spectrum[i];
} else if (bandCenterFrequency >= 9 && bandCenterFrequency <= 14) {
alpha += fft.spectrum[i];
} else if (bandCenterFrequency >= 15 && bandCenterFrequency <= 30) {
beta += fft.spectrum[i];
}
}
fill(255);
textSize(20);
text("Total Samples Processed: " + totalSamplesProcessed, 10, 20);
text("Alpha: " + alpha, 10, 40);
text("Beta : " + beta, 10, 60);
text("Delta: " + delta, 10, 80);
text("Theta: " + theta, 10, 100);
}
function setupGui() {
const connectButton = createButton("Connect");
connectButton.mousePressed(connect);
const disconnectButton = createButton("Disconnect");
disconnectButton.mousePressed(disconnect);
}
async function connect() {
if (client) {
try {
await client.connect();
await client.start();
client.eegReadings.subscribe((reading) => {
// Unpack the samples from each EEGReading.
// Each eeg reading is this data structure:
// https://github.com/urish/muse-js/blob/master/src/lib/muse-interfaces.ts#L1-L6
if (reading.electrode == electrode) {
// Add the new samples to the existing samples.
samples = samples.concat(reading.samples);
// Keep track of this for reference.
totalSamplesProcessed += reading.samples.length;
// If we have enough samples in our sample buffer,
// then do the fft.
while (samples.length >= fftBufferSize) {
// Process some samples from our buffer.
fft.forward(samples.slice(0, fftBufferSize));
// Remove the samples that were processed from our buffer.
samples = samples.slice(fftBufferSize);
}
}
});
// The following data tracks head movement and might
// be nice to use to move particles around too ...
// See this for the data structures used
// https://github.com/urish/muse-js/blob/master/src/lib/muse-interfaces.ts#L21-L24
// client.telemetryData.subscribe((telemetry) => {
// console.log(telemetry);
// });
// client.accelerometerData.subscribe((acceleration) => {
// console.log(acceleration);
// });
// client.gyroscopeData.subscribe((gyro) => {
// console.log(gyro);
// });
} catch (err) {
console.error(err);
}
}
}
async function disconnect() {
if (client) {
await this.client.disconnect();
}
}