Шум смешивается с аудио, частота дискретизации которого преобразуется на устройствах iOS13.
Вход аудио с частотой 48 кГц и понижающей дискретизацией. Звук выводится с частотой 8 кГц, но в звуке возникает шум.
Что мы обнаружили в результате экспериментов, так это то, что длина аудиоданных различается до и после преобразования частоты дискретизации.
Есть ли решение?
1.Аудиоданные получаются следующим образом.
NSArray *filePaths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentDirectory1 = [filePaths1 objectAtIndex:0];
NSString *filename1 = [documentDirectory1 stringByAppendingPathComponent:@"/SampleRateConversionBefore"];
FILE *fd1 = fopen([filename1 UTF8String], "a+b");
fwrite(data, sizeof(char), length, fd1);
fclose(fd1);
//data:Audio data acquired by microphone
convertedDataLength = [_converter doSampleRateConvert:data inDataLength:length outData:convertedData];
NSArray *filePaths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentDirectory2 = [filePaths2 objectAtIndex:0];
NSString *filename2 = [documentDirectory2 stringByAppendingPathComponent:@"/SampleRateConversionAfter"];
FILE *fd2 = fopen([filename2 UTF8String], "a+b");
fwrite(&convertedData, sizeof(char), convertedDataLength, fd2);
fclose(fd2);
2.doSampleRateConvert метод описывается следующим образом.
Значение, переданное inOutPacketNum, отличалось от возвращаемого значения. Но я не знаю, почему они не одинаковы. В iOS12 значение, переданное inOutPacketNum, и возвращаемое значение - это одно и то же значение.
-(NSInteger)doSampleRateConvert:(int16_t*)inData
inDataLength:(UInt32)inDataLength
outData:(int16_t*)outData
{
//Save conversion result
OSStatus status = 0;
//Stores the data size after sampling rate conversion
NSInteger resultOutDataLength = 0;
//Stores the number of packets after sample rate conversion
UInt32 inOutPacketNum = 0;
memcpy((int8_t*)_audioDataIO.inputBuffer, (int8_t*)inData , inDataLength);
_audioDataIO.inputBufferSize = inDataLength;
inOutPacketNum = inDataLength * SAMPLE_RATE_CONVERT_AFTER / SAMPLE_RATE_CONVERT_BEFORE / BYTES_PER_PACKET;
//Sample rate conversion
status = AudioConverterFillComplexBuffer(_audioConverter, //Audio Converter Object
convertDataProc, //Callback function that supplies the buffer needed for conversion
&_audioDataIO
&inOutPacketNum,
&_audioBufferList, //The buffer to get the result
NULL);
if(errSecSuccess != status)
{
return AUDIOCALL_CONVERT_ERROR;
}
//Set sample rate conversion byte size
resultOutDataLength = inOutPacketNum * BYTES_PER_PACKET;
//Copy the sample rate converted data
memcpy((int8_t*)outData, (int8_t*)_audioBufferList.mBuffers[0].mData , resultOutDataLength);
return resultOutDataLength;
}
3. Обратный вызов, вызываемый во время преобразования частоты дискретизации:
OSStatus convertDataProc(
AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** outDataPacketDescription,
void* inUserData)
{
AudioDataIO *audioDataIO = (AudioDataIO*)inUserData;
//Set audio data before sample rate conversion
ioData->mBuffers[0].mData = audioDataIO->inputBuffer;
//Set the number of channels before sample rate conversion
ioData->mBuffers[0].mNumberChannels = CHANNELS_PER_FRAME;
if(*ioNumberDataPackets > (audioDataIO->inputBufferSize / BYTES_PER_PACKET))
{
//Set audio data size before sample rate conversion
ioData->mBuffers[0].mDataByteSize = audioDataIO->inputBufferSize;
//Set the number of packets read
*ioNumberDataPackets = audioDataIO->inputBufferSize / BYTES_PER_PACKET;
}
else
{
//Set byte size for ioNumberDataPackets specified in convertDataProc
ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets * BYTES_PER_PACKET;
//Set the number of packets read
*ioNumberDataPackets = *ioNumberDataPackets;
}
return errSecSuccess;
}