CMSampleBufferSetDataBufferFromAudioBufferList returning error 12731

audiounit, avfoundation, core-audio, ios, iphone

Solution

Since there is a similar question without answer all over the internet. I managed to solve it and the recording fully works. My problem was wrong parameter passed to `CMSampleBufferCreate`. numSamples instead of 1 should be equal to numberOfFrames. So the final call is:

CMSampleBufferCreate(kCFAllocatorDefault,NULL,false,NULL,NULL,format,
                    (CMItemCount)numberOfFrames, 1, &timing, 0, NULL, &buff);

Problem

I am trying to capture app sound and pass it to AVAssetWriter as input. I am setting callback for audio unit to get AudioBufferList. The problem starts with converting AudioBufferList to CMSampleBufferRef. It always return error -12731 which indicates that required parameter is missing Thanks Karol ``` -(OSStatus) recordingCallbackWithRef:(void*)inRefCon flags:(AudioUnitRenderActionFlags*)flags timeStamp:(const AudioTimeStamp*)timeStamp busNumber:(UInt32)busNumber framesNumber:(UInt32)numberOfFrames data:(AudioBufferList*)data { AudioBufferList bufferList; bufferList.mNumberBuffers = 1; bufferList.mBuffers[0].mData = NULL; OSStatus status; status = AudioUnitRender(audioUnit, flags, timeStamp, busNumber, numberOfFrames, &bufferList); [self checkOSStatus:status]; AudioStreamBasicDescription audioFormat; // Describe format 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; CMSampleBufferRef buff = NULL; CMFormatDescriptionRef format = NULL; CMSampleTimingInfo timing = { CMTimeMake(1, 44100), kCMTimeZero, kCMTimeInvalid }; status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &audioFormat, 0, NULL, 0, NULL, NULL, &format); [self checkOSStatus:status]; status = CMSampleBufferCreate(kCFAllocatorDefault,NULL,false,NULL,NULL,format,1, 1, &timing, 0, NULL, &buff); [self checkOSStatus:status]; status = CMSampleBufferSetDataBufferFromAudioBufferList(buff, kCFAllocatorDefault, kCFAllocatorDefault, 0, &bufferList); [self checkOSStatus:status]; //Status here is 12731 //Do something with the buffer return noErr; } ``` Edit: I checked bufferList.mBuffers[0].mData and it is not null so probably that's not a problem.

Original source