Files
sonobulus/src/synth/AudioEngine.cpp
2026-06-12 23:13:18 -05:00

94 lines
2.7 KiB
C++

#include "AudioEngine.hpp"
#include <iostream>
#include <cmath>
#include <numbers>
#include <string>
AudioEngine::AudioEngine(ConfigService* config, LoggerService* logger, Synth* synth) : config_(config), logger_(logger), synth_(synth) {
if(audioDevice_.getDeviceCount() < 1) {
std::cout << "No audio devices found" << std::endl;
}
if(logger_ == nullptr) std::cout << "err: logger nullptr" << std::endl;
}
AudioEngine::~AudioEngine() {
(void)stop();
}
bool AudioEngine::start() {
// initialize the audio engine
RtAudio::StreamParameters params;
params.deviceId = audioDevice_.getDefaultOutputDevice();
params.nChannels = channels_; // we're doing two duplicate channels for pseudo-mono
params.firstChannel = 0;
RtAudio::StreamOptions options;
options.flags = RTAUDIO_MINIMIZE_LATENCY;
RtAudioErrorType status = audioDevice_.openStream(&params, nullptr, RTAUDIO_FLOAT32, sampleRate_, &bufferFrames_, &AudioEngine::audioCallback, this, &options);
if(status != RTAUDIO_NO_ERROR) {
std::cout << "Error opening RtAudio stream" << std::endl;
return false;
}
status = audioDevice_.startStream();
if(status != RTAUDIO_NO_ERROR) {
std::cout << "Error starting RtAudio stream" << std::endl;
return false;
}
// sanity check
std::string msg = "sample rate: " + std::to_string(sampleRate_) + ", buffer frames: " + std::to_string(bufferFrames_);
logger_->log("AudioEngine", LogFlag::Info, msg);
return true;
}
bool AudioEngine::stop() {
if(audioDevice_.isStreamRunning()) audioDevice_.stopStream();
if(audioDevice_.isStreamOpen()) audioDevice_.closeStream();
return true;
}
int32_t AudioEngine::audioCallback(void* outputBuffer, void* inputBuffer, uint32_t nFrames, double, RtAudioStreamStatus status, void* userData) {
// error if the callback is late
if(status) static_cast<AudioEngine*>(userData)->logger_->log("AudioEngine", LogFlag::Warning, "Audio buffer underflow");
return static_cast<AudioEngine*>(userData)->process(static_cast<float*>(outputBuffer), static_cast<size_t>(nFrames));
}
int32_t AudioEngine::process(float* out, size_t nFrames) {
synth_->process(out, nFrames);
// const float twoPi = 2.0f*std::numbers::pi_v<float>;
// float phaseIncrement = twoPi * freq_ / sampleRate_;
// for(size_t i = 0; i < nFrames; i++) {
// // simulate a sine wave
// phase_ += phaseIncrement;
// if(phase_ > twoPi) {
// phase_ -= twoPi;
// }
// float outSample = std::sin(phase_) / 4.0f * noteOn_;
// out[2*i] = outSample;
// out[2*i+1] = outSample;
// }
return 0;
}