我需要构建一个表示录制文件中语音级别(dB)的可视化图形。我试着这样做:
NSError *error = nil;
AVAudioPlayer *meterPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:self.recording.fileName] error:&error];
if (error) {
_lcl_logger(lcl_cEditRecording, lcl_vError, @"Cannot initialize AVAudioPlayer with file %@ due to: %@ (%@)", self.recording.fileName, error, error.userInfo);
} else {
[meterPlayer prepareToPlay];
meterPlayer.meteringEnabled = YES;
for (NSTimeInterval i = 0; i <= meterPlayer.duration; ++i) {
meterPlayer.currentTime = i;
[meterPlayer updateMeters];
float averagePower = [meterPlayer averagePowerForChannel:0];
_lcl_logger(lcl_cEditRecording, lcl_vTrace, @"Second: %f, Level: %f dB", i, averagePower);
}
}
[meterPlayer release];
如果它解决了会很酷,但事实并非如此。我总是得到-160分贝。关于如何实现的任何其他想法?
UPD :这是我最后得到的:
答案 0 :(得分:7)
我只是想帮助那些遇到同样问题并花费大量时间进行搜索的人。为了省时间,我把答案拿出来。我不喜欢这里有人将此视为秘密...
搜索有关 extaudioservice ,音频队列和 avfoundation 的文章。
我意识到我应该使用AVFoundation,原因很简单,它是最新的捆绑包,它是Objective C但不是那么cpp风格。
所以做这件事的步骤并不复杂:
AVAsset
avassetreader
avasset
avassettrack
avasset
avassetreadertrackoutput
avassettrack
avassetreadertrackoutput
添加到上一个avassetreader
以开始读取音频数据从 avassettrackoutput 逐个 copyNextSampleBuffer (它是一个循环读取所有数据)。
每个 copyNextSampleBuffer 都会为您提供一个 CMSampleBufferRef ,可用于通过 CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer 获取 AudioBufferList 。 AudioBufferList 是 AudioBuffer 的数组。 AudioBuffer 是一堆音频数据,存储在 mData 部分。
您也可以在 extAudioService 中实现上述内容。但我认为上述 avfoundation 方法更容易。
接下来的问题是,如何处理 mData ?请注意,当您获得 avassetreadertrackoutput 时,您可以指定其输出格式,因此我们指定输出为 lpcm 。
然后你最终得到的 mData 实际上是一个浮动格式的幅度值。
容易对吗?虽然我花了很多时间来从这里和那里组织这个。
分享的两个有用资源: 阅读本文以了解基本术语和概念:https://www.mikeash.com/pyblog/friday-qa-2012-10-12-obtaining-and-interpreting-audio-data.html
示例代码:https://github.com/iluvcapra/JHWaveform 您可以直接从此示例中复制上述大部分代码,并将其用于您自己的目的。
答案 1 :(得分:3)
我自己没有使用它,但Apple的avTouch iPhone样本有由AVAudioPlayer驱动的条形图,您可以轻松查看它们是如何做到的。
答案 2 :(得分:0)
我认为您不能根据约束使用AVAudioPlayer
。即使您可以在没有实际播放声音文件的情况下让它“开始”,它也只会帮助您像音频文件流一样快地构建图形。你所说的是对声音进行静态分析,这需要采用不同的方法。您需要自己读取文件并手动解析。我认为在SDK中使用任何东西都没有快速的解决方案。
答案 3 :(得分:0)