Files
autosample/README.md
2026-03-12 16:30:04 -04:00

175 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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, and the [Vulkan SDK](https://vulkan.lunarg.com/) (for headers, `vulkan-1.lib`, and `glslc`). The build system looks for `%VULKAN_SDK%` or falls back to `C:\VulkanSDK\1.4.341.1`.
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 both build directories, vendor libraries, and generated sources. Invalid arguments produce an error with usage info.
## 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, per-monitor DPI awareness (v2) with `WM_DPICHANGED` handling
- **macOS**: `platform_macos.mm` — Cocoa/AppKit, NSWindow, NSTextInputClient
### UI layer (`src/ui/`)
A thin wrapper around [Clay](https://github.com/nicbarker/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_vulkan.cpp` — Vulkan, GLSL shaders (compiled to SPIR-V at build time)
- **macOS**: `renderer_metal.mm` — Metal, MSL shaders
Both renderers share the same vertex format (18 floats), SDF rounded-rect shader, and Clay command processing logic. Font rasterization and text measurement use FreeType on both platforms with the embedded [Inter](https://rsms.me/inter/) typeface. The font atlas is a 1024x1024 R8 texture containing ASCII glyphs 32126 rasterized at a fixed pixel size; text at other sizes is scaled from the atlas. The Inter TTF is embedded at build time as a C byte array (`font_inter.gen.h`) so there are no runtime font file dependencies. Font scale is multiplied by the platform DPI scale factor for crisp rendering on high-DPI displays.
### 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 build)
assets/
fonts/
Inter-Regular.ttf Inter typeface (SIL Open Font License)
OFL.txt Font license
vendor/
nob/
nob.h nob build system (vendored, single-header)
clay/
clay.h Clay v0.14 (modified for MSVC C++ compatibility)
freetype/
include/ FreeType 2.13.3 public headers
src/ FreeType source (minimal module set)
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 (per-monitor DPI aware)
platform_macos.mm macOS Cocoa implementation
renderer/
renderer.h Renderer API (graphics-agnostic)
renderer_dx12.cpp DirectX 12 implementation
renderer_metal.mm Metal implementation
font_inter.gen.h Generated at build time — embedded font data
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, etc.) ship with the OS.
- [nob.h](https://github.com/tsoding/nob.h) — build system
- [Clay](https://github.com/nicbarker/clay) — single-header C layout library (v0.14, with MSVC C++ patches)
- [FreeType](https://freetype.org/) — font rasterizer (v2.13.3, FreeType License). Compiled as a static library with a minimal module set (truetype, sfnt, smooth, autofit, psnames, pshinter, gzip). Replaces platform-specific font backends (GDI on Windows, Core Text on macOS) for consistent cross-platform text rendering. Static libraries are built into their vendor directories (`vendor/freetype/freetype.lib` on Windows, `vendor/freetype/libfreetype.a` on macOS); debug builds on Windows use a `_d` suffix to avoid CRT mismatch.
- [Inter](https://rsms.me/inter/) — typeface (v4.1, SIL Open Font License). Embedded at build time as a C byte array header so there are no runtime font file dependencies.
- [LunaSVG](https://github.com/nicbarker/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](https://github.com/nicbarker/plutovg) as its 2D vector graphics backend.