list output devices on macos

This commit is contained in:
Johannes Pohl 2017-10-21 20:37:12 +02:00
parent 331e965a4e
commit 52c5d21da4
4 changed files with 62 additions and 2 deletions

View file

@ -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

View file

@ -16,6 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
//#include <CoreServices/CoreServices.h>
#include <CoreAudio/CoreAudio.h>
#include "coreAudioPlayer.h"
#define NUM_BUFFERS 2
@ -44,6 +46,54 @@ CoreAudioPlayer::~CoreAudioPlayer()
}
/// TODO: experimental. No output device can be configured yet.
std::vector<PcmDevice> 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<PcmDevice> 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

View file

@ -41,6 +41,7 @@ public:
virtual ~CoreAudioPlayer();
void playerCallback(AudioQueueRef queue, AudioQueueBufferRef bufferRef);
static std::vector<PcmDevice> pcm_list(void);
protected:
virtual void worker();

View file

@ -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;