62 lines
1.9 KiB
C++
62 lines
1.9 KiB
C++
// 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;
|
|
}
|