2026-03-05 03:08:22 -05:00
2026-03-05 02:31:31 -05:00
2026-03-05 02:31:31 -05:00
2026-03-05 03:08:22 -05:00
2026-03-05 02:31:31 -05:00
2026-03-05 03:08:22 -05:00
2026-03-05 03:08:22 -05:00
2026-02-22 17:12:57 -05:00

autosample

Graphical interface for automatically recording samples from existing analog audio hardware.

Build

Windows

Requires MSVC (Visual Studio 2019 Build Tools or later) with the Windows SDK and C++20 support.

Open a Developer Command Prompt, then:

cl /nologo build.c
build.exe debug
build_debug\autosample.exe

macOS

Requires Xcode Command Line Tools (xcode-select --install).

cc build.c -o build
./build debug
open build_debug/autosample.app

The first command is a one-time bootstrap. After that, ./build detects changes to build.c and rebuilds itself automatically. Pass debug for a debug build (output in build_debug/) or omit for release (build_release/). Pass clean to wipe the build directory.

Architecture

The project uses a unity build: src/main.cpp includes all other .cpp/.mm files, producing a single translation unit compiled with one compiler invocation. Platform selection is handled with #ifdef __APPLE__ guards.

Base layer (src/base/)

Foundational types and utilities shared across the project. Provides sized integer/float typedefs (U8, S32, F32, B32, etc.), math primitives (Vec2F32), string helpers, and arena allocators. This layer has no dependencies beyond the C standard library.

Platform layer (src/platform/)

Abstracts window creation, event polling, menus, clipboard, and native handles behind a C-style API with opaque PlatformWindow handles.

  • Windows: platform_win32.cpp — Win32/HWND, WM_* message loop
  • macOS: platform_macos.mm — Cocoa/AppKit, NSWindow, NSTextInputClient

UI layer (src/ui/)

A thin wrapper around Clay (v0.14), a single-header C layout library. Clay uses macros (CLAY(), CLAY_TEXT(), etc.) for declarative layout with automatic sizing, flex-like child arrangement, and built-in text measurement.

  • ui_core.h / ui_core.cpp — Defines UI_Context and UI_Theme, handles Clay initialization, lifecycle (ui_begin_frame / ui_end_frame), text measurement bridge, theme/accent management, and error handling. CLAY_IMPLEMENTATION is defined here.
  • ui_widgets.h / ui_widgets.cpp — Immediate-mode widget library: buttons, checkboxes, radio groups, text inputs (with selection, clipboard, Tab cycling), dropdowns, tab bars, draggable windows, and modal dialogs.
  • ui_icons.h / ui_icons.cpp — SVG icon atlas rasterized at startup via lunasvg. Icons are rendered as custom Clay elements.

The application layout is built in main.cpp using Clay macros directly. Panel builder functions (build_browser_panel, build_main_panel, etc.) compose the UI each frame.

Theme system

The UI supports a full theme system managed through UI_Theme (ui_core.h) with live switching at runtime:

  • Base themes: Dark and Light, selectable via ui_set_theme(). Each defines a full palette — backgrounds, borders, text, accent colors, title bars, scrollbars, tab colors, and drop shadow opacity.
  • Accent palettes: 7 color options (Blue, Turquoise, Orange, Purple, Pink, Red, Green) applied via ui_set_accent(). Each palette provides coordinated accent, hover, tab gradient, button text, and tab text colors tuned for both dark and light base themes.
  • Corner radius: Configurable at runtime (None / Small / Medium / Large) via g_theme.corner_radius. All widgets read CORNER_RADIUS which scales with uis().
  • UI scale: Cmd+/Cmd- (Ctrl on Windows) zoom from 0.5x to 3.0x. All widget sizes, padding, font sizes, and corner radii scale via uis() / uip() / uifs() helpers.

Visual depth

Interactive elements use subtle visual effects for a DAW-style look:

  • Gradients: Buttons, title bars, dropdown headers, and tab bars use vertical gradients via Clay's CLAY_RENDER_COMMAND_TYPE_CUSTOM system and a per-frame CustomGradientData pool. Buttons and title bars are lighter on top (raised), text inputs are darker on top (inset/recessed).
  • Drop shadows: Floating windows, modals, and dropdown lists cast soft multi-layer shadows. 7 concentric rects with linearly decreasing opacity simulate a gaussian blur, offset down-right for directional lighting.
  • Panel highlights: 1px lighter lines at the top of panel content areas simulate beveled edges.

Renderer (src/renderer/)

Custom SDF-based pipeline for UI rendering. Processes Clay's Clay_RenderCommandArray output directly — no intermediate scene graph.

  • Windows: renderer_dx12.cpp — DirectX 12, HLSL shaders, GDI font atlas (Segoe UI)
  • macOS: renderer_metal.mm — Metal, MSL shaders, Core Text font atlas (SF Pro)

Both renderers share the same vertex format (18 floats), SDF rounded-rect shader, and Clay command processing logic. Text measurement uses GDI on Windows and Core Text on macOS.

Audio (src/audio/)

Audio device enumeration and output with test tone generation.

  • Windows: audio_asio.cpp — ASIO driver via COM, registry enumeration, multi-format sample writing
  • macOS: audio_coreaudio.cpp — CoreAudio with AUGraph/HAL Output, Float32 non-interleaved

MIDI (src/midi/)

MIDI device enumeration with real-time input monitoring.

  • Windows: midi_win32.cpp — Win32 multimedia API (midiIn* / midiOut*)
  • macOS: midi_coremidi.cpp — CoreMIDI client with single input port, source connection

Project structure

build.c                            Build script (cc build.c -o nob)
vendor/
  nob/
    nob.h                          nob build system (vendored, single-header)
  clay/
    clay.h                         Clay v0.14 (modified for MSVC C++ compatibility)
src/
  main.cpp                         Entry point, unity build includes, Clay layout
  menus.cpp                        Menu bar setup
  base/
    base_core.h                    Sized types, macros
    base_arena.h / .cpp            Arena allocator
    base_math.h                    Vec2, min/max
    base_strings.h / .cpp          String utilities
    base_inc.h / .cpp              Aggregate include/impl
  platform/
    platform.h                     Window management API (platform-agnostic)
    platform_win32.cpp             Win32 implementation
    platform_macos.mm              macOS Cocoa implementation
  renderer/
    renderer.h                     Renderer API (graphics-agnostic)
    renderer_dx12.cpp              DirectX 12 implementation
    renderer_metal.mm              Metal implementation
  ui/
    ui_core.h                      Clay wrapper, UI_Theme, scale helpers, custom render types
    ui_core.cpp                    Clay init, text measurement bridge, theme/accent palettes
    ui_widgets.h / .cpp            Immediate-mode widgets (button, checkbox, radio, text input, dropdown, tab bar, window, modal)
    ui_icons.h / .cpp              SVG icon atlas (check, close, chevron) via lunasvg
  audio/
    audio.h                        Audio device and playback API
    audio_asio.cpp                 Windows ASIO implementation
    audio_coreaudio.cpp            macOS CoreAudio implementation
  midi/
    midi.h                         MIDI device enumeration API
    midi_win32.cpp                 Win32 multimedia implementation
    midi_coremidi.cpp              macOS CoreMIDI implementation

Modifications to vendor/clay/clay.h

Two targeted patches for MSVC C++ compatibility:

  1. CLAY__CONFIG_WRAPPER bypass (lines 158163): MSVC C++ rejects designated initializers inside function-style casts. In C++ mode, the wrapper struct is bypassed: (type { __VA_ARGS__ }) instead of (WrapperType { .field = ... }).wrapped.

  2. Debug view stub (lines ~31553858): Clay's built-in debug view functions use CLAY__INIT(type) { .field = ... } directly (not through CLAY__CONFIG_WRAPPER), which also fails in MSVC C++. An #ifdef __cplusplus guard stubs out the 4 debug view functions as empty no-ops. The debug overlay is not needed.

These patches allow the entire project (including Clay) to compile as a single C++20 translation unit, avoiding C/C++ ABI mismatches with CLAY_PACKED_ENUM (which controls enum sizing differently in C vs C++ mode).

Code style

This project is written in C-style C++. We use .cpp files and a small subset of C++ features (default struct values, function overloading, namespaces where useful) but avoid the rest. No classes, no inheritance, limit templates, no exceptions, no RTTI, avoid STL containers or algorithms. Data is plain structs. Functions operate on those structs, or pointers to them. macOS files use .mm extension for Objective-C++ interop.

Memory should be managed with arena allocators where possible rather than individual malloc/free or new/delete calls. Arenas make allocation fast, avoid fragmentation, and simplify cleanup.

Syntax style

  • Opening braces go on the same line as the function signature (K&R style), not on the next line.
  • Use CAPS_SNAKE_CASE for constants, lower_snake_case for functions and variables, and CapsCamelCase for types.

Dependencies

All dependencies are vendored as source. On Windows, nothing to install beyond the Windows SDK. On macOS, only Xcode Command Line Tools are needed — all frameworks (Metal, Cocoa, CoreAudio, CoreMIDI, CoreText, etc.) ship with the OS.

  • nob.h — build system
  • Clay — single-header C layout library (v0.14, with MSVC C++ patches)
  • LunaSVG — SVG rendering library (MIT, by Samuel Ugochukwu) used to rasterize icon SVGs into an R8 texture atlas at startup. Icons (close, check, chevron, knob) are defined as inline SVG strings in ui_icons.cpp and rendered at a fixed pixel size into a packed atlas. The atlas is uploaded to the GPU once and sampled by the renderer for icon and rotated-icon custom elements. Bundled with PlutoVG as its 2D vector graphics backend.
Description
Graphical interface for automatically recording samples from existing analog audio hardware
Readme 6.2 MiB
Languages
C 87%
Objective-C 12.2%
GLSL 0.8%