Recording with RemoteIO: .caf result - step shifted slower + distorted

So, I have compiled several routines for recording sound based on some posts here. The posts I referred to here and here , along with reading the sites to which they link.

My setup: I have an existing AUGraph: (multiple AUSamplers -> Mixer -> RemoteIO). AUSamplers are connected to the tracks in the MusicPlayer instance. Everything works fine, but I want to add an entry to it.

Recording works, but the result .caf - step / pace shifted slower +, has poor sound quality. There must be something wrong with the format I specify?

Can someone take a look at this and tell me where I formatted the format incorrectly?

EDIT: Could there be a stereo / mono issue? I want to record in mono.

I set the stream format for the RemoteIO instance:

AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 44100.00; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2; // Apply format result = AudioUnitSetProperty(ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat)); 

Then, from the button action, I create a Ref file and attach renderCallback to the RemoteIO instance:

 - (void)startRecording { OSStatus result; AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 44100.00; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory]; CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); result = ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &audioFormat, NULL, kAudioFileFlags_EraseFile, &extAudioFileRef); CFRelease(destinationURL); NSAssert(result == noErr, @"Couldn't create file for writing"); result = ExtAudioFileSetProperty(extAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &audioFormat); NSAssert(result == noErr, @"Couldn't create file for format"); result = ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL); NSAssert(result == noErr, @"Couldn't initialize write buffers for audio file"); printf("Adding render to remoteIO \n"); result = AudioUnitAddRenderNotify(ioUnit, renderCallback, (__bridge void*)self); if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result]; return;} } 

Finally, in my rendercallback, I write out the data in the postRender phase:

 static OSStatus renderCallback (void * inRefCon, AudioUnitRenderActionFlags * ioActionFlags, const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData) { OSStatus result; if (*ioActionFlags == kAudioUnitRenderAction_PostRender){ double timeInSeconds = inTimeStamp->mSampleTime / kSampleRate; printf("%fs inBusNumber: %lu inNumberFrames: %lu \n", timeInSeconds, inBusNumber, inNumberFrames); MusicPlayerController* THIS = (__bridge MusicPlayerController *)inRefCon; result = ExtAudioFileWriteAsync(THIS->extAudioFileRef, inNumberFrames, ioData); if(result) printf("ExtAudioFileWriteAsync %ld \n", result); } return noErr; } 
+4
source share
1 answer

Good - found a code that solves this, although I don’t quite understand why.

I set mBitsPerChannel to 16 for the output stream of RemoteIO and ExtFileRef. The result slowed down and a scratchy sound. Setting ExtFileRef mBitsPerChannel to 32 plus adding the kAudioFormatFlagsNativeEndian flag solves the problem: the .caf sound is perfect (leaving the RemoteIO output stream settings as they were).

But then also adjusting the output parameters of the RemoteIO in accordance with my new settings also works. Therefore, I am confused. Should this work as long as the AudioStreamBasicDescription parameters are symmetrical for the RemoteIO and ExtFileRef instance?

In any case ... the working setting is below.

 size_t bytesPerSample = sizeof (AudioUnitSampleType); AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate= graphSampleRate; audioFormat.mFormatID=kAudioFormatLinearPCM; audioFormat.mFormatFlags=kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; audioFormat.mBytesPerPacket=bytesPerSample; audioFormat.mBytesPerFrame=bytesPerSample; audioFormat.mFramesPerPacket=1; audioFormat.mChannelsPerFrame=1; audioFormat.mBitsPerChannel= 8 * bytesPerSample; audioFormat.mReserved=0; 
+3
source

Source: https://habr.com/ru/post/917297/


All Articles