// 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; }