gpt4 book ai didi

ios - AudioConverterRef 采样率转换 (iOS)

转载 作者:行者123 更新时间:2023-12-01 16:39:30 24 4
gpt4 key购买 nike

我编写了一个 voip 应用程序,它使用“novocaine”库来录制和播放声音。我将采样率设置为8kHz。此采样率在音频单元的 AudioStreamBasicDescription 中的 novocaine 中设置,并作为 Audio Session 属性 kAudioSessionProperty_PreferredHardwareSampleRate。我知道设置首选硬件采样率并不能保证实际的硬件采样率会改变,但它适用于除 iPhone6s 和 iPhone6s+ 之外的所有设备(当路由更改为扬声器时)。使用 iPhone6s(+) 和扬声器路线,我从麦克风接收 48kHz 声音。所以我需要以某种方式将 48 kHz 声音转换为 8kHz。在文档中,我发现 AudioConverterRef 可以在这种情况下使用,但我在使用它时遇到了麻烦。

我使用 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)我的转换实现有什么问题?

先谢谢大家了

最佳答案

有一个问题是这样的:

AudioUnitGetProperty(self.inputUnit,
kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global,
0,
&bufferSizeFrames,
&size);

kAudioDevicePropertyBufferFrameSize 是 OSX 属性,iOS 上不存在。这段代码是如何编译的?

如果您以某种方式使其编译,请检查该函数的返回代码!我有一种感觉,它失败了,并且 bufferSizeFrames 为零。这将使 AudioConverterFillComplexBuffer 返回 -50 (kAudio_ParamError)。

因此,在 iOS 上,您可以自己选择一个 bufferSizeFrames,或者如果必须的话,可以根据 AVAudioSessionIOBufferDuration 来选择它。

另一个问题:检查您的返回码。全部!

例如

UInt32 tmp = kAudioConverterQuality_Medium;
AudioConverterSetProperty( converter, kAudioConverterCodecQuality,
sizeof( tmp ), &tmp );

我很确定 LPCM->LPCM 转换中没有编解码器可言,并且 kAudioConverterQuality_Medium 无论如何都不是与 kAudioConverterCodecQuality 一起使用的正确值。我不明白这个调用如何能够成功。

关于ios - AudioConverterRef 采样率转换 (iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34899959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com