From 1f5b16e9f0d81b824d2345b23199ddd8b447d300 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sat, 28 Jan 2023 16:04:09 +0200 Subject: [PATCH] Initial PaJackStreamInfo hostApiSpecificStreamInfo --- include/pa_jack.h | 46 +++++++++++++++++++++++++++ src/hostapi/jack/pa_jack.c | 65 ++++++++++++++++++++++++++++++++------ 2 files changed, 101 insertions(+), 10 deletions(-) diff --git a/include/pa_jack.h b/include/pa_jack.h index 750d116..70e6b1b 100644 --- a/include/pa_jack.h +++ b/include/pa_jack.h @@ -6,6 +6,7 @@ * PortAudio Portable Real-Time Audio Library * JACK-specific extensions * + * Copyright (c) 2023 Nedko Arnaudov * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining @@ -50,6 +51,51 @@ extern "C" { #endif +/* Stream setup flags. */ +/* While values here match the ones of JackPortFlags, + * relying on this fact should be last resort */ +typedef enum PaJackFlags +{ + /** + * if PaJackFlagPortIsPhysical is set, then the port corresponds + * to some kind of physical I/O connector. + */ + PaJackFlagPortIsPhysical = 0x4, + + /** + * PaJackFlagPortIsTerminal means: + * + * for an input port: the data received by the port + * will not be passed on or made + * available at any other port + * + * for an output port: the data available at the port + * does not originate from any other port + * + * Audio synthesizers, I/O hardware interface clients, HDR + * systems are examples of clients that would set this flag for + * their ports. + */ + PaJackFlagPortIsTerminal = 0x10, +} +PaJackFlags; + +/** @brief Jack Stream info + * + * This strutct provides means to supply additional parameters + * when opening stream with jack hostapi + */ +typedef struct PaJackStreamInfo +{ + unsigned long size; /**< sizeof(PaJackStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paJACK */ + unsigned long version; /**< 1 */ + + const char * name; /**< Name of stream to use as jack port name base can be (NULL) */ + unsigned long long flags; /**< collection of PaJackFlags */ +} +PaJackStreamInfo; + /** Set the JACK client name. * * During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain diff --git a/src/hostapi/jack/pa_jack.c b/src/hostapi/jack/pa_jack.c index 3dcaadb..ec82f9b 100644 --- a/src/hostapi/jack/pa_jack.c +++ b/src/hostapi/jack/pa_jack.c @@ -4,6 +4,7 @@ * Latest Version at: http://www.portaudio.com * JACK Implementation by Joshua Haberman * + * Copyright (c) 2023 Nedko Arnaudov * Copyright (c) 2004 Stefan Westerfeld * Copyright (c) 2004 Arve Knudsen * Copyright (c) 2002 Joshua Haberman @@ -880,6 +881,27 @@ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) jackErr_ = NULL; } +static PaError IsJackStreamInfoValid(PaJackStreamInfo *si) +{ + if( si == NULL ) + return paNoError; + + if( si->size != sizeof(PaJackStreamInfo) ) + return paIncompatibleHostApiSpecificStreamInfo; + if( si->hostApiType != paJACK ) + return paIncompatibleHostApiSpecificStreamInfo;// paInvalidHostApi; + if( si->version != 1 ) + return paIncompatibleHostApiSpecificStreamInfo;// paHostApiNotFound; + if( (si->flags & (PaJackFlagPortIsPhysical | PaJackFlagPortIsTerminal)) != si->flags ) + return paInvalidFlag; + + if( si->name && + strlen( clientName_ ) + strlen( si->name ) >= jack_port_name_size() ) + return paInvalidFlag; + + return paNoError; +} + static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, @@ -887,6 +909,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; + PaError result = paNoError; if( inputParameters ) { @@ -904,8 +927,9 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, return paInvalidChannelCount; /* validate inputStreamInfo */ - if( inputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ + result = IsJackStreamInfoValid( inputParameters->hostApiSpecificStreamInfo ); + if( result != paNoError ) + return result; } else { @@ -928,8 +952,9 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, return paInvalidChannelCount; /* validate outputStreamInfo */ - if( outputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ + result = IsJackStreamInfoValid( outputParameters->hostApiSpecificStreamInfo ); + if( result != paNoError ) + return result; } else { @@ -1169,8 +1194,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, return paInvalidChannelCount; /* validate inputStreamInfo */ - if( inputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ + result = IsJackStreamInfoValid( inputParameters->hostApiSpecificStreamInfo ); + if( result != paNoError ) + return result; } else { @@ -1193,8 +1219,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, return paInvalidChannelCount; /* validate outputStreamInfo */ - if( outputParameters->hostApiSpecificStreamInfo ) - return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ + result = IsJackStreamInfoValid( outputParameters->hostApiSpecificStreamInfo ); + if( result != paNoError ) + return result; } else { @@ -1258,7 +1285,16 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, ofs = jackHostApi->inputBase; for( i = 0; i < inputChannelCount; i++ ) { - snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i ); + if( inputParameters->hostApiSpecificStreamInfo ) + { + snprintf( port_string, jack_port_name_size(), "%s in_%lu", + inputParameters->hostApiSpecificStreamInfo, + ofs + i ); + } + else + { + snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i ); + } UNLESS( stream->local_input_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory ); @@ -1268,7 +1304,16 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, ofs = jackHostApi->outputBase; for( i = 0; i < outputChannelCount; i++ ) { - snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i ); + if( outputParameters->hostApiSpecificStreamInfo ) + { + snprintf( port_string, jack_port_name_size(), "%s out_%lu", + outputParameters->hostApiSpecificStreamInfo, + ofs + i ); + } + else + { + snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i ); + } UNLESS( stream->local_output_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory );