微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS AudioUnit设置将麦克风输入保存到原始PCM文件

我目前正在开发iOS的VOIP项目.
我使用AudioUnits从麦克风获取数据并播放声音.
我的主要应用程序是用C#(Xamarin)编写的,它使用C库来加快音频和编解码器的处理速度.

为了测试输入/输出结果,我正在测试录音和放大器.在同一设备上播放
– 将麦克风音频数据存储在recordingCallback的缓冲区中
– 从playbackCallback中的缓冲区播放数据

这按预期工作,语音质量很好.

我需要将传入的音频数据从麦克风保存到原始PCM文件中.

我已经这样做了,但结果文件只包含一些短的“嘟嘟”信号.

所以我的问题是:

我需要什么音频设置,我可以在生成的原始PCM文件中听到我的声音(真实的音频信号)而不是短的哔声?
有谁知道什么可能是错的或我必须做什么,我能够正确地重播生成的PCM文件

我目前的格式设置是(C#代码):

int framesPerPacket = 1;
int channelsPerFrame = 1;
int bitsPerChannel = 16;
int bytesPerFrame = bitsPerChannel / 8 * channelsPerFrame;
int bytesPerPacket = bytesPerFrame * framesPerPacket;
AudioStreamBasicDescription audioFormat = new AudioStreamBasicDescription ()
{
  SampleRate = 8000,Format = AudioFormatType.LinearPCM,FormatFlags = AudioFormatFlags.LinearPCMIsSignedInteger | AudioFormatFlags.LinearPCMIsPacked | AudioFormatFlags.LinearPCMIsAlignedHigh,BitsPerChannel = bitsPerChannel,ChannelsPerFrame = channelsPerFrame,BytesPerFrame = bytesPerFrame,FramesPerPacket = framesPerPacket,BytesPerPacket = bytesPerPacket,Reserved = 0
};

额外的C#设置(这里没有错误检查):

AVAudioSession session = AVAudioSession.SharedInstance();
NSError error = null;
session.SetCategory(AVAudioSession.CategoryPlayAndRecord,out error);
session.SetPreferredioBufferDuration(Config.packetLength,out error);
session.SetPreferredSampleRate(Format.samplingRate,out error);
session.SetActive(true,out error);

我目前的录音回调简称(仅限PCM文件保存)(C代码):

Osstatus 
NotSoAmazingAudioEngine::recordingCallback(void *inRefCon,AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp,UInt32 inBusNumber,UInt32 inNumberFrames,audiobufferlist *ioData) {
std::pair<BufferData*,int> bufferInfo = _sendBuffer.getNextEmptyBufferList();
audiobufferlist* bufferList = new audiobufferlist();
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mData = NULL;
Osstatus status = AudioUnitRender(_instance->_audioUnit,ioActionFlags,inTimeStamp,inBusNumber,inNumberFrames,bufferList);
if(_instance->checkStatus(status))
{
    if(fout != NULL) //fout is a "FILE*"
    {
        fwrite(bufferList->mBuffers[0].mData,sizeof(short),bufferList->mBuffers[0].mDataByteSize/sizeof(short),fout);
    }
}
delete bufferList;
return noErr;

}

背景信息为什么我需要原始PCM文件

To compress the audio data I’d like to use the Opus codec.
With the codec I have the problem that there is a tiny “tick” at the end of each frame:
With a frame size of 60ms I nearly can’t hear them,at 20ms its annoying,at 10 ms frame sizes my own voice can’t be heared because of the ticking (for the VOIP application I try to get 10ms frames).

I don’t encode & decode in the callback functions (I encode/decode the data in the functions which I use to transfer audio data from the “micbuffer” to the “playbuffer”).
And everytime the playbackCallback wants to play some data,there is a frame in my buffer.

I also eliminate my Opus encoding/decoding functions as error source,because if I read PCM data from a raw PCM file,encode & decode it afterwards,and save it to a new raw PCM file,the ticking does not appear (if I play the result file with “Softe Audio Tools”,the output file audio is OK).

To find out what causes the ticking,I’d like to save the raw PCM data from the mic to a file to make further investigations on that issue.

解决方法

我自己找到了解决方案: 我的PCM播放器需要44100赫兹立体声,但我的文件只有8000赫兹单声道,因此我保存的文件播放速度太快了10倍.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐