【发布时间】:2014-08-11 22:14:40
【问题描述】:
我正在尝试为我的应用制作音量计,它会在录制视频时显示。我发现很多对 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,768 到32,767。但是,如果我只是打印出这个收到的值,我会得到很多弹跳数字。当处于“沉默”状态时,我得到的值在-200 和200 之间快速反弹,而当有噪音时,我得到从-4,000 到13,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,768 和32,767 是响亮的噪音时,0 是否总是静音?然后我可以简单地将所有负值乘以-1 以始终得到正值,然后找出它们的百分比(0 到 32767 之间)吗?不知何故,我不相信这会起作用,因为我猜负值是有原因的。我不完全确定要尝试什么。
【问题讨论】:
-
我建议阅读 en.wikipedia.org/wiki/Pulse-code_modulation 了解背景
-
@sbooth 谢谢,我从中学到了,但遗憾的是没有什么可以解决我的问题。我并不完全理解我所拥有的数据如何代表“响度”。动力'。当我现在对着麦克风说话时,我的日志中会打印出一堆数字。当我提高声音时,它们会有所不同。它们是否只代表我说话的音量,还是它们也代表其余部分,如我所说的/我的频率等?那么我怎样才能找到音量的最小值/最大值..
-
数字代表整个信号——你的声音的音量、频率等。计算响度有不同的方法——最简单的可能是选择一个采样窗口(例如 1/10 秒) ) 然后计算 RMS 功率。这不是一个很好的响度估计值,但它会是一个开始。
-
您在这一行中缺少平方根 - float power = accumulator / audioBufferList.mBuffers[0].mDataByteSize;
-
你找到解决办法了吗?
标签: ios objective-c audio avfoundation core-audio