#include "mem.h"
#include "log.h"
#include "syscalls.h"
+#include "configuration.h"
/** @brief Callback to request sample data */
static uaudio_callback *coreaudio_callback;
while(nsamples > 0) {
/* Integer-format input buffer */
- int16_t input[1024], *ptr = input;
+ unsigned char input[1024];
+ const size_t maxsamples = sizeof input / uaudio_sample_size;
/* How many samples we'll ask for */
- const int ask = nsamples > 1024 ? 1024 : (int)nsamples;
+ const size_t ask = nsamples > maxsamples ? maxsamples : nsamples;
/* How many we get */
int got;
got = coreaudio_callback(input, ask, coreaudio_userdata);
/* Convert the samples and store in the output buffer */
nsamples -= got;
- while(got > 0) {
- --got;
- *samples++ = *ptr++ * (0.5 / 32767);
+ if(uaudio_signed) {
+ if(uaudio_bits == 16) {
+ const int16_t *ptr = (int16_t *)input;
+ while(got > 0) {
+ --got;
+ *samples++ = *ptr++ * (0.5 / 32767);
+ }
+ } else {
+ const int8_t *ptr = (int8_t *)input;
+ while(got > 0) {
+ --got;
+ *samples++ = *ptr++ * (0.5 / 127);
+ }
+ }
+ } else {
+ if(uaudio_bits == 16) {
+ const uint16_t *ptr = (uint16_t *)input;
+ while(got > 0) {
+ --got;
+ *samples++ = ((int)*ptr++ - 32768) * (0.5 / 32767);
+ }
+ } else {
+ const uint8_t *ptr = (uint8_t *)input;
+ while(got > 0) {
+ --got;
+ *samples++ = ((int)*ptr++ - 128) * (0.5 / 127);
+ }
+ }
}
}
/* Move on to the next buffer */
AudioStreamBasicDescription asbd;
const char *device;
+ if(uaudio_bits != 8 && uaudio_bits != 16)
+ disorder_fatal(0, "asked for %d bits/channel but only support 8 and 16",
+ uaudio_bits);
coreaudio_callback = callback;
coreaudio_userdata = userdata;
- device = uaudio_get("device");
+ device = uaudio_get("device", "default");
coreaudio_adid = coreaudio_getdevice(device);
+ /* Get the device properties */
propertySize = sizeof asbd;
status = AudioDeviceGetProperty(coreaudio_adid, 0, false,
kAudioDevicePropertyStreamFormat,
D(("mChannelsPerFrame %08lx", asbd.mChannelsPerFrame));
D(("mBitsPerChannel %08lx", asbd.mBitsPerChannel));
D(("mReserved %08lx", asbd.mReserved));
+ /* Check that everything adds up */
if(asbd.mFormatID != kAudioFormatLinearPCM)
disorder_fatal(0, "audio device does not support kAudioFormatLinearPCM");
+ if(asbd.mSampleRate != uaudio_rate
+ || asbd.mChannelsPerFrame != (unsigned)uaudio_channels) {
+ disorder_fatal(0, "want %dHz %d channels "
+ "but got %gHz %"PRIu32" channels",
+ uaudio_rate,
+ uaudio_channels,
+ (double)asbd.mSampleRate,
+ (uint32_t)asbd.mChannelsPerFrame);
+ }
+ /* Add a collector callback */
status = AudioDeviceAddIOProc(coreaudio_adid, coreaudio_adioproc, 0);
if(status)
coreaudio_fatal(status, "AudioDeviceAddIOProc");
coreaudio_fatal(status, "AudioDeviceStop");
}
+static void coreaudio_configure(void) {
+ uaudio_set("device", config->device);
+}
+
const struct uaudio uaudio_coreaudio = {
.name = "coreaudio",
.options = coreaudio_options,
.start = coreaudio_start,
.stop = coreaudio_stop,
.activate = coreaudio_activate,
- .deactivate = coreaudio_deactivate
+ .deactivate = coreaudio_deactivate,
+ .configure = coreaudio_configure,
};
#endif