From f4d855b36bbc525063308d8d4615d2407d2b5aed Mon Sep 17 00:00:00 2001 From: homeburger Date: Sun, 14 Jun 2026 15:34:51 -0500 Subject: [PATCH] sync --- config/sonobulus.cfg | 2 +- src/main.cpp | 6 +++--- src/synth/AudioEngine.cpp | 9 +++------ src/synth/Instrument.cpp | 10 ++++++---- src/synth/Instrument.hpp | 4 ++++ src/synth/MidiController.cpp | 22 ++++++++++++++-------- src/synth/NoteQueue.cpp | 9 +++++++++ src/synth/NoteQueue.hpp | 11 +++++++++-- src/synth/Scope.cpp | 3 ++- src/synth/Scope.hpp | 8 +++++++- 10 files changed, 58 insertions(+), 26 deletions(-) diff --git a/config/sonobulus.cfg b/config/sonobulus.cfg index 7cdcc76..bf0c026 100644 --- a/config/sonobulus.cfg +++ b/config/sonobulus.cfg @@ -10,7 +10,7 @@ Logger = ( "Error" ); - ShowTime = true; + ShowTime = false; ShowSourceTrace = false; CoutEnabled = true; diff --git a/src/main.cpp b/src/main.cpp index c680fcc..5b5d679 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,8 +22,8 @@ int main(int argc, char* argv[]) { // create app objects ConfigService config = ConfigService("config/sonobulus.cfg"); LoggerService logger = LoggerService(&config, "Engine"); - NoteQueue queue = NoteQueue(); - ScopeBuffer scopeBuffer = ScopeBuffer(512); + NoteQueue queue = NoteQueue(&config, &logger); + ScopeBuffer scopeBuffer = ScopeBuffer(&config, &logger, 2048); KeyboardController keyboard(&config, &logger, &queue); MidiController midi(&config, &logger, &queue); Synth synth(&config, &logger, &scopeBuffer, &queue); @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) { engine.load(QUrl::fromLocalFile("ui/Main.qml")); // ugh if(engine.rootObjects().isEmpty()) { - std::cout << "engine is empty" << std::endl; + logger.log("Main", LogFlag::Error, "Engine is empty."); return -1; } diff --git a/src/synth/AudioEngine.cpp b/src/synth/AudioEngine.cpp index 9e55e71..512ff85 100644 --- a/src/synth/AudioEngine.cpp +++ b/src/synth/AudioEngine.cpp @@ -9,11 +9,8 @@ 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; + logger_->log("Audio", LogFlag::Error, "No audio devices found."); } - - if(logger_ == nullptr) std::cout << "err: logger nullptr" << std::endl; - } AudioEngine::~AudioEngine() { @@ -33,13 +30,13 @@ bool AudioEngine::start() { 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; + logger_->log("Audio", LogFlag::Error, "Error opening RtAudio stream."); return false; } status = audioDevice_.startStream(); if(status != RTAUDIO_NO_ERROR) { - std::cout << "Error starting RtAudio stream" << std::endl; + logger_->log("Audio", LogFlag::Error, "Error starting RtAudio stream."); return false; } diff --git a/src/synth/Instrument.cpp b/src/synth/Instrument.cpp index b0700b6..d8b7cb4 100644 --- a/src/synth/Instrument.cpp +++ b/src/synth/Instrument.cpp @@ -30,17 +30,19 @@ float Instrument::process(bool& scopeTrigger) { if(active_ && envelope_ < 1.0f) envelope_ += 0.01f; if(!active_ && envelope_ > 0.0f) envelope_ -= 0.0004f; + if(!isActive()) return 0.0f; + phase_ += phaseIncrement_; if(phase_ > 2.0f * pi) { phase_ -= 2.0f * pi; scopeTrigger = true; } - if(!isActive()) return 0.0f; - // float sample = sin(phase_); - float sample = phase_ / pi - 1.0f; // saw + targetSample = phase_ / pi - 1.0f; // saw - return sample * envelope_; + currentSample = (1.0f - responsiveness_) * currentSample + responsiveness_ * targetSample; + + return currentSample * envelope_; } diff --git a/src/synth/Instrument.hpp b/src/synth/Instrument.hpp index 7ccc6a7..72249e3 100644 --- a/src/synth/Instrument.hpp +++ b/src/synth/Instrument.hpp @@ -34,4 +34,8 @@ private: float phaseIncrement_ = 0.0f; float envelope_ = 0.0f; + float targetSample = 0.0f; + float currentSample = 0.0f; + static constexpr float responsiveness_ = 0.1f; + }; diff --git a/src/synth/MidiController.cpp b/src/synth/MidiController.cpp index b00ace8..fcc5481 100644 --- a/src/synth/MidiController.cpp +++ b/src/synth/MidiController.cpp @@ -14,7 +14,8 @@ MidiController::MidiController(ConfigService* config, LoggerService* logger, Not #endif midiIn_->ignoreTypes(false, false, false); } catch (RtMidiError& e) { - std::cout << "RtMidi init failed: " << e.getMessage() << std::endl; + std::string msg = "RtMidi init failed: " + e.getMessage(); + logger_->log("MIDI", LogFlag::Warning, msg); } openDefaultPort(); @@ -25,18 +26,21 @@ MidiController::~MidiController() { } // open the first for thats successful +// we could also add an option in the config for a preferred port name bool MidiController::openDefaultPort() { if (!midiIn_) return false; if (midiIn_->getPortCount() == 0) { - std::cout << "No MIDI input ports available" << std::endl; + logger_->log("MIDI", LogFlag::Warning, "No MIDI input ports available."); return false; } + // TODO: the ui will eventually need this class to expose the available midi ports so they can be chosen dynamically uint32_t portCount = midiIn_->getPortCount(); - std::cout << "Available MidiIn ports: " << portCount << std::endl; + std::string msg = "Available MidiIn ports: " + std::to_string(portCount); + logger_->log("MIDI", LogFlag::Info, msg); for (int i = 0; i < portCount; i++) { - std::cout << "#" << i << " : " << midiIn_->getPortName(i) << std::endl; - + msg = "\t#" + std::to_string(i) + " : " + midiIn_->getPortName(i); + logger_->log("MIDI", LogFlag::Info, msg); if(openPort(i)) return true; } @@ -49,11 +53,13 @@ bool MidiController::openPort(unsigned int index) { try { midiIn_->openPort(index); midiIn_->setCallback(&MidiController::midiCallback, this); - std::cout << "Opened MIDI port: " << midiIn_->getPortName(index) << std::endl; + + std::string msg = "Opened MIDI port: " + midiIn_->getPortName(index); + logger_->log("MIDI", LogFlag::Info, msg); return true; } catch (RtMidiError& e) { - std::cout << "Midi Port error" << std::endl; - std::cerr << e.getMessage() << std::endl; + std::string msg = "Midi Port error: " + e.getMessage(); + logger_->log("MIDI", LogFlag::Error, msg); return false; } } diff --git a/src/synth/NoteQueue.cpp b/src/synth/NoteQueue.cpp index d01d701..dc1cd5e 100644 --- a/src/synth/NoteQueue.cpp +++ b/src/synth/NoteQueue.cpp @@ -2,6 +2,15 @@ #include "NoteQueue.hpp" #include +NoteQueue::NoteQueue() { + +} + +NoteQueue::NoteQueue(ConfigService* config, LoggerService* logger) : + config_(config), logger_(logger) { + +} + // add event to noteQueue, called by MidiController or keyboardController bool NoteQueue::push(const NoteEvent& event) { size_t head = head_.load(std::memory_order_relaxed); diff --git a/src/synth/NoteQueue.hpp b/src/synth/NoteQueue.hpp index 519ea97..577dbc5 100644 --- a/src/synth/NoteQueue.hpp +++ b/src/synth/NoteQueue.hpp @@ -7,6 +7,9 @@ #include #include +#include "ConfigService.hpp" +#include "LoggerService.hpp" + enum NoteEventType { NoteOn = 0, NoteOff @@ -22,7 +25,8 @@ struct NoteEvent { class NoteQueue { public: - NoteQueue() = default; + NoteQueue(); + NoteQueue(ConfigService* config, LoggerService* logger); ~NoteQueue() = default; bool push(const NoteEvent& event); @@ -30,7 +34,10 @@ public: private: - static constexpr size_t SYNTH_NOTE_QUEUE_SIZE = 128; + ConfigService* config_; + LoggerService* logger_; + + static constexpr size_t SYNTH_NOTE_QUEUE_SIZE = 128; // TODO: config std::array buffer_; std::atomic head_{ 0 }; diff --git a/src/synth/Scope.cpp b/src/synth/Scope.cpp index 49da767..28b2d05 100644 --- a/src/synth/Scope.cpp +++ b/src/synth/Scope.cpp @@ -7,7 +7,8 @@ ScopeBuffer::ScopeBuffer(QObject *parent) : QObject(parent) { } -ScopeBuffer::ScopeBuffer(size_t size) : buffer_(size) { +ScopeBuffer::ScopeBuffer(ConfigService* config, LoggerService* logger, size_t size) : + config_(config), logger_(logger), buffer_(size) { } diff --git a/src/synth/Scope.hpp b/src/synth/Scope.hpp index f3b8826..d012ea7 100644 --- a/src/synth/Scope.hpp +++ b/src/synth/Scope.hpp @@ -8,6 +8,9 @@ #include #include +#include "ConfigService.hpp" +#include "LoggerService.hpp" + class ScopeBuffer : public QObject { Q_OBJECT // needed to attach to a qml component @@ -15,7 +18,7 @@ class ScopeBuffer : public QObject { public: explicit ScopeBuffer(QObject* parent = nullptr); - ScopeBuffer(size_t size); + ScopeBuffer(ConfigService* config, LoggerService* logger, size_t size); ~ScopeBuffer() = default; void push(float sample); @@ -31,6 +34,9 @@ public: private: + ConfigService* config_; + LoggerService* logger_; + std::vector buffer_; std::atomic writeIndex_{0};