我有一个应用程序,我使用Core Audio进行录音。声音由某些声部组成,然后必须保存到设备中。它工作正常,但在一些新的ios版本中,我在输出文件中有一个噪音,如失真。可能的原因是什么? ExtAudioFileCreateWithURL
用于创建输出文件,ExtAudioFileSetProperty
用于设置其属性。
任何帮助将不胜感激。
此代码是由另一位目前无法使用的程序员创建的,因此我不知道为何会实施此类攻击。
为不同版本的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);
}
}
保存记录:
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; }
}
示例输出文件: output.mp3
答案 0 :(得分:1)
您可以使用SPEEX进行去噪,首先包括speex_preprocess.h:
SpeexPreprocessState *_spt = speex_preprocess_state_init(NN, 16000);/NN is 320 for sampleRate 16000.
int i=1;
speex_preprocess_ctl(_spt, SPEEX_PREPROCESS_SET_DENOISE, &i);
-(BOOL)doConvert:(void *)data SampleLength:(SInt64)length
{
AudioBufferList *dataBuffer = (AudioBufferList*)data;
AudioSampleType *samples = (AudioSampleType*)dataBuffer->mBuffers[0].mData;
SInt64 count = length / NN;
//short sample_ground[count][NN];
short **sample_group;
sample_group = (short**)malloc(sizeof(short*)*count);
for (int i=0; i<count; i++)
sample_group[i] = (short*)malloc(sizeof(short)*NN);
for (int i = 0; i < count; i++) {
for (int j = 0 ; j < NN; j++) {
short value = samples[i*NN+j];
sample_group[i][j] = value;
}
}
for (int i = 0; i < count; i++) {
speex_preprocess_run(_spt, sample_group[i]);
}
for (int i = 0; i < count; i++) {
for (int j = 0 ; j < NN; j++) {
samples[i*NN+j] = sample_group[i][j];
}
}
for (int i=0; i<count; i++)
free(sample_group[i]);
free(sample_group);
return YES;
}
答案 1 :(得分:0)
oops ..应该是反馈。抱歉..
您发布的代码的主要区别在于格式设置 sizeof(mOutputFormat),&amp; mOutputFormat 其中mOutputFormat未指定其设置方式。
与设置的旧版本的dst格式进行比较。
设置“错误”格式通常会产生不良声音: - )