I’ve got an app where I use Core Audio for sound recording. Sound is made from some parts and then must be saved to the device. It was working fine but in some new ios versions I have a noise, something like distortion, in output files. What is the possible reason? ExtAudioFileCreateWithURL is used to create output file and ExtAudioFileSetProperty to set its properties.
Any help will be appreciated.
This code was created by another programmer who is currently unavailable, so I don’t have any idea why such hack was implemented.
The way sound buffer is created for different versions of ios:
static BOOL shouldFixData = NO;
static int checkOnce = 1;
if (checkOnce) {
checkOnce = 0;
if (inNumberFrames * 8 == ioData->mBuffers[0].mDataByteSize) {
shouldFixData = YES;
}
}
if (shouldFixData) {
AudioBufferList cutData = {0};
cutData.mNumberBuffers = 1;
cutData.mBuffers[0].mNumberChannels = ioData->mBuffers[0].mNumberChannels;
cutData.mBuffers[0].mDataByteSize = ioData->mBuffers[0].mDataByteSize / 2;
cutData.mBuffers[0].mData = malloc(cutData.mBuffers[0].mDataByteSize);
SInt32* oldData = (SInt32*)ioData->mBuffers[0].mData;
SInt32* newData = (SInt32*)cutData.mBuffers[0].mData;
int count = cutData.mBuffers[0].mDataByteSize/4;
for (int i = 0; i < count; ++i) {
newData[i] = oldData[i*2];
}
ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, &cutData);
free(cutData.mBuffers[0].mData);
} else {
ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, ioData);
}
}
Saving the record:
CAStreamBasicDescription dstFormat;
dstFormat.mSampleRate = mOutputFormat.mSampleRate;
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mChannelsPerFrame = 2;
dstFormat.mBitsPerChannel = 16;
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mFramesPerPacket = 1;
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
//recordInfo.output file is ExtAudioFileRef
err = ExtAudioFileCreateWithURL((CFURLRef)recordFileURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordInfo.outputFile);
if (err) { printf("ExtAudioFileCreateWithURL result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
NSComparisonResult versionCompareRes = [currSysVer compare:@"4.3" options:NSNumericSearch];
if (versionCompareRes == NSOrderedSame || versionCompareRes == NSOrderedDescending) {
//for new versions
err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(mOutputFormat), &mOutputFormat);
if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
} else {
//for old versions
err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(dstFormat), &dstFormat);
if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
}
sample output file:
output.mp3
oops.. should have been feedback. Sorry..
The main difference in the code you posted is the format setup
sizeof(mOutputFormat), &mOutputFormat
where mOutputFormat not specified how its set.
compared to the dst format for older version which is set.
Setting “wrong” format usually gives bad sound 🙂