ios – 将AVCaptureAudioDataOutput数据传递到vDSPAccelerate.framework

ios – 将AVCaptureAudioDataOutput数据传递到vDSPAccelerate.framework,第1张

概述我正在尝试创建一个在麦克风数据上运行FFT的应用程序,所以我可以检查一下输入中最响的频率. 我看到有很多获取音频输入的方法(RemoteIO AudioUnit,AudioQueue服务和AVFoundation),但似乎AVFoundation是最简单的.我有这个设置: // Configure the audio sessionAVAudioSession *session = [AVAud @H_301_4@ 我正在尝试创建一个在麦克风数据上运行FFT的应用程序,所以我可以检查一下输入中最响的频率.

我看到有很多获取音频输入的方法(RemoteIO AudioUnit,AudioQueue服务和AVFoundation),但似乎AVFoundation是最简单的.我有这个设置:

// Configure the audio sessionAVAudioSession *session = [AVAudioSession sharedInstance];[session setcategory:AVAudioSessioncategoryRecord error:NulL];[session setMode:AVAudioSessionModeMeasurement error:NulL];[session setActive:YES error:NulL];// Optional - default gives 1024 samples at 44.1kHz//[session setPreferredioBufferDuration:samplesPerSlice/session.sampleRate error:NulL];// Configure the capture session (strongly-referenced instance variable,otherwise the capture stops after one slice)_captureSession = [[AVCaptureSession alloc] init];// Configure audio device inputAVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];AVCaptureDeviceinput *input = [AVCaptureDeviceinput deviceinputWithDevice:device error:NulL];[_captureSession addinput:input];// Configure audio data outputAVCaptureAudioDataOutput *output = [[AVCaptureAudioDataOutput alloc] init];dispatch_queue_t queue = dispatch_queue_create("My callback",disPATCH_QUEUE_SERIAL);[output setSampleBufferDelegate:self queue:queue];[_captureSession addOutput:output];// Start the capture session.   [_captureSession startRunning];

(加上错误检查,为了便于阅读,此处省略).

然后我实现以下AVCaptureAudioDataOutputSampleBufferDelegate方法:

- (voID)captureOutput:(AVCaptureOutput *)captureOutputdIDOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer       fromConnection:(AVCaptureConnection *)connection{    NSLog(@"Num samples: %ld",CMSampleBufferGetNumSamples(sampleBuffer));    // Usually gives 1024 (except the first slice)}

我不确定下一步应该是什么. CMSampleBuffer格式究竟描述了什么(以及可以做出哪些假设,如果有的话)?如何以最少的额外预处理量将原始音频数据输入vDSP_fft_zrip? (另外,您建议如何验证我看到的原始数据是否正确?)

@H_301_4@解决方法 CMSampleBufferRef是一种包含0个或更多媒体样本的opaque类型.文档中有一些模糊:

http://developer.apple.com/library/ios/#documentation/CoreMedia/Reference/CMSampleBuffer/Reference/reference.html

在这种情况下,它将包含一个音频缓冲区,以及样本格式和时序信息的描述等.如果你真的很感兴趣,只需在委托回调中加一个断点并查看.

第一步是获取指向已返回的数据缓冲区的指针:

// get a pointer to the audio bytesCMItemCount numSamples = CMSampleBufferGetNumSamples(sampleBuffer);CMBlockBufferRef audioBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);size_t lengthAtOffset;size_t totalLength;char *samples;CMBlockBufferGetDataPointer(audioBuffer,&lengthAtOffset,&totalLength,&samples);

iPhone麦克风的默认样本格式是线性PCM,具有16位样本.这可能是单声道或立体声,具体取决于是否有外接麦克风.要计算FFT,我们需要有一个浮点向量.幸运的是,有一个加速函数可以为我们进行转换:

// check what sample format we have// this should always be linear PCM// but may have 1 or 2 channelsCMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);const AudioStreamBasicDescription *desc = CMAudioFormatDescriptionGetStreamBasicDescription(format);assert(desc->mFormatID == kAudioFormatlinearPCM);if (desc->mChannelsPerFrame == 1 && desc->mBitsPerChannel == 16) {    float *convertedSamples = malloc(numSamples * sizeof(float));    vDSP_vflt16((short *)samples,1,convertedSamples,numSamples);} else {    // handle other cases as required}

现在您有一个样本缓冲区的浮点向量,可以与vDSP_fft_zrip一起使用.似乎无法通过AVFoundation将输入格式从麦克风更改为浮动样本,因此您将无法使用此最后一个转换步骤.我会在实践中保留缓冲区,如果有必要在更大的缓冲区到达时重新分配它们,这样你就不会使用每个委托回调来复制和释放缓冲区.

至于你的上一个问题,我想最简单的方法是注入一个已知的输入并检查它是否给你正确的响应.您可以在麦克风中播放正弦波,并检查您的FFT在正确的频率仓中是否有峰值,就像这样.

@H_301_4@ @H_301_4@ @H_301_4@ @H_301_4@ 总结

以上是内存溢出为你收集整理的ios – 将AVCaptureAudioDataOutput数据传递到vDSP / Accelerate.framework全部内容,希望文章能够帮你解决ios – 将AVCaptureAudioDataOutput数据传递到vDSP / Accelerate.framework所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1073797.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存