mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 23:05:29 +00:00
Merge pull request #71 from michaelmaltese/feature-more-coreaudio-formats
coreaudio: support more formats: S16LE, S32LE, and Float64LE
This commit is contained in:
commit
45d5691254
|
@ -631,10 +631,15 @@ static int refresh_devices(struct SoundIoPrivate *si) {
|
||||||
|
|
||||||
rd.device->layout_count = 1;
|
rd.device->layout_count = 1;
|
||||||
rd.device->layouts = &rd.device->current_layout;
|
rd.device->layouts = &rd.device->current_layout;
|
||||||
// in CoreAudio, format is always 32-bit native endian float
|
|
||||||
rd.device->format_count = 1;
|
rd.device->format_count = 4;
|
||||||
rd.device->formats = &dev->prealloc_format;
|
rd.device->formats = ALLOCATE(enum SoundIoFormat, rd.device->format_count);
|
||||||
rd.device->formats[0] = SoundIoFormatFloat32NE;
|
if (!rd.device->formats)
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
rd.device->formats[0] = SoundIoFormatS16LE;
|
||||||
|
rd.device->formats[1] = SoundIoFormatS32LE;
|
||||||
|
rd.device->formats[2] = SoundIoFormatFloat32LE;
|
||||||
|
rd.device->formats[3] = SoundIoFormatFloat64LE;
|
||||||
|
|
||||||
prop_address.mSelector = kAudioDevicePropertyNominalSampleRate;
|
prop_address.mSelector = kAudioDevicePropertyNominalSampleRate;
|
||||||
prop_address.mScope = aim_to_scope(aim);
|
prop_address.mScope = aim_to_scope(aim);
|
||||||
|
@ -917,6 +922,30 @@ static OSStatus write_callback_ca(void *userdata, AudioUnitRenderActionFlags *io
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_ca_desc(enum SoundIoFormat fmt, AudioStreamBasicDescription *desc) {
|
||||||
|
switch (fmt) {
|
||||||
|
case SoundIoFormatFloat32LE:
|
||||||
|
desc->mFormatFlags = kAudioFormatFlagIsFloat;
|
||||||
|
desc->mBitsPerChannel = 32;
|
||||||
|
break;
|
||||||
|
case SoundIoFormatFloat64LE:
|
||||||
|
desc->mFormatFlags = kAudioFormatFlagIsFloat;
|
||||||
|
desc->mBitsPerChannel = 64;
|
||||||
|
break;
|
||||||
|
case SoundIoFormatS32LE:
|
||||||
|
desc->mFormatFlags = kAudioFormatFlagIsSignedInteger;
|
||||||
|
desc->mBitsPerChannel = 32;
|
||||||
|
break;
|
||||||
|
case SoundIoFormatS16LE:
|
||||||
|
desc->mFormatFlags = kAudioFormatFlagIsSignedInteger;
|
||||||
|
desc->mBitsPerChannel = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SoundIoErrorIncompatibleDevice;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||||
struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio;
|
struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio;
|
||||||
struct SoundIoOutStream *outstream = &os->pub;
|
struct SoundIoOutStream *outstream = &os->pub;
|
||||||
|
@ -957,12 +986,15 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP
|
||||||
AudioStreamBasicDescription format = {0};
|
AudioStreamBasicDescription format = {0};
|
||||||
format.mSampleRate = outstream->sample_rate;
|
format.mSampleRate = outstream->sample_rate;
|
||||||
format.mFormatID = kAudioFormatLinearPCM;
|
format.mFormatID = kAudioFormatLinearPCM;
|
||||||
format.mFormatFlags = kAudioFormatFlagIsFloat;
|
int err;
|
||||||
|
if ((err = set_ca_desc(outstream->format, &format))) {
|
||||||
|
outstream_destroy_ca(si, os);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
format.mBytesPerPacket = outstream->bytes_per_frame;
|
format.mBytesPerPacket = outstream->bytes_per_frame;
|
||||||
format.mFramesPerPacket = 1;
|
format.mFramesPerPacket = 1;
|
||||||
format.mBytesPerFrame = outstream->bytes_per_frame;
|
format.mBytesPerFrame = outstream->bytes_per_frame;
|
||||||
format.mChannelsPerFrame = outstream->layout.channel_count;
|
format.mChannelsPerFrame = outstream->layout.channel_count;
|
||||||
format.mBitsPerChannel = 32;
|
|
||||||
|
|
||||||
if ((os_err = AudioUnitSetProperty(osca->instance, kAudioOutputUnitProperty_CurrentDevice,
|
if ((os_err = AudioUnitSetProperty(osca->instance, kAudioOutputUnitProperty_CurrentDevice,
|
||||||
kAudioUnitScope_Input, OUTPUT_ELEMENT, &dca->device_id, sizeof(AudioDeviceID))))
|
kAudioUnitScope_Input, OUTPUT_ELEMENT, &dca->device_id, sizeof(AudioDeviceID))))
|
||||||
|
@ -975,7 +1007,7 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP
|
||||||
kAudioUnitScope_Input, OUTPUT_ELEMENT, &format, sizeof(AudioStreamBasicDescription))))
|
kAudioUnitScope_Input, OUTPUT_ELEMENT, &format, sizeof(AudioStreamBasicDescription))))
|
||||||
{
|
{
|
||||||
outstream_destroy_ca(si, os);
|
outstream_destroy_ca(si, os);
|
||||||
return SoundIoErrorOpeningDevice;
|
return SoundIoErrorIncompatibleDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
AURenderCallbackStruct render_callback = {write_callback_ca, os};
|
AURenderCallbackStruct render_callback = {write_callback_ca, os};
|
||||||
|
@ -1248,12 +1280,16 @@ static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPri
|
||||||
AudioStreamBasicDescription format = {0};
|
AudioStreamBasicDescription format = {0};
|
||||||
format.mSampleRate = instream->sample_rate;
|
format.mSampleRate = instream->sample_rate;
|
||||||
format.mFormatID = kAudioFormatLinearPCM;
|
format.mFormatID = kAudioFormatLinearPCM;
|
||||||
format.mFormatFlags = kAudioFormatFlagIsFloat;
|
|
||||||
format.mBytesPerPacket = instream->bytes_per_frame;
|
format.mBytesPerPacket = instream->bytes_per_frame;
|
||||||
format.mFramesPerPacket = 1;
|
format.mFramesPerPacket = 1;
|
||||||
format.mBytesPerFrame = instream->bytes_per_frame;
|
format.mBytesPerFrame = instream->bytes_per_frame;
|
||||||
format.mChannelsPerFrame = instream->layout.channel_count;
|
format.mChannelsPerFrame = instream->layout.channel_count;
|
||||||
format.mBitsPerChannel = 32;
|
|
||||||
|
int err;
|
||||||
|
if ((err = set_ca_desc(instream->format, &format))) {
|
||||||
|
instream_destroy_ca(si, is);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if ((os_err = AudioUnitSetProperty(isca->instance, kAudioUnitProperty_StreamFormat,
|
if ((os_err = AudioUnitSetProperty(isca->instance, kAudioUnitProperty_StreamFormat,
|
||||||
kAudioUnitScope_Output, INPUT_ELEMENT, &format, sizeof(AudioStreamBasicDescription))))
|
kAudioUnitScope_Output, INPUT_ELEMENT, &format, sizeof(AudioStreamBasicDescription))))
|
||||||
|
|
Loading…
Reference in a new issue