A 42 Lyon project — wireframe 3D terrain renderer and real-time audio oscilloscope, built in C with the MiniLibX graphics library.
The repository is organised in three independent build targets:
| Target | Directory | Binary | Description |
|---|---|---|---|
| Mandatory | Fdf/ |
fdf |
Isometric wireframe terrain viewer |
| Bonus | Fdf-bonus/ |
bonus |
Enhanced viewer with projections, zoom, pan, rotation |
| Super Bonus | Fdf-sbonus/ |
oscilloscope_visualizer |
Real-time audio oscilloscope via PulseAudio |
The core project: read a .fdf map file (a grid of integers representing elevation, with optional 0xRRGGBB colors) and render it as a wireframe mesh in an isometric projection.
- Map parsing — reads
.fdffiles, handles variable-width grids, per-pixel hex colors - Isometric projection —
iso()converts 3D coordinates(x, y, z)to 2D screen space - Bresenham line drawing — connects each grid point to its right and bottom neighbours
- Auto-centering — the mesh is centered on screen;
zscaling and spacing are computed from the map's min/max elevation - MiniLibX — single window, ESC to quit
./fdf maps/42.fdf
Extends the mandatory with interactive controls and a second projection mode.
- Dual projection — toggle between isometric (
iso) and dimetric (dim) withM - Rotation — rotate the mesh with
B(counter-clockwise) andN(clockwise) - Pan — arrow keys move the mesh on screen
- Zoom — mouse wheel adjusts the grid spacing
- Z-scale —
,and.adjust the elevation scale factor - Function-pointer projection —
t_projlets the map switch projection at runtime
make bonus
./bonus maps/42.fdf
Video displaying dual projection, rotation, pan, zoom, z-scale
A real-time audio oscilloscope that captures system audio via PulseAudio and renders it as an X-Y vector display in a MiniLibX window. This is the most technically involved part of the project.
The program listens to a PulseAudio monitor source (by default the FiiO K7 USB DAC output) and plots the live audio waveform in X-Y mode: the left channel drives the X axis, the right channel drives the Y axis. This produces the classic vector-graphics patterns seen on hardware oscilloscopes — Lissajous figures, phase rings, rotating shapes — that respond in real time to whatever music is playing.
The program runs two POSIX threads in parallel, coordinated by a mutex-protected g_stop flag and a SIGINT handler for clean shutdown:
┌──────────────┐
│ main() │
│ signal(SIGINT)│
└──────┬───────┘
│
┌────────────┴────────────┐
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ pa_thread │ │ mlx_thread │
│ (PulseAudio)│ │ (MiniLibX)│
└─────┬─────┘ └─────┬─────┘
│ │
│ int16_t *buffer │ draw_routine()
│ (shared via t_env) │ mlx_loop_hook()
│ │
┌─────▼─────────────────────────▼─────┐
│ t_env (shared) │
│ buffer, buf_len, pa, mlx │
└──────────────────────────────────────┘
Audio thread (pa_thread)
- Creates a
pa_threaded_mainloopand connects to the PulseAudio server - Opens a recording stream on the monitor source at 192 kHz, stereo, S16LE
- Uses
PA_STREAM_ADJUST_LATENCYwith a 1 ms buffer (tlength) andfragsize=1for minimum latency - A
stream_read_callbackpeeks the latest PCM samples and stores the pointer in the sharedt_env.buffer
Render thread (mlx_thread)
- Creates the MiniLibX window (1000x1000) and an alpha-capable image buffer
draw_routine()runs on everymlx_loop_hooktick:- Checks
g_stop— if set, callsmlx_loop_end()for a clean exit - Clears the screen: either full opaque clear (default) or image-recreate (GLASS mode for afterglow trails)
- Plots each stereo sample pair as a single pixel:
x = half - half * (left / MAXPCM),y = half - half * (right / MAXPCM) - If
RAINBOWis enabled, cycles the draw color through the HSV hue wheel every 10 ticks - Pushes the image to the window
- Checks
| Feature | Description |
|---|---|
| X-Y vector display | Left channel → X, right channel → Y. Produces Lissajous patterns from stereo audio |
| 192 kHz sample rate | 4x oversampling for dense, smooth vector traces |
| Multithreaded | PulseAudio and MiniLibX run in separate pthreads, sharing a lock-free buffer pointer |
| Rainbow color cycling | Optional HSV hue rotation (RAINBOW=1 compile flag) |
| Afterglow / GLASS mode | GLASS=1 recreates the image each frame instead of clearing — produces phosphor-like trails |
| Debug mode | DEBUG=1 draws both channels as separate time-domain waveforms (left top, right below) |
| Clean shutdown | SIGINT and ESC both signal g_stop via mutex; each thread exits its loop and joins cleanly |
| Audio tests | make audio builds a separate binary (audio_tests/) with PulseAudio faders and dBFS metering |
# Dependencies (Debian/Ubuntu)
sudo apt install libpulse-dev libx11-dev libxext-dev libxrender-dev libasound2-dev
# Build the oscilloscope
make sbonus
# Run (audio plays from your default output device)
./oscilloscope_visualizerCompile-time flags (set via make variables in Fdf-sbonus/Makefile):
| Flag | Default | Effect |
|---|---|---|
WIDTH |
1000 | Window width |
HEIGHT |
1000 | Window height |
RAINBOW |
0 | Enable rainbow color cycling |
GLASS |
0 | Enable afterglow trail effect |
DEBUG |
0 | Draw time-domain waveforms instead of X-Y |
Example: rainbow + glass afterglow
make sbonus RAINBOW=1 GLASS=1
Oscilloscope with standard music
Oscilloscope on oscilloscope music (shrooms)
Oscilloscope on oscilloscope music (core)
debug mode showing separate left/right channel waveforms and normal lissajous oscilloscope shapes
The root Makefile conditionally includes sub-Makefiles depending on the target:
| Command | What it builds |
|---|---|
make |
Mandatory fdf binary |
make bonus |
Bonus bonus binary |
make sbonus |
Super Bonus oscilloscope_visualizer binary |
make audio |
Audio test utilities from Fdf-sbonus/audio_tests/ |
make debug |
Mandatory with -g and DEBUG=1 |
make clean / fclean / re |
Clean / full clean / rebuild |
Both fdf and bonus link against libft and minilibx-linux. The super bonus links against libft, minilibx-linux-edit (a fork with alpha image support), PulseAudio, ALSA, and pthreads.
- PulseAudio API documentation
- MiniLibX — 42 school's minimal X11 graphics library
- Bresenham's line algorithm — used for wireframe drawing
- HSV color space — used for the rainbow transition
- Lissajous curve — the patterns produced by X-Y oscilloscope mode
AI assistance was used for:
- Understanding PulseAudio's threaded mainloop and callback-based API
- Debugging thread synchronization and mutex patterns
- HSV ↔ RGB color conversion math
- Structuring this README
All generated code was reviewed, tested, and understood before inclusion.
