make basic audio engine parameters configurable
This commit is contained in:
@@ -47,7 +47,6 @@ if (-not ($dependencies_found -eq $libraries.Count)) {
|
|||||||
# configure
|
# configure
|
||||||
Write-Host "Configuring metabolus..."
|
Write-Host "Configuring metabolus..."
|
||||||
cmake -S . -B $BUILD_DIR -G "Visual Studio 17 2022" `
|
cmake -S . -B $BUILD_DIR -G "Visual Studio 17 2022" `
|
||||||
-DCMAKE_BUILD_TYPE=Release `
|
|
||||||
-DQt6_ROOT="$QT_ROOT\lib\cmake\Qt6" `
|
-DQt6_ROOT="$QT_ROOT\lib\cmake\Qt6" `
|
||||||
-DRtAudio_ROOT="$RTAUDIO_ROOT" `
|
-DRtAudio_ROOT="$RTAUDIO_ROOT" `
|
||||||
-DRtMidi_ROOT="$RTMIDI_ROOT" `
|
-DRtMidi_ROOT="$RTMIDI_ROOT" `
|
||||||
@@ -56,7 +55,7 @@ cmake -S . -B $BUILD_DIR -G "Visual Studio 17 2022" `
|
|||||||
|
|
||||||
# build
|
# build
|
||||||
Write-Host "Building metabolus..."
|
Write-Host "Building metabolus..."
|
||||||
cmake --build $BUILD_DIR
|
cmake --build $BUILD_DIR --config $CONFIG
|
||||||
|
|
||||||
# TODO: install
|
# TODO: install
|
||||||
|
|
||||||
@@ -64,14 +63,14 @@ cmake --build $BUILD_DIR
|
|||||||
Write-Host "Deploying metabolus..."
|
Write-Host "Deploying metabolus..."
|
||||||
cd $BUILD_DIR
|
cd $BUILD_DIR
|
||||||
|
|
||||||
& "$QT_ROOT\bin\windeployqt6.exe" .\Debug\metabolus.exe
|
& "$QT_ROOT\bin\windeployqt6.exe" .\$CONFIG\metabolus.exe
|
||||||
|
|
||||||
# copy dlls
|
# copy dlls
|
||||||
Copy-Item -Path "$RTAUDIO_ROOT\bin\rtaudio.dll" -Destination .\Debug
|
Copy-Item -Path "$RTAUDIO_ROOT\bin\rtaudio.dll" -Destination .\$CONFIG
|
||||||
Copy-Item -Path "$RTMIDI_ROOT\bin\rtmidi.dll" -Destination .\Debug
|
Copy-Item -Path "$RTMIDI_ROOT\bin\rtmidi.dll" -Destination .\$CONFIG
|
||||||
Copy-Item -Path "$YAMLCPP_ROOT\bin\yaml-cpp.dll" -Destination .\Debug
|
Copy-Item -Path "$YAMLCPP_ROOT\bin\yaml-cpp.dll" -Destination .\$CONFIG
|
||||||
|
|
||||||
# copy configs, but don't overwrite
|
# copy configs, but don't overwrite
|
||||||
Copy-Item -Path "$CONFIG_ROOT" -Destination ".\Debug\" -Recurse -ErrorAction SilentlyContinue
|
Copy-Item -Path "$CONFIG_ROOT" -Destination ".\$CONFIG\" -Recurse -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
cd $PROJECT_ROOT
|
cd $PROJECT_ROOT
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
echo "Installing dependencies ... "
|
echo "Installing dependencies ... "
|
||||||
|
|
||||||
|
# TODO: add a clean (like delete build dirs) script
|
||||||
|
|
||||||
$project_root = $PWD
|
$project_root = $PWD
|
||||||
|
|
||||||
if (-not (Test-Path -Path "$PWD\build\lib")) {
|
if (-not (Test-Path -Path "$PWD\build\lib")) {
|
||||||
@@ -12,21 +14,28 @@ $build_lib_dir = "$PWD\build\lib"
|
|||||||
# rtaudio
|
# rtaudio
|
||||||
mkdir "$build_lib_dir\rtaudio" -Force
|
mkdir "$build_lib_dir\rtaudio" -Force
|
||||||
cd $project_root\lib\rtaudio
|
cd $project_root\lib\rtaudio
|
||||||
cmake -S . -B build -G "Visual Studio 17 2022" -DRTDUIO_API_WASAPI=ON -DRTAUDIO_API_DS=OFF -DRT_AUDIO_API_ASIO=OFF -DRTAUDIO_BUILD_SHARED_LIBS=ON
|
cmake -S . -B build -G "Visual Studio 17 2022" `
|
||||||
|
-DRTDUIO_API_WASAPI=ON `
|
||||||
|
-DRTAUDIO_API_DS=OFF `
|
||||||
|
-DRT_AUDIO_API_ASIO=OFF `
|
||||||
|
-DRTAUDIO_BUILD_SHARED_LIBS=ON
|
||||||
cmake --build build --config Release
|
cmake --build build --config Release
|
||||||
cmake --install build --prefix "$build_lib_dir\rtaudio"
|
cmake --install build --prefix "$build_lib_dir\rtaudio"
|
||||||
|
|
||||||
# rtmidi
|
# rtmidi
|
||||||
mkdir "$build_lib_dir\rtmidi" -Force
|
mkdir "$build_lib_dir\rtmidi" -Force
|
||||||
cd $project_root\lib\rtmidi
|
cd $project_root\lib\rtmidi
|
||||||
cmake -S . -B build -G "Visual Studio 17 2022" -DRT_MIDI_API_WINMM=ON -DRTMIDI_BUILD_SHARED_LIBS=ON
|
cmake -S . -B build -G "Visual Studio 17 2022" `
|
||||||
|
-DRT_MIDI_API_WINMM=ON `
|
||||||
|
-DRTMIDI_BUILD_SHARED_LIBS=ON
|
||||||
cmake --build build --config Release
|
cmake --build build --config Release
|
||||||
cmake --install build --prefix "$build_lib_dir\rtmidi"
|
cmake --install build --prefix "$build_lib_dir\rtmidi"
|
||||||
|
|
||||||
# yaml-cpp
|
# yaml-cpp
|
||||||
mkdir "$build_lib_dir\yaml-cpp" -Force
|
mkdir "$build_lib_dir\yaml-cpp" -Force
|
||||||
cd $project_root\lib\yaml-cpp
|
cd $project_root\lib\yaml-cpp
|
||||||
cmake -S . -B build -G "Visual Studio 17 2022" -DYAML_BUILD_SHARED_LIBS=ON
|
cmake -S . -B build -G "Visual Studio 17 2022" `
|
||||||
|
-DYAML_BUILD_SHARED_LIBS=ON
|
||||||
cmake --build build --config Release
|
cmake --build build --config Release
|
||||||
cmake --install build --prefix "$build_lib_dir\yaml-cpp"
|
cmake --install build --prefix "$build_lib_dir\yaml-cpp"
|
||||||
|
|
||||||
|
|||||||
@@ -11,39 +11,34 @@ namespace fs = std::filesystem;
|
|||||||
|
|
||||||
ConfigInterface::ConfigInterface() {
|
ConfigInterface::ConfigInterface() {
|
||||||
|
|
||||||
std::string audioConfig = configRoot + "/" + filename;
|
//std::cout << "Config constructor" << std::endl;
|
||||||
|
|
||||||
std::cout << "CWD: " << fs::current_path() << std::endl;
|
}
|
||||||
std::cout << "Audio config: " << fs::absolute(audioConfig).string() << std::endl;
|
|
||||||
|
int ConfigInterface::getValue(ConfigFile file, std::string key, int defaultVal) {
|
||||||
// opening the file myself because YAML::LoadFile didn't seem to work on windows
|
|
||||||
std::ifstream file(fs::absolute(audioConfig).string());
|
// assemble filepath
|
||||||
if(file.good()) {
|
std::string filepath = configRoot + "/" + filePaths[static_cast<int>(file)];
|
||||||
std::cout << "File exists" << std::endl;
|
filepath = fs::absolute(filepath).string();
|
||||||
} else {
|
|
||||||
std::cout << "File does not exist" << std::endl;
|
// attempt to open file
|
||||||
}
|
YAML::Node config;
|
||||||
|
try {
|
||||||
//YAML::Node config;
|
YAML::Node config = YAML::LoadFile(filepath);
|
||||||
/*
|
|
||||||
try {
|
// read key if it exists
|
||||||
YAML::Node config = YAML::Load("{sampleRate: 44100}");
|
if(config[key]) {
|
||||||
std::cout << "Loaded config file" << std::endl;
|
return config[key].as<int>(defaultVal);
|
||||||
|
} else {
|
||||||
std::cout << "Type enum: " << static_cast<int>(config.Type()) << std::endl;
|
return -1; // key does not exist
|
||||||
|
}
|
||||||
if(config["sampleRate"]) {
|
|
||||||
//int sampleRate = config["sampleRate"].as<int>();
|
} catch(const std::exception& e) {
|
||||||
//std::cout << sampleRate << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
} else {
|
return -1;
|
||||||
std::cout << "Key does not exist" << std::endl;
|
}
|
||||||
}
|
|
||||||
} catch(const std::exception& e) {
|
// unreachable
|
||||||
std::cerr << e.what() << '\n';
|
return -1;
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
YAML::Node n = YAML::Load("{sampleRate: 44100}");
|
|
||||||
std::cout << n["sampleRate"].as<int>() << "\n";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
enum class ConfigFile {
|
||||||
|
Audio = 0
|
||||||
|
// other files here
|
||||||
|
};
|
||||||
|
|
||||||
|
// might have a config file for specifying paths to other config files instead of this
|
||||||
|
const std::vector<std::string> filePaths = {
|
||||||
|
"audio.yaml"
|
||||||
|
};
|
||||||
|
|
||||||
class ConfigInterface {
|
class ConfigInterface {
|
||||||
|
|
||||||
@@ -10,9 +21,10 @@ public:
|
|||||||
ConfigInterface();
|
ConfigInterface();
|
||||||
~ConfigInterface() = default;
|
~ConfigInterface() = default;
|
||||||
|
|
||||||
|
int getValue(ConfigFile file, std::string key, int defaultVal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const std::string configRoot = "config";
|
const std::string configRoot = "config";
|
||||||
const std::string filename = "audio.yaml";
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,9 +9,7 @@
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// std::cout << "Main()" << std::endl;
|
// std::cout << "Main()" << std::endl;
|
||||||
|
|
||||||
ConfigInterface config = ConfigInterface();
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
MainWindow window; // entry point goes to MainWindow::MainWindow()
|
MainWindow window; // entry point goes to MainWindow::MainWindow()
|
||||||
|
|||||||
@@ -3,14 +3,11 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
AudioEngine::AudioEngine() : synth_(params_) {
|
AudioEngine::AudioEngine(ConfigInterface* config) : synth_(params_), config_(config) {
|
||||||
if(audio_.getDeviceCount() < 1) {
|
if(audio_.getDeviceCount() < 1) {
|
||||||
throw std::runtime_error("No audio devices found");
|
throw std::runtime_error("No audio devices found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get audio configurations
|
|
||||||
synth_.setSampleRate(sampleRate_);
|
|
||||||
|
|
||||||
synth_.setScopeBuffer(&scope_);
|
synth_.setScopeBuffer(&scope_);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,6 +18,13 @@ AudioEngine::~AudioEngine() {
|
|||||||
|
|
||||||
bool AudioEngine::start() {
|
bool AudioEngine::start() {
|
||||||
|
|
||||||
|
// get config values
|
||||||
|
sampleRate_ = config_->getValue(ConfigFile::Audio, "sampleRate", sampleRate_);
|
||||||
|
bufferFrames_ = config_->getValue(ConfigFile::Audio, "bufferSize", bufferFrames_);
|
||||||
|
channels_ = config_->getValue(ConfigFile::Audio, "channels", channels_);
|
||||||
|
|
||||||
|
synth_.setSampleRate(sampleRate_);
|
||||||
|
|
||||||
// initialize the audio engine
|
// initialize the audio engine
|
||||||
RtAudio::StreamParameters params;
|
RtAudio::StreamParameters params;
|
||||||
params.deviceId = audio_.getDefaultOutputDevice();
|
params.deviceId = audio_.getDefaultOutputDevice();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Synth.h"
|
#include "Synth.h"
|
||||||
#include "../KeyboardController.h"
|
#include "../KeyboardController.h"
|
||||||
|
#include "../ConfigInterface.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define AUDIO_API RtAudio::WINDOWS_WASAPI
|
#define AUDIO_API RtAudio::WINDOWS_WASAPI
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
class AudioEngine {
|
class AudioEngine {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioEngine();
|
AudioEngine(ConfigInterface* config);
|
||||||
~AudioEngine();
|
~AudioEngine();
|
||||||
|
|
||||||
// starts the audio stream. returns true on success and false on failure
|
// starts the audio stream. returns true on success and false on failure
|
||||||
@@ -43,6 +44,7 @@ private:
|
|||||||
NoteQueue noteQueue_; // stores note events for passing between threads
|
NoteQueue noteQueue_; // stores note events for passing between threads
|
||||||
Synth synth_; // generates audio
|
Synth synth_; // generates audio
|
||||||
ScopeBuffer scope_ { 1024 }; // stores audio samples for visualization
|
ScopeBuffer scope_ { 1024 }; // stores audio samples for visualization
|
||||||
|
ConfigInterface* config_; // access to config files
|
||||||
|
|
||||||
RtAudio audio_{AUDIO_API}; // audio device
|
RtAudio audio_{AUDIO_API}; // audio device
|
||||||
// TODO: id like a yml config file or something for these
|
// TODO: id like a yml config file or something for these
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ void ScopeBuffer::push(float sample) {
|
|||||||
buffer_[w % buffer_.size()] = sample;
|
buffer_[w % buffer_.size()] = sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: needs a mutex to prevent flickering
|
// TODO: needs a mutex/spinlock to prevent flickering
|
||||||
// outputs value from the scope buffer, called by the scope widget
|
// outputs value from the scope buffer, called by the scope widget
|
||||||
void ScopeBuffer::read(std::vector<float>& out) const {
|
void ScopeBuffer::read(std::vector<float>& out) const {
|
||||||
|
|
||||||
while(!spinLock_) { int x = 1 + 1; }
|
// yeah this didn't work, maybe it needs to be atomic or something
|
||||||
|
//while(!spinLock_) { int x = 1 + 1; }
|
||||||
|
|
||||||
size_t w = writeIndex_.load(std::memory_order_relaxed);
|
size_t w = writeIndex_.load(std::memory_order_relaxed);
|
||||||
for (size_t i = 0; i < out.size(); i++) {
|
for (size_t i = 0; i < out.size(); i++) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui_(new Ui::MainWindow),
|
ui_(new Ui::MainWindow),
|
||||||
audio_(new AudioEngine()),
|
audio_(new AudioEngine(&config_)),
|
||||||
keyboard_(audio_->noteQueue()),
|
keyboard_(audio_->noteQueue()),
|
||||||
midi_(audio_->noteQueue()) {
|
midi_(audio_->noteQueue()) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "../synth/AudioEngine.h"
|
#include "../synth/AudioEngine.h"
|
||||||
#include "../MidiController.h"
|
#include "../MidiController.h"
|
||||||
|
#include "../ConfigInterface.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
@@ -32,5 +33,6 @@ private:
|
|||||||
AudioEngine* audio_ = nullptr;
|
AudioEngine* audio_ = nullptr;
|
||||||
KeyboardController keyboard_;
|
KeyboardController keyboard_;
|
||||||
MidiController midi_;
|
MidiController midi_;
|
||||||
|
ConfigInterface config_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user