From 40580179d1d35cc85f4235faa8d59390335ffe89 Mon Sep 17 00:00:00 2001 From: Blitblank Date: Mon, 22 Dec 2025 21:22:45 -0600 Subject: [PATCH] windows checkpoint --- scripts/build.bat | 68 ++++++++++++++++++++++++++++++++++++ src/synth/AudioEngine.cpp | 73 +++++++++++++++++++++++++++++++++++++++ src/synth/AudioEngine.h | 31 +++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 scripts/build.bat create mode 100644 src/synth/AudioEngine.cpp create mode 100644 src/synth/AudioEngine.h diff --git a/scripts/build.bat b/scripts/build.bat new file mode 100644 index 0000000..cf03b6c --- /dev/null +++ b/scripts/build.bat @@ -0,0 +1,68 @@ +@echo off +setlocal + +REM ================================ +REM Configuration +REM ================================ + +set BUILD_DIR=build +set CONFIG=Release + +REM Update these paths if needed +set QT_ROOT=C:\Qt\6.6.1\msvc2022_64 +set RTAUDIO_ROOT=C:\rtaudio + +REM ================================ +REM Environment setup +REM ================================ + +call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" + +set PATH=%QT_ROOT%\bin;%PATH% + +REM ================================ +REM Configure +REM ================================ + +if not exist %BUILD_DIR% ( + mkdir %BUILD_DIR% +) + +cmake -S . -B %BUILD_DIR% ^ + -G Ninja ^ + -DCMAKE_BUILD_TYPE=%CONFIG% ^ + -DCMAKE_PREFIX_PATH=%QT_ROOT% ^ + -DRTAUDIO_ROOT=%RTAUDIO_ROOT% + +if errorlevel 1 goto error + +REM ================================ +REM Build +REM ================================ + +cmake --build %BUILD_DIR% + +if errorlevel 1 goto error + +REM ================================ +REM Deploy Qt + RtAudio +REM ================================ + +cd %BUILD_DIR% + +windeployqt MyQtApp.exe + +copy "%RTAUDIO_ROOT%\bin\rtaudio.dll" . + +echo. +echo Build successful. +goto end + +:error +echo. +echo Build FAILED. +exit /b 1 + +:end +endlocal +pause \ No newline at end of file diff --git a/src/synth/AudioEngine.cpp b/src/synth/AudioEngine.cpp new file mode 100644 index 0000000..d56054e --- /dev/null +++ b/src/synth/AudioEngine.cpp @@ -0,0 +1,73 @@ + +#include "AudioEngine.h" + +#include +#include + +AudioEngine::AudioEngine() { + if(audio_.getDeviceCount() < 1) { + throw std::runtime_error("No audio devices found"); + } +} + +AudioEngine::~AudioEngine() { + stop(); +} + +bool AudioEngine::start() { + + RtAudio::StreamParameters params; + params.deviceId = audio_.getDefaultOutputDevice(); + params.nChannels = 1; + params.firstChannel = 0; + + RtAudio::StreamOptions options; + options.flags = RTAUDIO_MINIMIZE_LATENCY; + + try { + audio_.openStream(¶ms, nullptr, RTAUDIO_FLOAT32, sampleRate_, &bufferFrames_, &AudioEngine::audioCallback, this, &options); + audio_.startStream(); + } catch(RtAudioError& e) { + std::cerr << e.getMessage() << std::endl; + return false; + } + + std::cout << "sample rate: " << sampleRate_ << " buffer frames: " << bufferFrames_ << std::endl; + return true; + +} + +void AudioEngine::stop() { + + if(audio_.isStreamRunning()) audio_.stopStream(); + if(audio_.isStreamOpen()) audio_.closeStream(); +} + +void AudioEngine::setFrequency(float freq) { + targetFreq_.store(freq, std::memory_order_relaxed); +} + +int32_t AudioEngine::audioCallback( void* outputBuffer, void*, uint32_t nFrames, double, RtAudioStreamStatus status, void* userData) { + + if (status) std::cerr << "Stream underflow!" << std::endl; + + return static_cast(userData)->process(static_cast(outputBuffer), nFrames); +} + +int32_t AudioEngine::process(float* out, uint32_t nFrames) { + const float sr = static_cast(sampleRate_); + float target = targetFreq_.load(std::memory_order_relaxed); + float freqStep = (target - currentFreq_) / nFrames; + + for (uint32_t i = 0; i < nFrames; ++i) { + currentFreq_ += freqStep; + + float phaseInc = 2.0f * M_PI * currentFreq_ / sr; + out[i] = std::sin(phase_); + + phase_ += phaseInc; + if (phase_ > 2.0f * M_PI) phase_ -= 2.0f * M_PI; + } + + return 0; +} diff --git a/src/synth/AudioEngine.h b/src/synth/AudioEngine.h new file mode 100644 index 0000000..1c99700 --- /dev/null +++ b/src/synth/AudioEngine.h @@ -0,0 +1,31 @@ + +#pragma once + +#include +#include +#include + +class AudioEngine { + +public: + AudioEngine(); + ~AudioEngine(); + + bool start(); + void stop(); + + void setFrequency(float freq); + +private: + static int32_t audioCallback(void* outputBuffer, void* inputBuffer, uint32_t nFrames, double streamTime, RtAudioStreamStatus status, void* userData); + int32_t process(float* out, uint32_t nFrames); + + RtAudio audio_; + uint32_t sampleRate_ = 44100; + uint32_t bufferFrames_ = 256; + + std::atomic targetFreq_{ 400.0f }; + float currentFreq_ = 440.0f; + float phase_ = 0.0f; + +};