Jack: report ports in --capabilities

This commit is contained in:
Martin Piatka
2019-08-21 13:28:47 +02:00
parent 696034ff59
commit 8597f39bdd
3 changed files with 123 additions and 85 deletions

View File

@@ -59,6 +59,7 @@
#include "audio/utils.h"
#include "lib_common.h"
#include "utils/ring_buffer.h"
#include "jack_common.h"
#include <jack/jack.h>
#include <stdlib.h>
#include <stdio.h>
@@ -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>][:<device>]\n");
@@ -131,42 +126,13 @@ static void audio_cap_jack_help(const char *client_name)
printf("\t\t<n> - 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)

View File

@@ -48,6 +48,7 @@
#include "host.h"
#include "lib_common.h"
#include "utils/ring_buffer.h"
#include "jack_common.h"
#include <jack/jack.h>
#include <stdlib.h>
@@ -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)

107
src/jack_common.h Normal file
View File

@@ -0,0 +1,107 @@
/**
* @file jack_common.h
* @author Martin Piatka <piatka@cesnet.cz>
* Martin Pulec <pulec@cesnet.cz>
*/
/*
* 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 <stdio.h>
#include <jack/jack.h>
#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