diff --git a/client/Makefile b/client/Makefile
index a3fe3b81..9f2cfc53 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -70,7 +70,7 @@ else ifeq ($(TARGET), MACOS)
CXX = g++
STRIP = strip
CXXFLAGS += -DHAS_OGG -DHAS_COREAUDIO -DFREEBSD -DHAS_BONJOUR -DHAS_DAEMON -I/usr/local/include -Wno-unused-local-typedef -Wno-deprecated
-LDFLAGS += -lvorbis -lFLAC -L/usr/local/lib -framework AudioToolbox -framework CoreFoundation -framework IOKit
+LDFLAGS += -lvorbis -lFLAC -L/usr/local/lib -framework AudioToolbox -framework CoreAudio -framework CoreFoundation -framework IOKit
OBJ += ../common/daemon.o player/coreAudioPlayer.o browseZeroConf/browseBonjour.o
else
diff --git a/client/player/coreAudioPlayer.cpp b/client/player/coreAudioPlayer.cpp
index 232b5818..d31396c7 100644
--- a/client/player/coreAudioPlayer.cpp
+++ b/client/player/coreAudioPlayer.cpp
@@ -16,6 +16,8 @@
along with this program. If not, see .
***/
+//#include
+#include
#include "coreAudioPlayer.h"
#define NUM_BUFFERS 2
@@ -44,6 +46,54 @@ CoreAudioPlayer::~CoreAudioPlayer()
}
+/// TODO: experimental. No output device can be configured yet.
+std::vector CoreAudioPlayer::pcm_list(void)
+{
+ UInt32 propsize;
+
+ AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster };
+
+ AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &theAddress, 0, NULL, &propsize);
+ int nDevices = propsize / sizeof(AudioDeviceID);
+ AudioDeviceID *devids = new AudioDeviceID[nDevices];
+ AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &propsize, devids);
+
+ std::vector result;
+ for (int i = 0; i < nDevices; ++i)
+ {
+ if (devids[i] == kAudioDeviceUnknown)
+ continue;
+
+ UInt32 propSize;
+ AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyScopeOutput, 0 };
+ if (AudioObjectGetPropertyDataSize(devids[i], &theAddress, 0, NULL, &propSize))
+ continue;
+
+ AudioBufferList *buflist = (AudioBufferList *)malloc(propSize);
+ if (AudioObjectGetPropertyData(devids[i], &theAddress, 0, NULL, &propSize, buflist))
+ continue;
+ int channels = 0;
+ for (UInt32 i = 0; i < buflist->mNumberBuffers; ++i)
+ channels += buflist->mBuffers[i].mNumberChannels;
+ free(buflist);
+ if (channels == 0)
+ continue;
+
+ UInt32 maxlen = 1024;
+ char buf[maxlen];
+ theAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, 0 };
+ AudioObjectGetPropertyData(devids[i], &theAddress, 0, NULL, &maxlen, buf);
+ LOG(DEBUG) << "device: " << i << ", name: " << buf << ", channels: " << channels << "\n";
+
+ result.push_back(PcmDevice(i, buf));
+ }
+ delete[] devids;
+ return result;
+}
+
+
void CoreAudioPlayer::playerCallback(AudioQueueRef queue, AudioQueueBufferRef bufferRef)
{
/// Estimate the playout delay by checking the number of frames left in the buffer
diff --git a/client/player/coreAudioPlayer.h b/client/player/coreAudioPlayer.h
index 13f58d4e..7cb5d9f8 100644
--- a/client/player/coreAudioPlayer.h
+++ b/client/player/coreAudioPlayer.h
@@ -41,6 +41,7 @@ public:
virtual ~CoreAudioPlayer();
void playerCallback(AudioQueueRef queue, AudioQueueBufferRef bufferRef);
+ static std::vector pcm_list(void);
protected:
virtual void worker();
diff --git a/client/player/pcmDevice.h b/client/player/pcmDevice.h
index c5f48120..8c61fff4 100644
--- a/client/player/pcmDevice.h
+++ b/client/player/pcmDevice.h
@@ -24,7 +24,16 @@
struct PcmDevice
{
- PcmDevice() : idx(-1){};
+ PcmDevice() :
+ idx(-1)
+ {
+ };
+
+ PcmDevice(int idx, const std::string& name, const std::string& description = "") :
+ idx(idx), name(name), description(description)
+ {
+ };
+
int idx;
std::string name;
std::string description;