Set the CoreAudio stream according to the device channel format

This commit is contained in:
Chris Robinson 2021-07-24 22:01:53 -07:00
parent 510e5fc197
commit 02a985e70a

View File

@ -397,10 +397,10 @@ bool CoreAudioPlayback::reset()
/* retrieve default output unit's properties (output side) */ /* retrieve default output unit's properties (output side) */
AudioStreamBasicDescription streamFormat{}; AudioStreamBasicDescription streamFormat{};
auto size = static_cast<UInt32>(sizeof(AudioStreamBasicDescription)); UInt32 size{sizeof(streamFormat)};
err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output,
0, &streamFormat, &size); 0, &streamFormat, &size);
if(err != noErr || size != sizeof(AudioStreamBasicDescription)) if(err != noErr || size != sizeof(streamFormat))
{ {
ERR("AudioUnitGetProperty failed\n"); ERR("AudioUnitGetProperty failed\n");
return false; return false;
@ -416,15 +416,9 @@ bool CoreAudioPlayback::reset()
TRACE(" streamFormat.mSampleRate = %5.0f\n", streamFormat.mSampleRate); TRACE(" streamFormat.mSampleRate = %5.0f\n", streamFormat.mSampleRate);
#endif #endif
/* set default output unit's input side to match output side */ /* Use the sample rate from the output unit's current parameters, but reset
err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, * everything else.
0, &streamFormat, size); */
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
return false;
}
if(mDevice->Frequency != streamFormat.mSampleRate) if(mDevice->Frequency != streamFormat.mSampleRate)
{ {
mDevice->BufferSize = static_cast<uint>(uint64_t{mDevice->BufferSize} * mDevice->BufferSize = static_cast<uint>(uint64_t{mDevice->BufferSize} *
@ -433,82 +427,54 @@ bool CoreAudioPlayback::reset()
} }
/* FIXME: How to tell what channels are what in the output device, and how /* FIXME: How to tell what channels are what in the output device, and how
* to specify what we're giving? eg, 6.0 vs 5.1 */ * to specify what we're giving? e.g. 6.0 vs 5.1
switch(streamFormat.mChannelsPerFrame) */
{ streamFormat.mChannelsPerFrame = mDevice->channelsFromFmt();
case 1:
mDevice->FmtChans = DevFmtMono;
break;
case 2:
mDevice->FmtChans = DevFmtStereo;
break;
case 4:
mDevice->FmtChans = DevFmtQuad;
break;
case 6:
mDevice->FmtChans = DevFmtX51;
break;
case 7:
mDevice->FmtChans = DevFmtX61;
break;
case 8:
mDevice->FmtChans = DevFmtX71;
break;
default:
ERR("Unhandled channel count (%d), using Stereo\n", streamFormat.mChannelsPerFrame);
mDevice->FmtChans = DevFmtStereo;
streamFormat.mChannelsPerFrame = 2;
break;
}
setDefaultWFXChannelOrder();
/* use channel count and sample rate from the default output unit's current
* parameters, but reset everything else */
streamFormat.mFramesPerPacket = 1; streamFormat.mFramesPerPacket = 1;
streamFormat.mFormatFlags = 0; streamFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;
streamFormat.mFormatID = kAudioFormatLinearPCM;
switch(mDevice->FmtType) switch(mDevice->FmtType)
{ {
case DevFmtUByte: case DevFmtUByte:
mDevice->FmtType = DevFmtByte; mDevice->FmtType = DevFmtByte;
/* fall-through */ /* fall-through */
case DevFmtByte: case DevFmtByte:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; streamFormat.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamFormat.mBitsPerChannel = 8; streamFormat.mBitsPerChannel = 8;
break; break;
case DevFmtUShort: case DevFmtUShort:
mDevice->FmtType = DevFmtShort; mDevice->FmtType = DevFmtShort;
/* fall-through */ /* fall-through */
case DevFmtShort: case DevFmtShort:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; streamFormat.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamFormat.mBitsPerChannel = 16; streamFormat.mBitsPerChannel = 16;
break; break;
case DevFmtUInt: case DevFmtUInt:
mDevice->FmtType = DevFmtInt; mDevice->FmtType = DevFmtInt;
/* fall-through */ /* fall-through */
case DevFmtInt: case DevFmtInt:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; streamFormat.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
streamFormat.mBitsPerChannel = 32; streamFormat.mBitsPerChannel = 32;
break; break;
case DevFmtFloat: case DevFmtFloat:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat; streamFormat.mFormatFlags |= kLinearPCMFormatFlagIsFloat;
streamFormat.mBitsPerChannel = 32; streamFormat.mBitsPerChannel = 32;
break; break;
} }
streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame * streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame*streamFormat.mBitsPerChannel/8;
streamFormat.mBitsPerChannel / 8; streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame*streamFormat.mFramesPerPacket;
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags |= kAudioFormatFlagsNativeEndian |
kLinearPCMFormatFlagIsPacked;
err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
0, &streamFormat, sizeof(AudioStreamBasicDescription)); 0, &streamFormat, sizeof(streamFormat));
if(err != noErr) if(err != noErr)
{ {
ERR("AudioUnitSetProperty failed\n"); ERR("AudioUnitSetProperty failed\n");
return false; return false;
} }
setDefaultWFXChannelOrder();
/* setup callback */ /* setup callback */
mFrameSize = mDevice->frameSizeFromFmt(); mFrameSize = mDevice->frameSizeFromFmt();
AURenderCallbackStruct input{}; AURenderCallbackStruct input{};