c ++ Jackaudio无法获得立体声

时间:2015-04-20 12:36:26

标签: c++ c audio

我在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);
}

2 个答案:

答案 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有正确的预感 - 您的代码没有任何问题,但是当您测试程序时,系统上的端口映射有问题(即端口如何映射到物理端口上你的声卡)。修复它的方法是在您的应用程序之外:使用一些混音器或补丁托架样式应用程序正确路由您的程序的流。不是你的(代码)错误,你的程序运行正常并按照你的意图行事。