First Signals on Screen

After getting the dev environment working, I had eight channels of synthetic EEG scrolling across a black window. Cool to look at, not very useful. So I spent the next round making it into something I can actually work with.

EEG visualizer showing 8 channels with threshold indicators and ImGui controls

Dear ImGui for live controls

First order of business: stop recompiling every time I want to change a parameter. Sokol has a sokol_imgui.h bridge that makes Dear ImGui integration almost trivial. Two sliders give me vertical gain (how tall the waveforms are) and time window (how many samples fit on screen). Sounds simple but being able to drag these while data is streaming changes everything. You can zoom into a few milliseconds of signal or pull back to see the full second.

ImGui::Begin("Signal Controls");
ImGui::SliderFloat("Vertical Gain", &g_vertical_gain, 0.001f, 0.05f);
ImGui::SliderInt("Time Window (Samples)", &g_time_window, 10, 1000);
ImGui::End();

Two traces per channel

I’m drawing each channel twice. A gray trace shows the raw signal, noise and all. On top of that, a colored trace renders a quick 3-sample moving average:

float avg_val = (g_ch[c].data[idx] + g_ch[c].data[i1] + g_ch[c].data[i2]) / 3.0f;

Not real filtering. Just enough smoothing to visually separate the waveform shape from the noise floor. Proper bandpass and notch filters will come later through BrainFlow’s DataFilter.

Threshold detection (very rough)

I also threw in a per-channel threshold check. If a sample crosses 100 µV, a red dot lights up on the right side of that channel. One line of code:

g_trigger_active[c] = (val > g_threshold);

No debouncing, no hysteresis, no artifact rejection. It fires on noise all the time. But the point isn’t to detect real brain events yet. The point is to prove the pipeline works end to end: BrainFlow streams data, each sample gets evaluated in real time, and the result shows up visually in the same frame. That’s the wiring I’ll need when I replace this with an actual detector.

What’s next

Hook up the real Cyton board over serial instead of the synthetic data, add BrainFlow’s built-in filters to clean things up, and start thinking about what it looks like to stream this to a remote endpoint.