From 796fed50704a4eabb74999e352ab4f59053034e5 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Fri, 2 Jan 2026 01:32:22 +0100 Subject: [PATCH] Some AI shite Signed-off-by: Nikolai Rodionov --- .gitignore | 2 + conanfile.py | 3 +- meson.build | 12 +++-- src/engine/main.cpp | 60 --------------------- src/gui/control_panel.cpp | 10 ---- src/gui/main.cpp | 13 ----- src/main.cpp | 110 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 89 deletions(-) delete mode 100644 src/engine/main.cpp delete mode 100644 src/gui/control_panel.cpp delete mode 100644 src/gui/main.cpp create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore index 277fc18..cef67cc 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,5 @@ compile_commands.json # Conan build dir build/ .cache/ + +venv diff --git a/conanfile.py b/conanfile.py index f93be4b..0eca1ec 100644 --- a/conanfile.py +++ b/conanfile.py @@ -19,10 +19,11 @@ class daw_projectConan(ConanFile): def requirements(self): self.requires("conan-test-lib/0.0.2") self.requires("qt/6.10.1") + self.requires("libsndfile/1.2.2") def layout(self): self.folders.build = "build" - self.folders.generators = "build/scripts" + self.folders.generators = "venv" def generate(self): deps = PkgConfigDeps(self) diff --git a/meson.build b/meson.build index 3dda900..9efdef0 100644 --- a/meson.build +++ b/meson.build @@ -1,13 +1,15 @@ project('daw-exp ', 'cpp') qt_dep = dependency('qt6', modules: ['Core', 'Widgets']) + jack_dep = dependency('jack', required : true) test_dep = dependency('conan-test-lib', required: true) +snd_dep = dependency('sndfile', required: true) -#executable('daw-project', 'src/engine/main.cpp', -# dependencies: [jack_dep, test_dep], -# install: true) +appleframeworks_dep = dependency('appleframeworks', + modules : ['AudioUnit', 'AudioToolbox', 'CoreAudio'] +) -executable('daw-gui', 'src/gui/main.cpp', - dependencies: [qt_dep, test_dep], +executable('daw-gui', 'src/main.cpp', + dependencies: [qt_dep, test_dep, snd_dep, appleframeworks_dep], install: true) diff --git a/src/engine/main.cpp b/src/engine/main.cpp deleted file mode 100644 index a928242..0000000 --- a/src/engine/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// src/main.cpp -#include -#include -#include -#include -static std::atomic g_client{nullptr}; -static float g_phase = 0.0f; -static const float kFreq = 440.0f; - -int process(jack_nframes_t nframes, void* arg) { - jack_port_t* port = static_cast(arg); - float* out = (float*)jack_port_get_buffer(port, nframes); - jack_client_t* client = g_client.load(); - if (!client) return 0; - - jack_nframes_t sr = jack_get_sample_rate(client); - for (jack_nframes_t i = 0; i < nframes; ++i) { - out[i] = std::sinf(g_phase); - g_phase += 2.0f * static_cast(M_PI) * kFreq / static_cast(sr); - if (g_phase > 2.0f * static_cast(M_PI)) g_phase -= 2.0f * static_cast(M_PI); - } - return 0; -} - -int main() { - jack_status_t status; - jack_client_t* client = jack_client_open("cpp_jack_player", JackNullOption, &status); - if (!client) { - std::cerr << "Failed to open JACK client (status=" << status << ")\n"; - return 1; - } - g_client.store(client); - - jack_port_t* outport = jack_port_register(client, "output", JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - if (!outport) { - std::cerr << "Failed to register output port\n"; - jack_client_close(client); - return 1; - } - - if (jack_set_process_callback(client, process, outport) != 0) { - std::cerr << "Failed to set process callback\n"; - jack_client_close(client); - return 1; - } - - if (jack_activate(client) != 0) { - std::cerr << "Failed to activate JACK client\n"; - jack_client_close(client); - return 1; - } - - std::cout << "Client active. Connect " << jack_get_client_name(client) - << ":output to system:playback (e.g. with qjackctl). Press Enter to quit.\n"; - std::cin.get(); - - jack_client_close(client); - return 0; -} diff --git a/src/gui/control_panel.cpp b/src/gui/control_panel.cpp deleted file mode 100644 index 2e20de0..0000000 --- a/src/gui/control_panel.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -#include "qpushbutton.h" -#include -#include - -void add_button() -{ - QPushButton button ("Hello"); - button.show(); -} diff --git a/src/gui/main.cpp b/src/gui/main.cpp deleted file mode 100644 index e402eb6..0000000 --- a/src/gui/main.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include "./control_panel.cpp" -#include - -int main(int argc, char **argv) -{ - conan_test_lib(); - QApplication app (argc, argv); - add_button(); - - return app.exec(); -} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c42d329 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include + +constexpr double SAMPLE_RATE = 44100.0; +constexpr double FREQUENCY = 440.0; // A4 +constexpr double AMPLITUDE = 0.25; + +struct SineState { + double phase = 0.0; +}; + +OSStatus renderCallback( + void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData) +{ + auto* state = static_cast(inRefCon); + double phase = state->phase; + double phaseIncrement = 2.0 * M_PI * FREQUENCY / SAMPLE_RATE; + + for (UInt32 frame = 0; frame < inNumberFrames; ++frame) { + float sample = static_cast(std::sin(phase) * AMPLITUDE); + phase += phaseIncrement; + if (phase >= 2.0 * M_PI) + phase -= 2.0 * M_PI; + + // Write same sample to all channels + for (UInt32 buffer = 0; buffer < ioData->mNumberBuffers; ++buffer) { + float* data = static_cast(ioData->mBuffers[buffer].mData); + data[frame] = sample; + } + } + + state->phase = phase; + return noErr; +} + +int main() { + AudioUnit audioUnit; + SineState state; + + // Describe output unit + AudioComponentDescription desc{}; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + + AudioComponent comp = AudioComponentFindNext(nullptr, &desc); + if (!comp) { + std::cerr << "Failed to find audio component\n"; + return 1; + } + + AudioComponentInstanceNew(comp, &audioUnit); + + // Set stream format + AudioStreamBasicDescription format{}; + format.mSampleRate = SAMPLE_RATE; + format.mFormatID = kAudioFormatLinearPCM; + format.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; + format.mBitsPerChannel = 32; + format.mChannelsPerFrame = 2; + format.mBytesPerFrame = sizeof(float) * format.mChannelsPerFrame; + format.mFramesPerPacket = 1; + format.mBytesPerPacket = format.mBytesPerFrame; + + AudioUnitSetProperty( + audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &format, + sizeof(format) + ); + + // Set render callback + AURenderCallbackStruct callback{}; + callback.inputProc = renderCallback; + callback.inputProcRefCon = &state; + + AudioUnitSetProperty( + audioUnit, + kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Input, + 0, + &callback, + sizeof(callback) + ); + + AudioUnitInitialize(audioUnit); + AudioOutputUnitStart(audioUnit); + + std::cout << "Playing sine wave (Ctrl+C to quit)...\n"; + while (true) { + sleep(1); + } + + AudioOutputUnitStop(audioUnit); + AudioUnitUninitialize(audioUnit); + AudioComponentInstanceDispose(audioUnit); + + return 0; +} +