]> Repos - portaudio/commitdiff
Improves device selection via portaudio for MacOSX (hostapi coreaudio):
authorRoss Bencina <rossb@audiomulch.com>
Sat, 3 Sep 2016 12:34:22 +0000 (22:34 +1000)
committerRoss Bencina <rossb@audiomulch.com>
Sat, 3 Sep 2016 12:34:22 +0000 (22:34 +1000)
adds the possibility to get the device transport type (USB, bluetooth,
etc.) and an unique identifier. Corrects problems when: loading the same
device twice (for the moment only for the same hostapi), a new plugged
device is selected during a call or if the selected device is unchanged.
Vincent Lucas committed on Oct 29, 2012
26848f0 from https://github.com/jitsi/libsrc/commits/master/portaudio.zip

Makefile [new file with mode: 0644]
include/pa_mac_core.h
include/portaudio.h
portaudio-2.0.pc [new file with mode: 0644]
src/hostapi/coreaudio/pa_mac_core.c

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..fb69908
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,243 @@
+#
+# PortAudio V19 Makefile.in
+#
+# Dominic Mazzoni
+# Modifications by Mikael Magnusson
+# Modifications by Stelios Bounanos
+#
+
+top_srcdir = .
+srcdir = .
+
+top_builddir = .
+PREFIX = /usr/local
+prefix = $(PREFIX)
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+CC = gcc
+CXX = @CXX@
+CFLAGS = -I/usr/include -I$(top_srcdir)/include -I$(top_srcdir)/src/common -I$(top_srcdir)/src/os/unix -std=c99 -O2 -Wall -pedantic -pipe -fPIC -DNDEBUG -DPA_LITTLE_ENDIAN -arch i386 -arch x86_64 -mmacosx-version-min=10.4  -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=8 -DHAVE_NANOSLEEP=1 -DPA_USE_COREAUDIO=1
+LIBS = -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
+AR = /usr/bin/ar
+RANLIB = ranlib
+SHELL = /bin/sh
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+SHARED_FLAGS = 
+LDFLAGS = 
+DLL_LIBS = 
+CXXFLAGS = 
+NASM = 
+NASMOPT = 
+LN_S = ln -s
+LT_CURRENT=2
+LT_REVISION=0
+LT_AGE=0
+
+OTHER_OBJS = src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o  src/os/mac_osx/pa_osx_hotplug.o
+INCLUDES = portaudio.h
+
+PALIB = libportaudio.la
+PAINC = include/portaudio.h
+
+PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \
+            -export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio|PaOSS)_.*" \
+            -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+COMMON_OBJS = \
+       src/common/pa_allocation.o \
+       src/common/pa_converters.o \
+       src/common/pa_cpuload.o \
+       src/common/pa_dither.o \
+       src/common/pa_debugprint.o \
+       src/common/pa_front.o \
+       src/common/pa_process.o \
+       src/common/pa_stream.o \
+       src/common/pa_trace.o \
+       src/hostapi/skeleton/pa_hostapi_skeleton.o
+
+LOOPBACK_OBJS = \
+       qa/loopback/src/audio_analyzer.o \
+       qa/loopback/src/biquad_filter.o \
+       qa/loopback/src/paqa_tools.o \
+       qa/loopback/src/test_audio_analyzer.o \
+       qa/loopback/src/write_wav.o \
+       qa/loopback/src/paqa.o
+       
+TESTS = \
+       bin/paqa_devs \
+       bin/paqa_errs \
+       bin/patest1 \
+       bin/patest_buffer \
+       bin/patest_callbackstop \
+       bin/patest_clip \
+       bin/patest_dither \
+       bin/patest_hang \
+       bin/patest_in_overflow \
+       bin/patest_latency \
+       bin/patest_leftright \
+       bin/patest_longsine \
+       bin/patest_many \
+       bin/patest_maxsines \
+       bin/patest_mono \
+       bin/patest_multi_sine \
+       bin/patest_out_underflow \
+       bin/patest_pink \
+       bin/patest_prime \
+       bin/patest_read_record \
+       bin/patest_read_write_wire \
+       bin/patest_record \
+       bin/patest_ringmix \
+       bin/patest_saw \
+       bin/patest_sine8 \
+       bin/patest_sine \
+       bin/patest_sine_channelmaps \
+       bin/patest_sine_formats \
+       bin/patest_sine_time \
+       bin/patest_sine_srate \
+       bin/patest_start_stop \
+       bin/patest_stop \
+       bin/patest_stop_playout \
+       bin/patest_toomanysines \
+       bin/patest_two_rates \
+       bin/patest_underflow \
+       bin/patest_wire \
+       bin/patest_write_sine \
+       bin/patest_write_sine_nonint \
+       bin/patest_update_available_device_list \
+       bin/pa_devs \
+       bin/pa_fuzz \
+       bin/pa_minlat
+
+# Most of these don't compile yet.  Put them in TESTS, above, if
+# you want to try to compile them...
+ALL_TESTS = \
+       $(TESTS) \
+       bin/patest_sync \
+       bin/debug_convert \
+       bin/debug_dither_calc \
+       bin/debug_dual \
+       bin/debug_multi_in \
+       bin/debug_multi_out \
+       bin/debug_record \
+       bin/debug_record_reuse \
+       bin/debug_sine_amp \
+       bin/debug_sine \
+       bin/debug_sine_formats \
+       bin/debug_srate \
+       bin/debug_test1
+
+OBJS := $(COMMON_OBJS) $(OTHER_OBJS)
+
+LTOBJS := $(OBJS:.o=.lo)
+
+SRC_DIRS = \
+       src/common \
+       src/hostapi/alsa \
+       src/hostapi/asihpi \
+       src/hostapi/asio \
+       src/hostapi/coreaudio \
+       src/hostapi/dsound \
+       src/hostapi/jack \
+       src/hostapi/oss \
+       src/hostapi/wasapi \
+       src/hostapi/wdmks \
+       src/hostapi/wmme \
+       src/os/unix \
+       src/os/mac_osx \
+       src/os/win
+
+SUBDIRS =
+#SUBDIRS += bindings/cpp
+
+all: lib/$(PALIB) all-recursive tests
+
+tests: bin-stamp $(TESTS)
+
+loopback: bin-stamp bin/paloopback
+
+# With ASIO enabled we must link libportaudio and all test programs with CXX
+lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC)
+        $(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
+       @ #  $(LIBTOOL) --mode=link --tag=CXX $(CXX) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
+
+$(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c
+        $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
+       @ #  $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
+
+bin/paloopback: lib/$(PALIB) $(MAKEFILE) $(PAINC) $(LOOPBACK_OBJS)
+        $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(LOOPBACK_OBJS) lib/$(PALIB) $(LIBS)
+       @ # $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS)  $(LOOPBACK_OBJS) lib/$(PALIB) $(LIBS)
+
+install: lib/$(PALIB) portaudio-2.0.pc
+       $(INSTALL) -d $(DESTDIR)$(libdir)
+       $(LIBTOOL) --mode=install $(INSTALL) lib/$(PALIB) $(DESTDIR)$(libdir)
+       $(INSTALL) -d $(DESTDIR)$(includedir)
+       for include in $(INCLUDES); do \
+               $(INSTALL_DATA) -m 644 $(top_srcdir)/include/$$include $(DESTDIR)$(includedir)/$$include; \
+       done
+       $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+       $(INSTALL) -m 644 portaudio-2.0.pc $(DESTDIR)$(libdir)/pkgconfig/portaudio-2.0.pc
+       @echo ""
+       @echo "------------------------------------------------------------"
+       @echo "PortAudio was successfully installed."
+       @echo ""
+       @echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
+       @echo "to make the shared object available.  You may also need to"
+       @echo "modify your LD_LIBRARY_PATH environment variable to include"
+       @echo "the directory $(libdir)"
+       @echo "------------------------------------------------------------"
+       @echo ""
+       $(MAKE) install-recursive
+
+uninstall:
+       $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(PALIB)
+       $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(includedir)/portaudio.h
+       $(MAKE) uninstall-recursive
+
+clean:
+       $(LIBTOOL) --mode=clean rm -f $(LTOBJS) $(LOOPBACK_OBJS) $(ALL_TESTS) lib/$(PALIB)
+       $(RM) bin-stamp lib-stamp
+       -$(RM) -r bin lib
+
+distclean: clean
+       $(RM) config.log config.status Makefile libtool portaudio-2.0.pc
+
+%.o: %.c $(MAKEFILE) $(PAINC)
+       $(CC) -c $(CFLAGS) $< -o $@
+
+%.lo: %.c $(MAKEFILE) $(PAINC)
+       $(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $< -o $@
+
+%.lo: %.cpp $(MAKEFILE) $(PAINC)
+       $(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c $(CXXFLAGS) $< -o $@
+
+%.o: %.cpp $(MAKEFILE) $(PAINC)
+       $(CXX) -c $(CXXFLAGS) $< -o $@
+
+%.o: %.asm
+       $(NASM) $(NASMOPT) -o $@ $<
+
+bin-stamp:
+       -mkdir bin
+       touch $@
+
+lib-stamp:
+       -mkdir lib
+       -mkdir -p $(SRC_DIRS)
+       touch $@
+
+Makefile: Makefile.in config.status
+       $(SHELL) config.status
+
+all-recursive:
+       if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir all; done ; fi
+
+install-recursive:
+       if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir install; done ; fi
+
+uninstall-recursive:
+       if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir uninstall; done ; fi
index 43321b601e48923de30d74c08ec0625e82f1eac3..5ab36c4dffced9b30257cc96fc21237ea283a1e8 100644 (file)
@@ -46,7 +46,7 @@
 #include "portaudio.h"
 
 #include <AudioUnit/AudioUnit.h>
-//#include <AudioToolbox/AudioToolbox.h>
+#include <AudioToolbox/AudioToolbox.h>
 
 #ifdef __cplusplus
 extern "C" {
index dd0ea0891c443d0d4d5bb8df618e9d0fd6a05639..ecfa1c60d734a76ad6fe2682db89f4de04b29178 100644 (file)
@@ -470,7 +470,7 @@ typedef unsigned long PaSampleFormat;
 */
 typedef struct PaDeviceInfo
 {
-    int structVersion;  /* this is struct version 2 */
+    int structVersion;  /* this is struct version 3 */
     const char *name;
     PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
     
@@ -485,6 +485,11 @@ typedef struct PaDeviceInfo
     PaTime defaultHighOutputLatency;
 
     double defaultSampleRate;
+    
+    /*The transport type used by this device: USB, BuiltIn, Bluetooth, etc.*/
+    const char *transportType;
+    /*The unique identifier of this device (persistent across boots).*/
+    const char *deviceUID;
 } PaDeviceInfo;
 
 
diff --git a/portaudio-2.0.pc b/portaudio-2.0.pc
new file mode 100644 (file)
index 0000000..5046d1e
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: PortAudio
+Description: Portable audio I/O
+Requires:
+Version: 19
+
+Libs: -L${libdir} -lportaudio -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
+Cflags: -I${includedir} 
index a71a74c433f55665a25c0aafe19ba312e0752e6d..25cb2c517fe2c6ab17b9640f6971b228d9ed0f24 100644 (file)
@@ -67,6 +67,8 @@
 #include <string.h> /* strlen(), memcmp() etc. */
 #include <libkern/OSAtomic.h>
 
+#include <CoreFoundation/CFString.h>
+
 #include "pa_mac_core.h"
 #include "pa_mac_core_utilities.h"
 #include "pa_mac_core_blocking.h"
@@ -521,9 +523,111 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
 
     memset(deviceInfo, 0, sizeof(deviceInfo));
 
-    deviceInfo->structVersion = 2;
+    deviceInfo->structVersion = 3;
     deviceInfo->hostApi = hostApiIndex;
 
+    // target device UID property
+    unsigned long deviceUID = 0;
+
+    AudioObjectPropertyAddress addr;
+    addr.mSelector = kAudioDevicePropertyDeviceUID;
+    addr.mScope = kAudioObjectPropertyScopeGlobal;
+    addr.mElement = kAudioObjectPropertyElementMaster;
+
+    CFStringRef deviceUIDString;
+    propSize = sizeof(deviceUIDString);
+    err = ERR(AudioObjectGetPropertyData(
+            macCoreDeviceId,
+            &addr,
+            0,
+            NULL,
+            &propSize,
+            &deviceUIDString));
+    if (err)
+        return err;
+
+    CFIndex deviceUIDLength = CFStringGetLength(deviceUIDString) + 1;
+    char *ASCIIDeviceUID
+        = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,deviceUIDLength);
+    if ( !ASCIIDeviceUID )
+        return paInsufficientMemory;
+
+    deviceInfo->deviceUID = NULL;
+    if(CFStringGetCString (
+            deviceUIDString,
+            ASCIIDeviceUID,
+            deviceUIDLength,
+            kCFStringEncodingASCII))
+    {
+        deviceInfo->deviceUID = ASCIIDeviceUID;
+    }
+
+    // target device transport type property
+    addr.mSelector = kAudioDevicePropertyTransportType;
+    addr.mScope = kAudioObjectPropertyScopeGlobal;
+    addr.mElement = kAudioObjectPropertyElementMaster;
+
+    unsigned int transportType = 0;
+    propSize = sizeof(transportType);
+    err = ERR(AudioObjectGetPropertyData(
+            macCoreDeviceId,
+            &addr,
+            0,
+            NULL,
+            &propSize,
+            &transportType));
+    if (err)
+        return err;
+
+    switch(transportType)
+    {
+        case kAudioDeviceTransportTypeAggregate:
+            deviceInfo->transportType = "Aggregate";
+            break;
+        case kAudioDeviceTransportTypeAirPlay:
+            deviceInfo->transportType = "AirPlay";
+            break;
+        case kAudioDeviceTransportTypeAutoAggregate:
+            deviceInfo->transportType = "Auto aggregate";
+            break;
+        case kAudioDeviceTransportTypeAVB:
+            deviceInfo->transportType = "AVB";
+            break;
+        case kAudioDeviceTransportTypeBluetooth:
+            deviceInfo->transportType = "Bluetooth";
+            break;
+        case kAudioDeviceTransportTypeBuiltIn:
+            deviceInfo->transportType = "Built-in";
+            break;
+        case kAudioDeviceTransportTypeDisplayPort:
+            deviceInfo->transportType = "DisplayPort";
+            break;
+        case kAudioDeviceTransportTypeFireWire:
+            deviceInfo->transportType = "FireWire";
+            break;
+        case kAudioDeviceTransportTypeHDMI:
+            deviceInfo->transportType = "HDMI";
+            break;
+        case kAudioDeviceTransportTypePCI:
+            deviceInfo->transportType = "PCI";
+            break;
+        case kAudioDeviceTransportTypeThunderbolt:
+            deviceInfo->transportType = "Thunderbolt";
+            break;
+        case kAudioDeviceTransportTypeUnknown:
+            deviceInfo->transportType = "Unknown";
+            break;
+        case kAudioDeviceTransportTypeUSB:
+            deviceInfo->transportType = "USB";
+            break;
+        case kAudioDeviceTransportTypeVirtual:
+            deviceInfo->transportType = "Virtual";
+            break;
+        default:
+            deviceInfo->transportType = NULL;
+            break;
+    }
+
     /* Get the device name.  Fail if we can't get it. */
     err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
     if (err)