繁体   English   中英

我如何解释 AudioBuffer 并获得权力?

[英]How do I interpret an AudioBuffer and get the power?

我正在尝试为我的应用程序制作一个音量计,它将在录制视频时显示。 我发现 iOS 上有很多对此类仪表的支持,但主要是AVAudioPlayer ,这对我来说是没有选择的。 我正在使用AVCaptureSession进行录制,然后会以如下所示的委托方法结束:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);

    CFRetain(sampleBuffer);
    CFRetain(formatDescription);

    if(connection == audioConnection)
    {
        CMBlockBufferRef blockBuffer;
        AudioBufferList audioBufferList;

        CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, 
            NULL, &audioBufferList, sizeof(AudioBufferList), NULL, NULL,
            kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
            &blockBuffer);

        SInt16 *data = audioBufferList.mBuffers[0].mData;
    }
    //Releases etc..
}

(只显示相关代码)

据我所知,我收到一个“样本缓冲区”,其中包含音频或视频。 一旦我确认连接确实是音频,然后我从缓冲区“提取”audioBufferList,然后我坐在这儿留下一个(或多个?)audioBuffers 的列表。 据我了解,实际数据表示为SInt16或“16 位有符号整数”,据我所知,其范围从-32,76832,767 但是,如果我简单地打印出这个接收到的值,我会得到很多反弹的数字。 当处于“沉默”状态时,我得到的值在-200200之间快速反弹,当有噪音时,我得到的值从-4,00013,000 ,完全乱序。 正如我从阅读中了解到的,值0将代表沉默。 但是,我不明白负值和正值之间的区别,也不知道它们是否能够一直向上/向下达到+-32,768

我相信我需要一定比例的“响亮”,但一直找不到任何东西。

我已经阅读了一些关于此事的教程和参考资料,但对我来说没有任何意义。 我按照一个指南执行此操作(附加到上面的代码,在if ):

float accumulator = 0;
for(int i = 0; i < audioBufferList.mBuffers[0].mDataByteSize; i++)
    accumulator += data[i] * data[i];
float power = accumulator / audioBufferList.mBuffers[0].mDataByteSize;
float decibels = log10f(power);
NSLog(@"%f", decibels);

显然,这段代码应该从-1+1对齐,但这并没有发生。 现在我得到的值围绕6.194681时沉默, 7.773492一些噪音。 这感觉像是正确的“范围”,但在“错误的地方”。 我不能简单地从数字中减去 7 并假设我在-1+1之间。 这应该如何工作背后应该有一些逻辑和科学,但我对数字音频的工作原理知之甚少。

有谁知道这背后的逻辑? 0 总是沉默而-32,76832,767是大声的噪音吗? 然后我可以简单地将所有负值乘以-1以始终得到正值,然后找出它们的百分比(0 到 32767 之间)吗? 不知何故,我不相信这会奏效,因为我想负值是有原因的..我不完全确定要尝试什么。

您问题中的代码在几个方面是错误的。 这段代码试图从下面的文章中复制它,但是您没有正确处理它从文章中的基于浮点数的代码转换为 16 位整数数学。 您还会循环错误数量的值(最大 i),最终会引入垃圾数据。 所以这是各种各样的错误。

https://www.mikeash.com/pyblog/friday-qa-2012-10-12-obtaining-and-interpreting-audio-data.html

文章中的代码是正确的。 这是它的内容,稍微扩展一下。 这只是查看 32 位浮点缓冲区列表中的第一个缓冲区。

float accumulator = 0;
AudioBuffer buffer = bufferList->mBuffers[0];
float * data = (float *)buffer.mData;
UInt32 numSamples = buffer.mDataByteSize / sizeof(float);

for (UInt32 i = 0; i < numSamples; i++) {
    accumulator += data[i] * data[i];
}
float power = accumulator / (float)numSamples;
float decibels = 10 * log10f(power);

正如文章所说,这里的结果是分贝使用 0dB 参考。 例如,0.0 是最大值 例如,这与 AVAudioPlayer 的 averagePowerForChannel 返回的内容相同。

要在 16 位整数上下文中使用它,您需要 a) 适当地循环遍历每个 16 位样本,b) 将 data[i] 值从 16 位整数转换为 [ -1.0, 1.0] 在平方并添加到累加器之前的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM