From 5a97ea76d5892ad298341f9998d2c081fb319daf Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 17 Feb 2026 09:42:06 -0500 Subject: [PATCH 1/2] add windows build script --- lightningbeam-ui/build-windows.bat | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 lightningbeam-ui/build-windows.bat diff --git a/lightningbeam-ui/build-windows.bat b/lightningbeam-ui/build-windows.bat new file mode 100644 index 0000000..7ee3767 --- /dev/null +++ b/lightningbeam-ui/build-windows.bat @@ -0,0 +1,29 @@ +@echo off +REM Build script for Windows +REM Requires: FFmpeg 8.0.0 dev files in C:\ffmpeg, LLVM installed + +REM FFmpeg location (headers + libs + DLLs) +if not defined FFMPEG_DIR set FFMPEG_DIR=C:\ffmpeg + +REM LLVM/libclang for bindgen (ffmpeg-sys-next) +if not defined LIBCLANG_PATH set LIBCLANG_PATH=C:\Program Files\LLVM\bin + +REM Validate prerequisites +if not exist "%FFMPEG_DIR%\include\libavcodec\avcodec.h" ( + echo ERROR: FFmpeg dev files not found at %FFMPEG_DIR% + echo Download FFmpeg 8.0.0 shared+dev from https://github.com/GyanD/codexffmpeg/releases + echo and extract to %FFMPEG_DIR% + exit /b 1 +) + +if not exist "%LIBCLANG_PATH%\libclang.dll" ( + echo ERROR: LLVM/libclang not found at %LIBCLANG_PATH% + echo Install with: winget install LLVM.LLVM + exit /b 1 +) + +echo Building Lightningbeam Editor... +echo FFMPEG_DIR=%FFMPEG_DIR% +echo LIBCLANG_PATH=%LIBCLANG_PATH% + +cargo build --package lightningbeam-editor %* From 9935c2f3bd70c628182cf1795dd719fbb54e2578 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 17 Feb 2026 09:44:24 -0500 Subject: [PATCH 2/2] resample recorded audio if it has a different sample rate (fix for wsapi persnicketiness) --- daw-backend/src/lib.rs | 53 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/daw-backend/src/lib.rs b/daw-backend/src/lib.rs index bb7c664..a8bbcd3 100644 --- a/daw-backend/src/lib.rs +++ b/daw-backend/src/lib.rs @@ -155,7 +155,7 @@ impl AudioSystem { } }; - // Get input config - use the input device's own default config + // Get input config using the device's default (most compatible) let input_config = match input_device.default_input_config() { Ok(config) => { let cfg: cpal::StreamConfig = config.into(); @@ -165,7 +165,6 @@ impl AudioSystem { eprintln!("Warning: Could not get input config: {}, recording will be disabled", e); output_stream.play().map_err(|e| e.to_string())?; - // Spawn emitter thread if provided if let Some(emitter) = event_emitter { Self::spawn_emitter_thread(event_rx, emitter); } @@ -180,13 +179,57 @@ impl AudioSystem { } }; - // Build input stream that feeds into the ringbuffer + let input_sample_rate = input_config.sample_rate; + let input_channels = input_config.channels as u32; + let output_sample_rate = sample_rate; + let output_channels = channels; + let needs_resample = input_sample_rate != output_sample_rate || input_channels != output_channels; + + if needs_resample { + eprintln!("[AUDIO] Input device: {}Hz {}ch -> resampling to {}Hz {}ch", + input_sample_rate, input_channels, output_sample_rate, output_channels); + } + + // Build input stream with resampling if needed let input_stream = match input_device .build_input_stream( &input_config, move |data: &[f32], _: &cpal::InputCallbackInfo| { - for &sample in data { - let _ = input_tx.push(sample); + if !needs_resample { + for &sample in data { + let _ = input_tx.push(sample); + } + } else { + // Resample: linear interpolation from input rate to output rate + let in_ch = input_channels as usize; + let out_ch = output_channels as usize; + let ratio = output_sample_rate as f64 / input_sample_rate as f64; + let in_frames = data.len() / in_ch; + let out_frames = (in_frames as f64 * ratio) as usize; + + for i in 0..out_frames { + let src_pos = i as f64 / ratio; + let src_idx = src_pos as usize; + let frac = (src_pos - src_idx as f64) as f32; + + for ch in 0..out_ch { + // Map output channel to input channel + let in_ch_idx = ch.min(in_ch - 1); + + let s0 = if src_idx < in_frames { + data[src_idx * in_ch + in_ch_idx] + } else { + 0.0 + }; + let s1 = if src_idx + 1 < in_frames { + data[(src_idx + 1) * in_ch + in_ch_idx] + } else { + s0 + }; + + let _ = input_tx.push(s0 + frac * (s1 - s0)); + } + } } }, |err| eprintln!("Input stream error: {}", err),