Skip to content

Latest commit

 

History

63 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fdf

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

Mandatory — Fdf/

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 .fdf files, handles variable-width grids, per-pixel hex colors
  • Isometric projectioniso() 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; z scaling and spacing are computed from the map's min/max elevation
  • MiniLibX — single window, ESC to quit
./fdf maps/42.fdf

Mandatory fdf wireframe


Bonus — Fdf-bonus/

Extends the mandatory with interactive controls and a second projection mode.

  • Dual projection — toggle between isometric (iso) and dimetric (dim) with M
  • Rotation — rotate the mesh with B (counter-clockwise) and N (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 projectiont_proj lets the map switch projection at runtime
make bonus
./bonus maps/42.fdf

assets/bonus-fdf.mkv Video displaying dual projection, rotation, pan, zoom, z-scale


Super Bonus — Fdf-sbonus/

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.

What it does

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.

Architecture

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_mainloop and connects to the PulseAudio server
  • Opens a recording stream on the monitor source at 192 kHz, stereo, S16LE
  • Uses PA_STREAM_ADJUST_LATENCY with a 1 ms buffer (tlength) and fragsize=1 for minimum latency
  • A stream_read_callback peeks the latest PCM samples and stores the pointer in the shared t_env.buffer

Render thread (mlx_thread)

  • Creates the MiniLibX window (1000x1000) and an alpha-capable image buffer
  • draw_routine() runs on every mlx_loop_hook tick:
    1. Checks g_stop — if set, calls mlx_loop_end() for a clean exit
    2. Clears the screen: either full opaque clear (default) or image-recreate (GLASS mode for afterglow trails)
    3. Plots each stereo sample pair as a single pixel: x = half - half * (left / MAXPCM), y = half - half * (right / MAXPCM)
    4. If RAINBOW is enabled, cycles the draw color through the HSV hue wheel every 10 ticks
    5. Pushes the image to the window

Features

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

Build & run

# 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_visualizer

Compile-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

assets/osci.mkv Oscilloscope with standard music

assets/shrooms-osci.mkv Oscilloscope on oscilloscope music (shrooms)

assets/core-osci.mkv Oscilloscope on oscilloscope music (core)

assets/debug-osci.mkv debug mode showing separate left/right channel waveforms and normal lissajous oscilloscope shapes


Build system

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.


Resources

AI usage

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.

About

Wireframe 3D terrain renderer and real-time audio oscilloscope

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages