我在Windows 8.1上尝试使用c ++的JackAudio,它可以工作。
我使用的是一个可以在git上找到的简单客户端代码。这段代码应该向一个听到的低音信号和向另一个的高音信号发送,但对我来说,它发送两个信号都听到。
我不知道有什么问题,因为两个人都已注册,并且都可以访问正确的发言人。
/** @file simple_client.c
*
* @brief This simple client demonstrates the basic features of JACK
* as they would be used by many applications.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <jack/jack.h>
jack_port_t *output_port1, *output_port2;
jack_client_t *client;
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
paTestData;
static void signal_handler(int sig)
{
jack_client_close(client);
fprintf(stderr, "signal received, exiting ...\n");
exit(0);
}
/**
* The process callback for this JACK application is called in a
* special realtime thread once for each audio cycle.
*
* This client follows a simple rule: when the JACK transport is
* running, copy the input port to the output. When it stops, exit.
*/
int
process(jack_nframes_t nframes, void *arg)
{
jack_default_audio_sample_t *out1, *out2;
paTestData *data = (paTestData*)arg;
int i;
out1 = (jack_default_audio_sample_t*)jack_port_get_buffer(output_port1, nframes);
out2 = (jack_default_audio_sample_t*)jack_port_get_buffer(output_port2, nframes);
for (i = 0; i<nframes; i++)
{
out1[i] = data->sine[data->left_phase]; // left
out2[i] = data->sine[data->right_phase]; // right
data->left_phase += 1;
if (data->left_phase >= TABLE_SIZE) data->left_phase -= TABLE_SIZE;
data->right_phase += 10; // higher pitch so we can distinguish left and right.
if (data->right_phase >= TABLE_SIZE) data->right_phase -= TABLE_SIZE;
}
return 0;
}
/**
* JACK calls this shutdown_callback if the server ever shuts down or
* decides to disconnect the client.
*/
void
jack_shutdown(void *arg)
{
exit(1);
}
int
main(int argc, char *argv[])
{
const char **ports;
const char *client_name;
const char *server_name = NULL;
jack_options_t options = JackNullOption;
jack_status_t status;
paTestData data;
int i;
/*if (argc >= 2) { // client name specified?
client_name = argv[1];
if (argc >= 3) { // server name specified?
server_name = argv[2];
int my_option = JackNullOption | JackServerName;
options = (jack_options_t)my_option;
}
}
else { // use basename of argv[0]
client_name = strrchr(argv[0], '/');
if (client_name == 0) {
client_name = argv[0];
}
else {
client_name++;
}
}*/
client_name = "mytest";
for (i = 0; i<TABLE_SIZE; i++)
{
data.sine[i] = 0.2 * (float)sin(((double)i / (double)TABLE_SIZE) * M_PI * 2.);
}
data.left_phase = data.right_phase = 0;
// open a client connection to the JACK server
client = jack_client_open(client_name, options, &status, server_name);
if (client == NULL) {
fprintf(stderr, "jack_client_open() failed, "
"status = 0x%2.0x\n", status);
if (status & JackServerFailed) {
fprintf(stderr, "Unable to connect to JACK server\n");
}
exit(1);
}
if (status & JackServerStarted) {
fprintf(stderr, "JACK server started\n");
}
if (status & JackNameNotUnique) {
client_name = jack_get_client_name(client);
fprintf(stderr, "unique name `%s' assigned\n", client_name);
}
// tell the JACK server to call `process()' whenever
//there is work to be done.
jack_set_process_callback(client, process, &data);
// tell the JACK server to call `jack_shutdown()' if
//it ever shuts down, either entirely, or if it
//just decides to stop calling us.
jack_on_shutdown(client, jack_shutdown, 0);
// create two ports
output_port1 = jack_port_register(client, "output1",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
output_port2 = jack_port_register(client, "output2",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if ((output_port1 == NULL) || (output_port2 == NULL)) {
fprintf(stderr, "no more JACK ports available\n");
exit(1);
}
//Tell the JACK server that we are ready to roll. Our
// process() callback will start running now.
if (jack_activate(client)) {
fprintf(stderr, "cannot activate client");
exit(1);
}
// Connect the ports. You can't do this before the client is
// activated, because we can't make connections to clients
// that aren't running. Note the confusing (but necessary)
// orientation of the driver backend ports: playback ports are
// "input" to the backend, and capture ports are "output" from
// it.
ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical | JackPortIsInput);
if (ports == NULL) {
fprintf(stderr, "no physical playback ports\n");
exit(1);
}
if (jack_connect(client, jack_port_name(output_port1), ports[0])) {
fprintf(stderr, "cannot connect output ports\n");
}
if (jack_connect(client, jack_port_name(output_port2), ports[1])) {
fprintf(stderr, "cannot connect output ports\n");
}
jack_free(ports);
// install a signal handler to properly quits jack client
#ifdef WIN32
signal(SIGINT, signal_handler);
signal(SIGABRT, signal_handler);
signal(SIGTERM, signal_handler);
#else
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGINT, signal_handler);
#endif
// keep running until the Ctrl+C
while (1) {
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
jack_client_close(client);
exit(0);
}
答案 0 :(得分:1)
你有没有想过这个?我自己编码和配置杰克是一个很新的但我的预感是,问题不在代码中,而是它是混音器问题。我怀疑那里设置的地方已经将插孔服务器置于单声道模式中,这意味着所有输出流都被覆盖(是拼写检查器,multed是音频工程界的一个词:))所有物理音频输出。所以...流1将连接到左右物理输出,流2也将连接到物理左右输出。
没有任何地方可以说流1转到左输出而流2转到右边......事实上,如果你正在运行SDDS配置,第一个流可能是左输出,第二个可能是左中心...你不会到达正确的通道,直到你到达第5个流(第2,第3和第4个分别位于中心,中心和右中心)。
同样,这只是猜测,但请检查是否有混音器或补丁托架&#34;平台上的样式应用程序,允许您将流路由到物理输出。与此同时,我会在我的系统(Debian unstable / w experimental 4.3 kernel)上发布这段代码,看看会发生什么。
干杯,乔
答案 1 :(得分:1)
对原始海报的问题:您是否反对将此示例包含在JackD示例存储库(https://github.com/jackaudio/example-clients)中?我觉得它是如何使用JackD API的音频流部分的一个很好的例子。它可能需要一些小的重写作为通用平台C程序;它将与JackD示例repo(GPL 2)中的其他示例处于相同的许可下。我已经发送邮件给JackD开发人员的名单(jack-devel@lists.jackaudio.org)询问他们的想法。
无论如何 - shewhorn有正确的预感 - 您的代码没有任何问题,但是当您测试程序时,系统上的端口映射有问题(即端口如何映射到物理端口上你的声卡)。修复它的方法是在您的应用程序之外:使用一些混音器或补丁托架样式应用程序正确路由您的程序的流。不是你的(代码)错误,你的程序运行正常并按照你的意图行事。