rtaudio hello world
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <QQmlContext>
|
||||
|
||||
#include "TimerComponent.hpp"
|
||||
#include "synth/AudioEngine.hpp"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
@@ -27,6 +28,10 @@ int main(int argc, char* argv[]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// audio synthesizer doohickey
|
||||
AudioEngine audioEngine = AudioEngine();
|
||||
audioEngine.start();
|
||||
|
||||
// execute app
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -1,2 +1,85 @@
|
||||
|
||||
#include "AudioEngine.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
|
||||
AudioEngine::AudioEngine() {
|
||||
|
||||
if(audioDevice_.getDeviceCount() < 1) {
|
||||
std::cout << "No audio devices found" << 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(¶ms, 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::cout << "sample rate: " << sampleRate_ << " buffer frames: " << bufferFrames_ << std::endl;
|
||||
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) std::cout << "stream underflow" << std::endl;
|
||||
|
||||
return static_cast<AudioEngine*>(userData)->process(static_cast<float*>(outputBuffer), static_cast<size_t>(nFrames));
|
||||
|
||||
}
|
||||
|
||||
int32_t AudioEngine::process(float* out, size_t nFrames) {
|
||||
|
||||
for(size_t i = 0; i < nFrames; i++) {
|
||||
|
||||
// simulate a sine wave
|
||||
phase_ += 0.04f;
|
||||
const float twoPi = 2.0f*std::numbers::pi_v<float>;
|
||||
if(phase_ > twoPi) {
|
||||
phase_ -= twoPi;
|
||||
}
|
||||
float outSample = std::sin(phase_) / 4.0f;
|
||||
|
||||
out[2*i] = outSample;
|
||||
out[2*i+1] = outSample;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,39 @@
|
||||
|
||||
// The audio engine handles the RtAudio implementation of outputing samples to audio. the audio callback fills a buffer of audio samples and submits it for playback
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <RtAudio.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define AUDIO_API RtAudio::WINDOWS_WASAPI
|
||||
#else
|
||||
#define AUDIO_API RtAudio::LINUX_ALSA
|
||||
#endif
|
||||
|
||||
class AudioEngine {
|
||||
|
||||
public:
|
||||
|
||||
AudioEngine();
|
||||
~AudioEngine();
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
private:
|
||||
|
||||
static int32_t audioCallback(void* outputBuffer, void* inputBuffer, uint32_t nFrames, double streamtime, RtAudioStreamStatus status, void* userData);
|
||||
|
||||
int32_t process(float* out, size_t nFrames);
|
||||
|
||||
RtAudio audioDevice_ { AUDIO_API };
|
||||
|
||||
// TODO: make these configurable
|
||||
uint32_t sampleRate_ = 44100;
|
||||
uint32_t bufferFrames_ = 512;
|
||||
uint32_t channels_ = 2;
|
||||
|
||||
float phase_ = 0.0f;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user