From 8597f39bdd429490a36dd480a91cb30944f4d131 Mon Sep 17 00:00:00 2001 From: Martin Piatka <445597@mail.muni.cz> Date: Wed, 21 Aug 2019 13:28:47 +0200 Subject: [PATCH] Jack: report ports in --capabilities --- src/audio/capture/jack.c | 50 +++--------------- src/audio/playback/jack.c | 51 +++--------------- src/jack_common.h | 107 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 85 deletions(-) create mode 100644 src/jack_common.h diff --git a/src/audio/capture/jack.c b/src/audio/capture/jack.c index ff847dec3..70477e612 100644 --- a/src/audio/capture/jack.c +++ b/src/audio/capture/jack.c @@ -59,6 +59,7 @@ #include "audio/utils.h" #include "lib_common.h" #include "utils/ring_buffer.h" +#include "jack_common.h" #include #include #include @@ -110,20 +111,14 @@ static int jack_process_callback(jack_nframes_t nframes, void *arg) static void audio_cap_jack_probe(struct device_info **available_devices, int *count) { - *available_devices = malloc(sizeof(struct device_info)); - strcpy((*available_devices)[0].id, "jack"); - strcpy((*available_devices)[0].name, "JACK audio input"); - *count = 1; + *available_devices = audio_jack_probe(PACKAGE_STRING, JackPortIsOutput, count); } static void audio_cap_jack_help(const char *client_name) { - jack_client_t *client; - jack_status_t status; - const char **ports; - char *last_name = NULL; - int i; - int channel_count; + int count = 0; + int i = 0; + struct device_info *available_devices = audio_jack_probe(client_name, JackPortIsOutput, &count); printf("Usage:\n"); printf("\t-s jack[:name=][:]\n"); @@ -131,42 +126,13 @@ static void audio_cap_jack_help(const char *client_name) printf("\t\t - name of the JACK client (default: %s)\n", PACKAGE_STRING); printf("\n"); - client = jack_client_open(client_name, JackNullOption, &status); - if(status & JackFailure) { - fprintf(stderr, "[JACK capture] Opening JACK client failed.\n"); + if(!available_devices) return; - } - - ports = jack_get_ports(client, NULL, NULL, JackPortIsOutput); - if(ports == NULL) { - fprintf(stderr, "[JACK capture] Unable to enumerate ports.\n"); - return; - } printf("Available devices:\n"); - i = 0; - channel_count = 0; - while(ports[i] != NULL) { - char *item = strdup(ports[i]); - char *save_ptr = NULL; - char *name; - - ++channel_count; - name = strtok_r(item, "_", &save_ptr); - if(last_name && strcmp(last_name, name) != 0) { - printf("\tjack:%s (%d channels)\n", last_name, channel_count); - channel_count = 0; - } - free(last_name); - last_name = strdup(name); - free(item); - ++i; + for(i = 0; i < count; i++){ + printf("\t%s\n", available_devices[i].name); } - if(last_name) { - printf("\tjack:%s (%d channels)\n", last_name, channel_count); - } - free(last_name); - jack_client_close(client); } static void * audio_cap_jack_init(const char *cfg) diff --git a/src/audio/playback/jack.c b/src/audio/playback/jack.c index 9b2d4be79..07b774ba6 100644 --- a/src/audio/playback/jack.c +++ b/src/audio/playback/jack.c @@ -48,6 +48,7 @@ #include "host.h" #include "lib_common.h" #include "utils/ring_buffer.h" +#include "jack_common.h" #include #include @@ -120,58 +121,22 @@ static int jack_process_callback(jack_nframes_t nframes, void *arg) static void audio_play_jack_probe(struct device_info **available_devices, int *count) { - *available_devices = malloc(sizeof(struct device_info)); - strcpy((*available_devices)[0].id, "jack"); - strcpy((*available_devices)[0].name, "JACK audio output"); - *count = 1; + *available_devices = audio_jack_probe(PACKAGE_STRING, JackPortIsInput, count); } static void audio_play_jack_help(const char *driver_name) { UNUSED(driver_name); - jack_client_t *client; - jack_status_t status; - char *last_name = NULL; - int i; - int channel_count; - const char **ports; - - client = jack_client_open(PACKAGE_STRING, JackNullOption, &status); - if(status & JackFailure) { - fprintf(stderr, "[JACK playback] Opening JACK client failed.\n"); + int count = 0; + int i = 0; + struct device_info *available_devices = audio_jack_probe(PACKAGE_STRING, JackPortIsInput, &count); + if(!available_devices) return; - } - - ports = jack_get_ports(client, NULL, NULL, JackPortIsInput); - if(ports == NULL) { - fprintf(stderr, "[JACK playback] Unable to enumerate ports.\n"); - return; - } printf("JACK playback:\n"); - i = 0; - channel_count = 0; - while(ports[i] != NULL) { - char *item = strdup(ports[i]); - char *save_ptr = NULL; - char *name; - - ++channel_count; - name = strtok_r(item, "_", &save_ptr); - if(last_name && strcmp(last_name, name) != 0) { - printf("\tjack:%s (%d channels)\n", last_name, channel_count); - channel_count = 0; - } - free(last_name); - last_name = strdup(name); - free(item); - ++i; + for(i = 0; i < count; i++){ + printf("\t%s\n", available_devices[i].name); } - if(last_name) { - printf("\tjack:%s (%d channels)\n", last_name, channel_count); - } - free(last_name); - jack_client_close(client); } static void * audio_play_jack_init(const char *cfg) diff --git a/src/jack_common.h b/src/jack_common.h new file mode 100644 index 000000000..aff702095 --- /dev/null +++ b/src/jack_common.h @@ -0,0 +1,107 @@ +/** + * @file jack_common.h + * @author Martin Piatka + * Martin Pulec + */ +/* + * Copyright (c) 2019 CESNET, z. s. p. o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JACK_COMMON_H +#define JACK_COMMON_H + +#include +#include +#include "types.h" + +static inline struct device_info *audio_jack_probe(const char *client_name, + unsigned long port_flags, + int *count) +{ + jack_client_t *client; + jack_status_t status; + char *last_name = NULL; + int i; + int channel_count; + const char **ports; + int port_count = 0; + struct device_info *available_devices = NULL; + + client = jack_client_open(client_name, JackNullOption, &status); + if(status & JackFailure) { + fprintf(stderr, "[JACK playback] Opening JACK client failed.\n"); + return NULL; + } + + ports = jack_get_ports(client, NULL, NULL, port_flags); + if(ports == NULL) { + fprintf(stderr, "[JACK playback] Unable to enumerate ports.\n"); + return NULL; + } + + for(port_count = 0; ports[port_count] != NULL; port_count++); + + available_devices = calloc(port_count, sizeof(struct device_info)); + + channel_count = 0; + *count = 0; + for(i = 0; ports[i] != NULL; i++) { + char *item = strdup(ports[i]); + char *save_ptr = NULL; + char *name; + + ++channel_count; + name = strtok_r(item, "_", &save_ptr); + if(last_name && strcmp(last_name, name) != 0) { + sprintf(available_devices[*count].name, "jack:%s (%d channels)", last_name, channel_count); + sprintf(available_devices[*count].id, "jack:%s", last_name); + channel_count = 0; + (*count)++; + } + free(last_name); + last_name = strdup(name); + free(item); + } + if(last_name) { + sprintf(available_devices[*count].name, "jack:%s (%d channels)", last_name, channel_count); + sprintf(available_devices[*count].id, "jack:%s", last_name); + (*count)++; + } + free(last_name); + jack_client_close(client); + + return available_devices; +} + + +#endif //JACK_COMMON_H +