aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends/coreaudio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alc/backends/coreaudio.cpp')
-rw-r--r--alc/backends/coreaudio.cpp165
1 files changed, 82 insertions, 83 deletions
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 5d004efc..9254dbe0 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -27,6 +27,7 @@
#include <string.h>
#include "alcmain.h"
+#include "alexcpt.h"
#include "alu.h"
#include "ringbuffer.h"
#include "converter.h"
@@ -48,17 +49,21 @@ struct CoreAudioPlayback final : public BackendBase {
static OSStatus MixerProcC(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData);
+ AudioBufferList *ioData)
+ {
+ return static_cast<CoreAudioPlayback*>(inRefCon)->MixerProc(ioActionFlags, inTimeStamp,
+ inBusNumber, inNumberFrames, ioData);
+ }
OSStatus MixerProc(AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
- ALCenum open(const ALCchar *name) override;
+ void open(const ALCchar *name) override;
bool reset() override;
bool start() override;
void stop() override;
- AudioUnit mAudioUnit;
+ AudioUnit mAudioUnit{};
ALuint mFrameSize{0u};
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
@@ -73,14 +78,6 @@ CoreAudioPlayback::~CoreAudioPlayback()
}
-OSStatus CoreAudioPlayback::MixerProcC(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
- return static_cast<CoreAudioPlayback*>(inRefCon)->MixerProc(ioActionFlags, inTimeStamp,
- inBusNumber, inNumberFrames, ioData);
-}
-
OSStatus CoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags*,
const AudioTimeStamp*, UInt32, UInt32, AudioBufferList *ioData)
{
@@ -91,12 +88,12 @@ OSStatus CoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags*,
}
-ALCenum CoreAudioPlayback::open(const ALCchar *name)
+void CoreAudioPlayback::open(const ALCchar *name)
{
if(!name)
name = ca_device;
else if(strcmp(name, ca_device) != 0)
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Device name \"%s\" not found", name};
/* open the default output unit */
AudioComponentDescription desc{};
@@ -114,14 +111,15 @@ ALCenum CoreAudioPlayback::open(const ALCchar *name)
if(comp == nullptr)
{
ERR("AudioComponentFindNext failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not find audio component"};
}
OSStatus err{AudioComponentInstanceNew(comp, &mAudioUnit)};
if(err != noErr)
{
ERR("AudioComponentInstanceNew failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not create component instance: %u",
+ err};
}
/* init and start the default audio unit... */
@@ -129,12 +127,10 @@ ALCenum CoreAudioPlayback::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitInitialize failed\n");
- AudioComponentInstanceDispose(mAudioUnit);
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not initialize audio unit: %u", err};
}
mDevice->DeviceName = name;
- return ALC_NO_ERROR;
}
bool CoreAudioPlayback::reset()
@@ -307,12 +303,16 @@ struct CoreAudioCapture final : public BackendBase {
static OSStatus RecordProcC(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData);
+ AudioBufferList *ioData)
+ {
+ return static_cast<CoreAudioCapture*>(inRefCon)->RecordProc(ioActionFlags, inTimeStamp,
+ inBusNumber, inNumberFrames, ioData);
+ }
OSStatus RecordProc(AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
UInt32 inNumberFrames, AudioBufferList *ioData);
- ALCenum open(const ALCchar *name) override;
+ void open(const ALCchar *name) override;
bool start() override;
void stop() override;
ALCenum captureSamples(al::byte *buffer, ALCuint samples) override;
@@ -338,23 +338,15 @@ CoreAudioCapture::~CoreAudioCapture()
}
-OSStatus CoreAudioCapture::RecordProcC(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
- return static_cast<CoreAudioCapture*>(inRefCon)->RecordProc(ioActionFlags, inTimeStamp,
- inBusNumber, inNumberFrames, ioData);
-}
-
OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags*,
const AudioTimeStamp *inTimeStamp, UInt32, UInt32 inNumberFrames,
AudioBufferList*)
{
AudioUnitRenderActionFlags flags = 0;
union {
- ALbyte _[sizeof(AudioBufferList) + sizeof(AudioBuffer)*2];
+ al::byte _[sizeof(AudioBufferList) + sizeof(AudioBuffer)*2];
AudioBufferList list;
- } audiobuf = { { 0 } };
+ } audiobuf{};
auto rec_vec = mRing->getWriteVector();
inNumberFrames = static_cast<UInt32>(minz(inNumberFrames,
@@ -393,7 +385,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags*,
}
-ALCenum CoreAudioCapture::open(const ALCchar *name)
+void CoreAudioCapture::open(const ALCchar *name)
{
AudioStreamBasicDescription requestedFormat; // The application requested format
AudioStreamBasicDescription hardwareFormat; // The hardware format
@@ -412,7 +404,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(!name)
name = ca_device;
else if(strcmp(name, ca_device) != 0)
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Device name \"%s\" not found", name};
desc.componentType = kAudioUnitType_Output;
#if TARGET_OS_IOS
@@ -429,7 +421,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(comp == NULL)
{
ERR("AudioComponentFindNext failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not finda udio component"};
}
// Open the component
@@ -437,7 +429,8 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioComponentInstanceNew failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not create component instance: %u",
+ err};
}
// Turn off AudioUnit output
@@ -447,7 +440,8 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE,
+ "Could not disable audio unit output property: %u", err};
}
// Turn on AudioUnit input
@@ -457,7 +451,8 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE,
+ "Could not enable audio unit input property: %u", err};
}
#if !TARGET_OS_IOS
@@ -470,16 +465,17 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
- err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &inputDevice);
+ err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr,
+ &propertySize, &inputDevice);
if(err != noErr)
{
ERR("AudioObjectGetPropertyData failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not get input device: %u", err};
}
if(inputDevice == kAudioDeviceUnknown)
{
ERR("No input device found\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Unknown input device"};
}
// Track the input device
@@ -488,7 +484,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not set input device: %u", err};
}
}
#endif
@@ -502,7 +498,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not set capture callback: %u", err};
}
// Initialize the device
@@ -510,7 +506,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitInitialize failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not initialize audio unit: %u", err};
}
// Get the hardware format
@@ -520,52 +516,54 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr || propertySize != sizeof(AudioStreamBasicDescription))
{
ERR("AudioUnitGetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not get input format: %u", err};
}
// Set up the requested format description
switch(mDevice->FmtType)
{
- case DevFmtUByte:
- requestedFormat.mBitsPerChannel = 8;
- requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
- break;
- case DevFmtShort:
- requestedFormat.mBitsPerChannel = 16;
- requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
- break;
- case DevFmtInt:
- requestedFormat.mBitsPerChannel = 32;
- requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
- break;
- case DevFmtFloat:
- requestedFormat.mBitsPerChannel = 32;
- requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
- break;
- case DevFmtByte:
- case DevFmtUShort:
- case DevFmtUInt:
- ERR("%s samples not supported\n", DevFmtTypeString(mDevice->FmtType));
- return ALC_INVALID_VALUE;
+ case DevFmtUByte:
+ requestedFormat.mBitsPerChannel = 8;
+ requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
+ break;
+ case DevFmtShort:
+ requestedFormat.mBitsPerChannel = 16;
+ requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
+ break;
+ case DevFmtInt:
+ requestedFormat.mBitsPerChannel = 32;
+ requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
+ break;
+ case DevFmtFloat:
+ requestedFormat.mBitsPerChannel = 32;
+ requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
+ break;
+ case DevFmtByte:
+ case DevFmtUShort:
+ case DevFmtUInt:
+ ERR("%s samples not supported\n", DevFmtTypeString(mDevice->FmtType));
+ throw al::backend_exception{ALC_INVALID_VALUE, "%s samples not suppoted",
+ DevFmtTypeString(mDevice->FmtType)};
}
switch(mDevice->FmtChans)
{
- case DevFmtMono:
- requestedFormat.mChannelsPerFrame = 1;
- break;
- case DevFmtStereo:
- requestedFormat.mChannelsPerFrame = 2;
- break;
+ case DevFmtMono:
+ requestedFormat.mChannelsPerFrame = 1;
+ break;
+ case DevFmtStereo:
+ requestedFormat.mChannelsPerFrame = 2;
+ break;
- case DevFmtQuad:
- case DevFmtX51:
- case DevFmtX51Rear:
- case DevFmtX61:
- case DevFmtX71:
- case DevFmtAmbi3D:
- ERR("%s not supported\n", DevFmtChannelsString(mDevice->FmtChans));
- return ALC_INVALID_VALUE;
+ case DevFmtQuad:
+ case DevFmtX51:
+ case DevFmtX51Rear:
+ case DevFmtX61:
+ case DevFmtX71:
+ case DevFmtAmbi3D:
+ ERR("%s not supported\n", DevFmtChannelsString(mDevice->FmtChans));
+ throw al::backend_exception{ALC_INVALID_VALUE, "%s not supported",
+ DevFmtChannelsString(mDevice->FmtChans)};
}
requestedFormat.mBytesPerFrame = requestedFormat.mChannelsPerFrame * requestedFormat.mBitsPerChannel / 8;
@@ -591,7 +589,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Could not set input format: %u", err};
}
// Set the AudioUnit output format frame count
@@ -602,7 +600,8 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(FrameCount64 > std::numeric_limits<uint32_t>::max()/2)
{
ERR("FrameCount too large\n");
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE,
+ "Calculated frame count is too lareg: %" PRIu64, FrameCount64};
}
outputFrameCount = static_cast<uint32_t>(FrameCount64);
@@ -611,7 +610,8 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
if(err != noErr)
{
ERR("AudioUnitSetProperty failed: %d\n", err);
- return ALC_INVALID_VALUE;
+ throw al::backend_exception{ALC_INVALID_VALUE, "Failed to set capture frame count: %u",
+ err};
}
// Set up sample converter if needed
@@ -621,10 +621,9 @@ ALCenum CoreAudioCapture::open(const ALCchar *name)
mDevice->Frequency, Resampler::FastBSinc24);
mRing = CreateRingBuffer(outputFrameCount, mFrameSize, false);
- if(!mRing) return ALC_INVALID_VALUE;
+ if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to allocate ring buffer"};
mDevice->DeviceName = name;
- return ALC_NO_ERROR;
}