Init branch #1

Open
allanger wants to merge 6 commits from init-something into main
7 changed files with 121 additions and 89 deletions
Showing only changes of commit 796fed5070 - Show all commits

2
.gitignore vendored
View File

@@ -91,3 +91,5 @@ compile_commands.json
# Conan build dir
build/
.cache/
venv

View File

@@ -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)

View File

@@ -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)

View File

@@ -1,60 +0,0 @@
// src/main.cpp
#include <jack/jack.h>
#include <cmath>
#include <iostream>
#include <atomic>
static std::atomic<jack_client_t*> 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<jack_port_t*>(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<float>(M_PI) * kFreq / static_cast<float>(sr);
if (g_phase > 2.0f * static_cast<float>(M_PI)) g_phase -= 2.0f * static_cast<float>(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;
}

View File

@@ -1,10 +0,0 @@
#include "qpushbutton.h"
#include <QApplication>
#include <QPushButton>
void add_button()
{
QPushButton button ("Hello");
button.show();
}

View File

@@ -1,13 +0,0 @@
#include <QApplication>
#include <QPushButton>
#include "./control_panel.cpp"
#include <conan-test-lib.h>
int main(int argc, char **argv)
{
conan_test_lib();
QApplication app (argc, argv);
add_button();
return app.exec();
}

110
src/main.cpp Normal file
View File

@@ -0,0 +1,110 @@
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#include <cmath>
#include <iostream>
#include <unistd.h>
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<SineState*>(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<float>(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<float*>(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;
}