我寫了一個使用「novocaine」庫來錄製和播放聲音的voip應用程序。我將採樣率設置爲8kHz。此採樣率在音頻單元的AudioStreamBasicDescription中設置爲novocaine,並設置爲音頻會話屬性kAudioSessionProperty_PreferredHardwareSampleRate。據我所知,設置首選硬件採樣率並不能保證實際的硬件採樣率會發生變化,但它適用於除iPhone6s和iPhone6s +之外的所有設備(當路由更改爲揚聲器時)。通過iPhone6s(+)和揚聲器路線,我可以收到來自麥克風的48kHz聲音。所以我需要以某種方式將這個48kHz的聲音轉換成8kHz。在文檔中,我發現AudioConverterRef可以在這種情況下使用,但是我使用它時遇到麻煩。AudioConverterRef採樣率轉換(iOS)
我使用AudioConverterFillComplexBuffer進行採樣率轉換,但它總是返回-50 OSStatus(傳遞給函數的一個或多個參數無效)。這是我如何使用音頻轉換器:
// Setup AudioStreamBasicDescription for input
inputFormat.mSampleRate = 48000.0;
inputFormat.mFormatID = kAudioFormatLinearPCM;
inputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
inputFormat.mChannelsPerFrame = 1;
inputFormat.mBitsPerChannel = 8 * sizeof(float);
inputFormat.mFramesPerPacket = 1;
inputFormat.mBytesPerFrame = sizeof(float) * inputFormat.mChannelsPerFrame;
inputFormat.mBytesPerPacket = inputFormat.mBytesPerFrame * inputFormat.mFramesPerPacket;
// Setup AudioStreamBasicDescription for output
outputFormat.mSampleRate = 8000.0;
outputFormat.mFormatID = kAudioFormatLinearPCM;
outputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
outputFormat.mChannelsPerFrame = 1;
outputFormat.mBitsPerChannel = 8 * sizeof(float);
outputFormat.mFramesPerPacket = 1;
outputFormat.mBytesPerFrame = sizeof(float) * outputFormat.mChannelsPerFrame;
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame * outputFormat.mFramesPerPacket;
// Create new instance of audio converter
AudioConverterNew(&inputFormat, &outputFormat, &converter);
// Set conversion quality
UInt32 tmp = kAudioConverterQuality_Medium;
AudioConverterSetProperty(converter, kAudioConverterCodecQuality,
sizeof(tmp), &tmp);
AudioConverterSetProperty(converter, kAudioConverterSampleRateConverterQuality, sizeof(tmp), &tmp);
// Get the size of the IO buffer(s)
UInt32 bufferSizeFrames = 0;
size = sizeof(UInt32);
AudioUnitGetProperty(self.inputUnit,
kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global,
0,
&bufferSizeFrames,
&size);
UInt32 bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
// Allocate an AudioBufferList plus enough space for array of AudioBuffers
UInt32 propsize = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * outputFormat.mChannelsPerFrame);
// Malloc buffer lists
convertedInputBuffer = (AudioBufferList *)malloc(propsize);
convertedInputBuffer->mNumberBuffers = 1;
// Pre-malloc buffers for AudioBufferLists
convertedInputBuffer->mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame;
convertedInputBuffer->mBuffers[0].mDataByteSize = bufferSizeBytes;
convertedInputBuffer->mBuffers[0].mData = malloc(bufferSizeBytes);
memset(convertedInputBuffer->mBuffers[0].mData, 0, bufferSizeBytes);
// Setup callback for converter
static OSStatus inputProcPtr(AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription* __nullable* __nullable outDataPacketDescription,
void* __nullable inUserData)
{
// Read data from buffer
}
// Perform actual sample rate conversion
AudioConverterFillComplexBuffer(converter, inputProcPtr, NULL, &numberOfFrames, convertedInputBuffer, NULL)
inputProcPtr回調永遠不會被調用。我試圖設置不同數量的幀,但仍然收到OSStatus -50。
1)使用AudioConverterRef是否是正確的方式來進行採樣率轉換或可以以不同的方式完成?
2)我的轉換實現有什麼問題?
謝謝大家提前