首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioConverterRef采样率转换(iOS)

AudioConverterRef采样率转换(iOS)
EN

Stack Overflow用户
提问于 2016-01-20 20:22:16
回答 1查看 1.4K关注 0票数 4

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

我使用AudioConverterFillComplexBuffer进行采样率转换,但它总是返回-50 OSStatus (传递给函数的一个或多个参数无效)。下面是我使用音频转换器的方法:

代码语言:javascript
复制
// 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)我的转换实现出了什么问题?

提前感谢所有人

EN

回答 1

Stack Overflow用户

发布于 2016-01-21 05:56:59

一个问题是:

代码语言:javascript
复制
AudioUnitGetProperty(self.inputUnit,
                             kAudioDevicePropertyBufferFrameSize,
                             kAudioUnitScope_Global,
                             0,
                             &bufferSizeFrames,
                             &size);

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

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

因此,在iOS上,要么自己选择一个bufferSizeFrames,要么基于AVAudioSessionIOBufferDuration

另一个问题:检查你的返回码。所有的人!

例如:

代码语言:javascript
复制
UInt32 tmp = kAudioConverterQuality_Medium;
AudioConverterSetProperty( converter, kAudioConverterCodecQuality,
                      sizeof( tmp ), &tmp );

我非常确定在LPCM->LPCM转换中没有编解码器可言,而且kAudioConverterQuality_Medium在任何情况下都不是与kAudioConverterCodecQuality一起使用的正确值。我不明白这个调用怎么能成功。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34899959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档