This repository acts as a personal learning project. Through C++, the learning objective is to combine:
- Audio capture
- Lab Streaming layer (LSL)
- Fastest Fourier Transform of the West (fftw)
- OpenGL
- multuthreading
functionalities to stream data, perform instantaneous power spectral analysis and visualize the data. The project was largely inspired by online tutorials by Christian A. Kothe from Swartz Center for Computational Neuroscience, University of California San Diego: https://youtu.be/Y1at7yrcFW0?si=93i2B3Ol0n_D_U4M
And by Mike Shah's introduction to OpenGL: https://youtube.com/playlist?list=PLvv0ScY6vfd9zlZkIIqGDeG5TUWswkMox&si=PFQdkXjZepEbgN7h
Real-time audio visualization with waveform and FFT power spectrum analysis
Lab Streaming Layer (LSL) is a system for synchronizing time-series data streams in real-time research and development environments. It's commonly used in neuroscience, psychophysiology, and human-computer interaction research to synchronize multiple data sources (EEG, audio, video, sensors, etc.).
This repository contains:
- Basic audio capture and file encoding
- Real-time audio streaming over LSL
- Advanced OpenGL-based visualization with FFT analysis
- Example sender/receiver implementations
- Bluetooth device discovery tool
Basic audio capture application using the miniaudio library.
Purpose: Records audio from the system microphone and saves it to a WAV file.
Key Features:
- Simple direct audio capture
- WAV file encoding
- Minimal dependencies
Audio capture with LSL streaming capabilities.
Purpose: Captures audio from the microphone and streams it in real-time over an LSL outlet.
Key Features:
- Audio recording via miniaudio
- LSL outlet for network streaming
- Mutex-protected data handling
- 41.8 kHz sampling rate
Use Case: Source application for distributed audio processing workflows.
Bluetooth device discovery utility.
Purpose: Scans for nearby Bluetooth devices and displays their information.
Key Features:
- Device inquiry and enumeration
- Name and address reporting
Real-time audio visualization with spectral analysis (Direct capture architecture).
Purpose: Standalone application that captures audio directly from the microphone and displays both waveform and FFT power spectrum in real-time using OpenGL.
Key Features:
- Direct microphone capture
- Dual-trace visualization:
- Waveform display (2-second window)
- Power spectrum (0.4-second FFT window)
- Single-threaded monolithic design
- FFTW3 for frequency analysis
- OpenGL rendering with SDL3
Architecture: Self-contained, captures and visualizes in the same process.
Real-time audio visualization with spectral analysis (Network-based multi-threaded architecture).
Purpose: Receives audio from a remote LSL stream and visualizes it with advanced multi-threaded processing.
Key Features:
- LSL inlet for network audio reception
- Multi-threaded architecture:
- Thread 1: LSL data acquisition
- Thread 2: Trace buffer updates
- Thread 3: Power spectrum computation
- Main thread: OpenGL rendering
- Loosely coupled design (visualization only)
- Higher chunk size (500 samples) for network efficiency
- Template-based generic functions
Architecture: Distributed design intended for use with remote audio sources (like AudioSendLSL).
Use Case: Professional research environments where data acquisition and visualization are separated.
Mathematical function plotting demonstration.
Purpose: Test/example application for the OpenGL plotting framework without requiring audio input.
Key Features:
- Plots mathematical sine functions
- Demonstrates the EpochObject and App classes
- Reference implementation for the plotting system
Basic LSL tutorial examples.
Purpose: Demonstrates the fundamentals of LSL streaming with minimal code.
Files:
simple_sending_example.cpp- Creates an LSL outlet and streams random datasimple_recieving_example.cpp- Creates an LSL inlet and receives/displays data
Key Features:
- Minimal working examples
- Random data generation
- Console-based output
- Perfect for learning LSL basics
- Lab Streaming Layer (LSL) - Time-series streaming protocol
- miniaudio - Cross-platform audio I/O library
- SDL3 - Windowing and OpenGL context management
- GLAD - OpenGL loader
- FFTW3 - Fast Fourier Transform library
- C++11 or later
- CMake (recommended) or manual compilation
- Windows SDK (for Windows builds)
- Visual Studio or MinGW compiler
Projects may require the following DLLs in the executable directory:
SDL3.dlllibfftw3f.dllliblsl.dll(for LSL-enabled projects)
# For PlottingAudioCapture1
g++ -std=c++11 main.cpp GraphLSLData.cpp src/glad.c ^
-Isrc/include ^
-Lsrc/lib/SDL3 -Lsrc/lib/fftw-3.3.10 -Lsrc/lib/lsl ^
-lSDL3 -lfftw3f -llsl ^
-lopengl32 ^
-o main.exeEnsure required DLLs are in the same directory as the executable or in your system PATH.
-
Start the audio source:
cd AudioSendLSL ./main.exe
-
Start the visualizer:
cd PlottingAudioCapture2 ./main.exe
The visualizer will automatically discover and connect to the "MyAudioStream" LSL outlet.
cd PlottingAudioCapture1
./main.exeTerminal 1:
cd SimpleRecievingSending
./simple_sending_example.exeTerminal 2:
cd SimpleRecievingSending
./simple_recieving_example.exe- Sampling Rate: 41,800 Hz (most projects)
- Format: 32-bit float PCM
- Channels: Stereo (2 channels) for capture, mono (1 channel) for LSL streaming
- Waveform Display: 2.0 seconds (83,600 samples @ 41.8 kHz)
- Power Spectrum: 0.4 seconds (16,720 samples @ 41.8 kHz)
- FFT Output: (N+1)/2 frequency bins
- OpenGL Version: 4.1 Core Profile
βββββββββββββββββββ
β LSL Network β
β Stream β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β Thread 1: ββββββΆβ Mutex-Protected β
β ReadLSLData β β Vector Buffer β
βββββββββββββββββββ ββββββββββ¬ββββββββββ
β
βΌ
ββββββββββββββββββββ
β Thread 2: β
β UpdateTrace β
ββββββββββ¬ββββββββββ
β
βΌ
ββββββββββββββββββββ
β Thread 3: β
β UpdatePowerSpec β
ββββββββββ¬ββββββββββ
β
βΌ
ββββββββββββββββββββ
β Main Thread: β
β Render Graphics β
ββββββββββββββββββββ
Projects use LSL's resolver to automatically discover streams by name:
std::vector<lsl::stream_info> streaminfos = lsl::resolve_stream("name", "MyAudioStream");
lsl::stream_inlet inlet(streaminfos[0]);This repository demonstrates a progression from simple to complex:
- AudioCapture - Basic audio I/O
- AudioSendLSL - Adding network streaming
- PlottingFunction - Introducing visualization
- PlottingAudioCapture1 - Combining capture + visualization
- PlottingAudioCapture2 - Advanced multi-threaded distributed architecture
Each project builds on concepts from the previous ones while introducing new techniques.
MIT License
