我如何解释AudioBuffer并获得电源?

问题描述 投票:4回答:1

我正在尝试为我的应用制作一个体积计,它将在录制视频时显示。我已经为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,然后坐在这里列出一个(或多个?)audioBuffer列表。据我了解,实际数据表示为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之间。它应该如何工作背后应该有一些逻辑和科学,但是我对数字音频的工作原理还不够了解。

有人知道背后的逻辑吗?当-32,76832,767是大声声音时,0是否总是静音?然后,我可以简单地将所有负值乘以-1来始终得到正值,然后找出它们的百分比是多少(介于0和32767之间)吗?不知何故,我不认为这会奏效,因为我想这是负值的原因。.我不确定要尝试什么。

ios objective-c audio avfoundation core-audio
1个回答
0
投票

您问题中的代码在几种方面是错误的。这段代码试图从下面的文章中复制它,但是您没有正确地将其从文章中的基于浮点数的代码转换为16位整数数学。您还会循环使用错误数量的值(max 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是maximum值。例如,AVAudioPlayer的averagePowerForChannel返回的内容与此相同。

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

© www.soinside.com 2019 - 2024. All rights reserved.