Re: iOS 13 is not bit-accurate; previous versions were
Re: iOS 13 is not bit-accurate; previous versions were
- Subject: Re: iOS 13 is not bit-accurate; previous versions were
- From: Robert Kukuchka via Coreaudio-api <email@hidden>
- Date: Tue, 26 May 2020 14:01:11 -0700
Hi Andrew,
What mode are you specifying? Have you tried Measurement Mode?
~Rob
> On May 26, 2020, at 1:30 PM, Andrew Smith via Coreaudio-api
> <email@hidden> wrote:
>
> Brian,
>
> I’ve tried both allow mixing with other audio, and not, both work the same.
>
> I’m using the remote IO framework, and I will paste my main setup code below.
> One interesting thing that I’ve found is that if I select playback only mode,
> it works fine! The audio data passes through to the USB output device
> unaltered and the surround files play fine. It’s just when I add in record
> mode (using [avSession setCategory:AVAudioSessionCategoryPlayAndRecord
> mode:mode options:options error:&err]) that the output audio is no longer
> bit-accurate. I do need record and play for audio analysis of the input.
> Again this is only under iOS 13, older iOS work fine.
>
> Best,
> Andrew Smith
>
> In this code sample rate is always 48k and numChannels = 2. This is just
> copied from other sources and may certainly have issues! One thing I find
> weird is that I have to reverse the output busses when I apply the formats,
> ie I have to apply the playback format to the input bus.
>
> #define kOutputBus 0
> #define kInputBus 1
>
> OSStatus status;
> // Describe audio component
> AudioComponentDescription desc;
> desc.componentType = kAudioUnitType_Output;
> desc.componentSubType = kAudioUnitSubType_RemoteIO;
> desc.componentFlags = 0;
> desc.componentFlagsMask = 0;
> desc.componentManufacturer = kAudioUnitManufacturer_Apple;
>
> // Get component
> AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
>
> // Get audio units
> status = AudioComponentInstanceNew(inputComponent, &inRemoteIOUnitAV);
> [AvHelper checkStatus:status msg:@"AudioComponentInstanceNew"];
>
> UInt32 flag = 1;
> // Enable IO for playback
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioOutputUnitProperty_EnableIO,
> kAudioUnitScope_Output,
> kOutputBus,
> &flag,
> sizeof(flag));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 2"];
>
> // Enable IO for recording
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioOutputUnitProperty_EnableIO,
> kAudioUnitScope_Input,
> kInputBus,
> &flag,
> sizeof(flag));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 1"];
>
>
> // Describe format
> int numChannels = 2;
> AudioStreamBasicDescription audioFormat;
>
> audioFormat.mSampleRate = auSampleRate;
> audioFormat.mFormatID = kAudioFormatLinearPC
> audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger |
> kAudioFormatFlagIsPacked;
> audioFormat.mBytesPerPacket = 2 * numChannels;
> audioFormat.mFramesPerPacket = 1;
> audioFormat.mBytesPerFrame = 2 * numChannels;
> audioFormat.mChannelsPerFrame = numChannels;
> audioFormat.mBitsPerChannel = 16;
> audioFormat.mReserved = 0;
> // Apply format
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioUnitProperty_StreamFormat,
> kAudioUnitScope_Output,
> kInputBus,
> &audioFormat,
> sizeof(audioFormat));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 3"];
>
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioUnitProperty_StreamFormat,
> kAudioUnitScope_Input,
> kOutputBus,
> &audioFormat,
> sizeof(audioFormat));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 4"];
>
> // Set input callback
> AURenderCallbackStruct callbackStruct;
> callbackStruct.inputProc = inRenderProc.inputProc;
> callbackStruct.inputProcRefCon = inRenderProc.inputProcRefCon;
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioOutputUnitProperty_SetInputCallback,
> kAudioUnitScope_Global,
> kInputBus,
> &callbackStruct,
> sizeof(callbackStruct));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 5"];
>
> // Set output callback
> callbackStruct.inputProc = outRenderProc.inputProc;
> callbackStruct.inputProcRefCon = outRenderProc.inputProcRefCon;
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioUnitProperty_SetRenderCallback,
> kAudioUnitScope_Global,
> kOutputBus,
> &callbackStruct,
> sizeof(callbackStruct));
> [AvHelper checkStatus:status msg:@"AudioUnitSetProperty 6"];
>
> // Disable buffer allocation for the recorder (optional - do this if we
> want to pass in our own)
> flag = 0;
> status = AudioUnitSetProperty(inRemoteIOUnitAV,
> kAudioUnitProperty_ShouldAllocateBuffer,
> kAudioUnitScope_Output,
> kInputBus,
> &flag,
> sizeof(flag));
>
>
>> On May 21, 2020, at 10:18 PM, Brian Willoughby <email@hidden
>> <mailto:email@hidden>> wrote:
>>
>> On macOS, there was a way to "hog" the audio interface so that no other
>> application's audio would be mixed in. Even at the same sample rate, mixing
>> anything with a surround-encoded stream would destroy it.
>>
>> Are you already using anything like this? If so, and Apple broke it, then
>> that's one thing. If Apple doesn't offer "hog" mode on iOS, then you might
>> need to look for another way to take full control of the stream. I haven't
>> written audio code for iOS in years, but I recall that applications can mark
>> themselves as input-only, output-only, input and output, and various other
>> categories. Perhaps there is a category to say that you need un-manipulated
>> streams.
>>
>> The audio objects seem to keep changing, but there are usually way to query
>> your stream type, the stream type out the output unit, and to do that for
>> the input, output, and perhaps even global scopes (I think global scope is
>> the only one that doesn't have a stream type).
>>
>> Sorry I don't have an immediate answer, but maybe you can give us a few more
>> details on which audio object frameworks you're using, and perhaps the
>> results of some code-based queries of the output stream formats.
>>
>> Brian Willoughby
>>
>>
>> On May 21, 2020, at 4:00 PM, Andrew Smith via Coreaudio-api
>> <email@hidden <mailto:email@hidden>> wrote:
>>> I’m the developer of AudioTools, over 10 years on the app store, lots of
>>> audio test & measurement functions. One in particular is a 5.1 surround
>>> signal generator, which works with our own hardware device,
>>> iAudioInterface2, which happens to have a Toslink digital audio output
>>> connector. The idea is that I pre-encode surround signal audio files in the
>>> Dolby Digital 5.1 format, open the file in the app, and break the data into
>>> packets that get formatted to Dolby specs and sent out the Toslink
>>> connector at 48k sample rate. Surprisingly, this actually works. For many
>>> years it has, anyway. I can send out a pink noise signal to a particular
>>> channel, or send an encoded music file out to the system. I am using basic
>>> remote IO audio processing here. Despite many years in audio and DSP I do
>>> not consider myself an iOS guru, I just use a simple set of iOS tools that
>>> seem to work.
>>>
>>> Starting with iOS 13 however, the surround signal generator no longer
>>> works. This scheme relies on the signal (data) not being altered by iOS at
>>> all, it must be sent through unaltered, as bit-accurate audio. In 13, I get
>>> just random noise, while the same app on iOS 11 or 12 outputs the surround
>>> data correctly. My guess is that Apple has inserted a sample rate
>>> converter, even though as far as I can tell the hardware is still running
>>> at 48k, and I am requesting 48k. I’ve posted a bug report to Apple but
>>> unsurprisingly I’ve had no response to it since I am likely the only person
>>> on Earth who cares about this. Any ideas on something to try or if perhaps
>>> anyone else has knowledge about this I would highly appreciate it!
>>>
>>> Best,
>>> Andrew Smith
>>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Coreaudio-api mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden