diff options
| author | skal <pascal.massimino@gmail.com> | 2026-01-31 14:08:00 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-01-31 14:08:00 +0100 |
| commit | e4aadd83ffe0d0ff33d8ca058c192decbb25974b (patch) | |
| tree | 6884fb70359e7db8009c4ef7e5235d33242ef059 | |
| parent | 50d4bd635a5fd8aaf6f19b713c10bbb445301b97 (diff) | |
update state in .md files
| -rw-r--r-- | PROJECT_CONTEXT.md | 85 | ||||
| -rwxr-xr-x | scripts/build_win.sh | 3 | ||||
| -rw-r--r-- | src/gpu/gpu.cc | 36 |
3 files changed, 62 insertions, 62 deletions
diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md index 650189a..0e47b33 100644 --- a/PROJECT_CONTEXT.md +++ b/PROJECT_CONTEXT.md @@ -27,14 +27,16 @@ Incoming tasks in no particular order: - [x] 1. add a fullscreen mode (as command line option) - [x] 2. parse the keyboard key. Exit the demo when 'esc' is pressed. Toggle full-screen when 'f' is pressed. - [x] 3. add binary crunchers for all platforms -- 4. add cross-compilation for PC+linux (x86_64) and PC+Windows (.exe binary) +- [ ] 4. add cross-compilation for PC+linux (x86_64) and PC+Windows (.exe binary) + - [x] PC+Windows (.exe binary) via MinGW + - [ ] PC+linux (x86_64) - 5. implement a spectrogram editor for representing .spec with elementary shapes (bezier curves, lines, random noise, rectangles...) as a mean of compression / spec generation - 6. add a scripting tool to edit the demo (compiled into the binary at the end) - [x] 7. compile wgpu-native in optimized mode (not unoptimized) - [x] 8. add a #define STRIP_ALL to remove all unnecessary code for the final build (for instance, command-line args parsing, or unnecessary options, constant parameters to function calls, etc.) - [x] 9. work on the compact in-line and off-line asset system (@ASSET_SYSTEM.md) -- 10. optimize spectool to remove trailing zeroes from a spec file before saving it -- 11. implement a general [time / timer / beat] system in the demo, for effects timing +- [x] 10. optimize spectool to remove trailing zeroes from a spec file before saving it +- [x] 11. implement a general [time / timer / beat] system in the demo, for effects timing ## Session Decisions and Current State @@ -48,37 +50,48 @@ Incoming tasks in no particular order: ### Build System: - **Production Pipeline**: Automated the entire assembly process via a `final` CMake target (`make final`). - **Automation**: This target builds the tools, runs the `gen_assets.sh` script to re-analyze audio and regenerate sources, and then performs final binary stripping and crunching (using `strip` and `gzexe` on macOS). -- **Scripts**: - - `scripts/gen_assets.sh`: Re-analyzes source audio files into `.spec` format and triggers the `asset_packer`. - - `scripts/crunch_demo.sh`: Performs the final size optimization and compression. +- **Windows Cross-Compilation**: Implemented a full pipeline from macOS to Windows x86_64 using MinGW. + - `scripts/fetch_win_deps.sh`: Downloads pre-compiled GLFW and `wgpu-native` binaries. + - `scripts/build_win.sh`: Cross-compiles the demo, bundles MinGW DLLs, and crunches the binary. + - `scripts/run_win.sh`: Executes the resulting `.exe` using Wine. + - `scripts/crunch_win.sh`: Strips and packs the Windows binary using UPX (LZMA). + - `scripts/analyze_win_bloat.sh`: Reports section sizes and top symbols for size optimization. ### Audio Engine (Synth): - **Architecture**: Real-time additive synthesis from spectrograms using Inverse Discrete Cosine Transform (IDCT). -- **Dynamic Updates**: Implemented a double-buffering (flip-flop) mechanism for thread-safe, real-time updates of spectrogram data. The main thread writes to a back buffer, which is then atomically swapped to become the active front buffer for the audio thread, avoiding real-time allocations and locks. +- **Dynamic Updates**: Implemented a double-buffering (flip-flop) mechanism for thread-safe, real-time updates of spectrogram data. - **Peak Detection**: Real-time output peak detection with exponential decay for smooth visual synchronization. -- **Sample Generation**: Samples are generated in the frequency domain (spectrograms) and converted to time-domain audio using IDCT with a Hamming window. -- **Audio Input Support (`spectool`)**: Supports WAV and MP3 input for analysis (leveraging `miniaudio`'s built-in decoders). AAC is explicitly *not* supported due to complexity and dependency constraints. - -### Tools Developed: -- `spectool`: A command-line tool for analyzing WAV/MP3 files into `.spec` spectrogram format and for playing back `.spec` files through the synth engine. -- `specview`: A command-line tool for visualizing `.spec` spectrogram files in ASCII art. -- `asset_packer`: A build-time tool for embedding assets into the binary. +- **Procedural Melody**: Implemented a shared library (`src/audio/gen.cc`) for generating note spectrograms at runtime. Supports melody pasting with overlapping frames and spectral post-processing. +- **Spectral Filters**: Implemented runtime spectral effects including noise (grit), lowpass filtering, and comb filtering (phaser/flanger effects). +- **Timing System**: Implemented a beat-based timing system (BPM) used for both audio generation and visual synchronization. ### WebGPU Integration: -- **Strategy**: Uses system-installed `wgpu-native` (e.g., via Homebrew) for the implementation. -- **Surface Creation**: Uses `glfw3webgpu` helper library to abstract platform-specific surface creation from GLFW windows, keeping the codebase clean and cross-platform. -- **Headers**: Uses standard `<webgpu.h>` provided by the system install. -- **Visuals**: Pulsating heptagon synchronized with audio peaks, with automatic aspect ratio correction. +- **Resource Management**: Introduced `GpuBuffer`, `RenderPass`, and `ComputePass` abstractions to group pipeline and bind group resources. +- **Compute Shaders**: Implemented a high-performance particle system (10,000 particles) using compute shaders for physics and audio-reactive updates. +- **Visuals**: Pulsating heptagon and a compute-driven particle field synchronized with audio peaks and global time. -### Coding Style: -- **Standard**: Adopted a consistent coding style enforced by `.clang-format`. -- **Rules**: 2-space indentation, no tabs, 80-column line limit. -- **Headers**: Mandatory 3-line descriptive header at the top of every `.h` and `.cc` file. -- **File Extension**: All C++ source files renamed from `.cpp` to `.cc`. +### WebGPU Integration Fixes: +Several critical issues were resolved to ensure stable WebGPU operation across platforms: +- **Surface Creation (macOS)**: Fixed a `g_surface` assertion failure by adding platform-specific compile definitions (`-DGLFW_EXPOSE_NATIVE_COCOA`) to `CMakeLists.txt`. This allows `glfw3webgpu` to access the native window handles required for surface creation. +- **Texture Usage**: Resolved a validation error (`RENDER_ATTACHMENT` usage missing) by explicitly setting `g_config.usage = WGPUTextureUsage_RenderAttachment` in the surface configuration. +- **Render Pass Validation**: Fixed a "Depth slice provided but view is not 3D" error by ensuring `WGPURenderPassColorAttachment` is correctly initialized, specifically setting `resolveTarget = nullptr` and `depthSlice = WGPU_DEPTH_SLICE_UNDEFINED`. -### Platform & Input: -- **Windowing**: Uses GLFW for cross-platform window management. -- **Input**: Supports 'Esc' and 'Q' for quitting, and 'F' for toggling fullscreen. +### WebGPU Portability Layer: +To maintain a single codebase while supporting different `wgpu-native` versions (Native macOS/Linux headers vs. Windows/MinGW v0.19.4.1), a portability layer was implemented in `src/gpu/gpu.cc`: +- **Header Mapping**: Conditional inclusion of `<webgpu/webgpu.h>` for Windows vs. `<webgpu.h>` for native builds. +- **Type Shims**: Implementation of `WGPUStringView` as a simple `const char*` for older APIs, with `str_view()` and `label_view()` helpers to abstract the transition from raw strings to view structs. +- **API Lifecycle**: + - **Wait Mechanism**: Abstraction of `wgpuInstanceWaitAny` (new) vs. `wgpuInstanceProcessEvents` (old). + - **Request Methods**: Handling of callback signatures for `wgpuInstanceRequestAdapter` and `wgpuAdapterRequestDevice` which changed from struct-based callbacks to direct function pointers. +- **Struct Differences**: + - **Color Attachments**: Conditional removal of the `depthSlice` member in `WGPURenderPassColorAttachment`, which is not present in v0.19. + - **Error Handling**: Abstracted `wgpuDeviceSetUncapturedErrorCallback` via a `set_error_callback` helper to account for its relocation into the device descriptor in newer versions. +- **Surface Creation**: Custom logic in `glfw3webgpu.c` to handle `WGPUSurfaceSourceWindowsHWND` (new) vs. `WGPUSurfaceDescriptorFromWindowsHWND` (old). + +### Coding Style: +- **Standard**: Strictly enforced project-specific rules in `CONTRIBUTING.md`. +- **Cleanup**: Automate removal of trailing whitespaces and addition of missing newlines at EOF across all source files. +- **Constraints**: No `auto`, no C++ style casts (`static_cast`, etc.), mandatory 3-line headers. ### Design Decision: Spectrogram Data Representation @@ -87,22 +100,6 @@ Incoming tasks in no particular order: * Store frequencies logarithmically. * Use `uint16_t` instead of `float` for spectral values. * **Impact:** This aims to achieve better compression while retaining fine frequency resolution relevant to human perception. It will primarily affect the code responsible for saving to and reading from `.spec` files, requiring conversions between the new format and the linear float format used internally by the audio engine. -### Development Workflow: -- **Commit Policy**: Explicit rule to always run the full test suite before preparing any commit, documented in `CONTRIBUTING.md`. -- **Testing**: Comprehensive test suite including `AssetManagerTest`, `SynthEngineTest`, `HammingWindowTest`, and `SpectoolEndToEndTest`. - -### Spectrogram Generation Module -* **Goal:** Introduce programmatic functions to synthesize `.spec` data for creating custom sounds and textures. -* **Core Functionality:** Implemented `NoteParams` struct and `generate_note_spectrogram_data` function. -* **Key Features:** - * Synthesizes notes with configurable `base_freq`, `duration`, `amplitude`, and `delay`. - * Supports basic ADSR-like envelope (Attack). - * Includes vibrato (rate, depth). - * Allows control over harmonic content (`num_harmonics`, `harmonic_amplitude_decay`). - * Adds subtle variations via `pitch_randomness_stddev` and `amplitude_randomness_stddev`. -* **Data Flow:** - 1. `NoteParams` -> `generate_note_time_domain()` (produces time-domain samples using project constants for `SAMPLE_RATE` and `DCT_SIZE`) - 2. Time-domain samples -> `generate_spectral_data_from_time_domain()` (applies window, DCT, produces spectral frames) - 3. Spectral frames -> `save_spectrogram_to_spec_file()` (writes to `.spec` file). -* **Future Work:** Extend envelopes (Sustain, Decay, Release), add more waveform types, implement noise generation, advanced harmonic control, and explore `.spec` file format optimizations. +### Development Workflow: +- **Testing**: Comprehensive test suite including `AssetManagerTest`, `SynthEngineTest`, `HammingWindowTest`, and `SpectoolEndToEndTest`. All tests are verified before committing.
\ No newline at end of file diff --git a/scripts/build_win.sh b/scripts/build_win.sh index 493e322..db95416 100755 --- a/scripts/build_win.sh +++ b/scripts/build_win.sh @@ -31,4 +31,7 @@ else echo "Warning: Could not find MinGW DLLs. You might need them to run the exe." fi +# 4. Crunch the binary +./scripts/crunch_win.sh + echo "Build complete. Output: build_win/demo64k.exe" diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 40be1d2..b1f3f14 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -26,8 +26,12 @@ // Type Shims using WGPUStringView = const char *; -static const char *str_view(const char *str) { return str; } -static const char *label_view(const char *str) { return str; } +static const char *str_view(const char *str) { + return str; +} +static const char *label_view(const char *str) { + return str; +} // Renamed Types/Enums #define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor @@ -48,8 +52,7 @@ static void wgpuInstanceWaitAny(WGPUInstance instance, size_t, void *, } // Uncaptured Error Callback Helper -static void set_error_callback(WGPUDevice device, - WGPUErrorCallback callback) { +static void set_error_callback(WGPUDevice device, WGPUErrorCallback callback) { wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr); } @@ -75,11 +78,11 @@ static WGPUStringView str_view(const char *str) { return {str, strlen(str)}; } -static void set_error_callback(WGPUDevice device, - WGPUErrorCallback callback) { - // Handled in descriptor for new API, mostly. - // But we can also set it here if needed, or define a no-op if descriptor handles it. - // For new API, we set it in WGPUDeviceDescriptor.uncapturedErrorCallbackInfo. +static void set_error_callback(WGPUDevice device, WGPUErrorCallback callback) { + // Handled in descriptor for new API, mostly. + // But we can also set it here if needed, or define a no-op if descriptor + // handles it. For new API, we set it in + // WGPUDeviceDescriptor.uncapturedErrorCallbackInfo. } #endif @@ -109,8 +112,7 @@ struct Particle { // --- Helper Functions --- -GpuBuffer gpu_create_buffer(size_t size, uint32_t usage, - const void *data) { +GpuBuffer gpu_create_buffer(size_t size, uint32_t usage, const void *data) { WGPUBufferDescriptor desc = {}; desc.label = label_view("GpuBuffer"); desc.usage = (WGPUBufferUsage)usage; // Cast for C++ strictness with enums @@ -317,7 +319,6 @@ static void handle_request_device(WGPURequestDeviceStatus status, // ... (Shaders omitted for brevity, they are unchanged) ... - const char *main_shader_wgsl = R"( struct Uniforms { audio_peak : f32, @@ -568,12 +569,11 @@ void gpu_init(GLFWwindow *window) { initial_particles[i].color[3] = 1.0f; } - g_particle_buffer = - gpu_create_buffer(sizeof(Particle) * NUM_PARTICLES, - (WGPUBufferUsage)(WGPUBufferUsage_Storage | - WGPUBufferUsage_CopyDst | - WGPUBufferUsage_Vertex), - initial_particles.data()); + g_particle_buffer = gpu_create_buffer( + sizeof(Particle) * NUM_PARTICLES, + (WGPUBufferUsage)(WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst | + WGPUBufferUsage_Vertex), + initial_particles.data()); // Initialize Particle Compute Pass ResourceBinding compute_bindings[] = { |
