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;