5

我需要构建一个表示录制文件中的语音级别 (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:这是我最终得到的:

替代文字 http://img22.imageshack.us/img22/5778/waveform.png

4

4 回答 4

9

我只是想帮助其他遇到同样问题并花费大量时间进行搜索的人。为了节省您的时间,我提出了我的答案。我不喜欢这里有人把这当作秘密……

在搜索有关extaudioserviceaudio queueavfoundation的文章后。

我意识到我应该使用 AVFoundation,原因很简单,它是最新的捆绑包,它是 Objective C 但不是 cpp 风格。

所以它的步骤并不复杂:

  1. AVAsset从音频文件创建
  2. avassetreader从创建avasset
  3. 创建avassettrackavasset
  4. 创建avassetreadertrackoutputavassettrack
  5. 添加avassetreadertrackoutput到前面avassetreader开始读出音频数据

avassettrackoutput 中,您可以一个一个地复制NextSampleBuffer(它是一个循环读取所有数据)。

每个copyNextSampleBuffer 都会为您提供一个CMSampleBufferRef,可用于通过CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer获取AudioBufferListAudioBufferListAudioBuffer的数组。AudioBuffer是存储在其mData部分中的一堆音频数据。

您也可以在extAudioService中实现上述内容。但我认为上述avfoundation方法更容易。

那么下一个问题,如何处理mData?请注意,当您获取avassetreadertrackoutput时,您可以指定其输出格式,因此我们指定输出为lpcm

那么最终得到的mData其实就是一个float格式的幅值。

容易吧?虽然我花了很多时间从这里和那里组织这个。

两个有用的共享资源:阅读本文以了解基本术语和概念:https ://www.mikeash.com/pyblog/friday-qa-2012-10-12-obtaining-and-interpreting-audio-data.html

示例代码:https ://github.com/iluvcapra/JHWaveform 您可以直接从该示例中复制上述大部分代码并用于您自己的目的。

于 2014-03-07T02:23:08.567 回答
3

我自己没有使用过,但 Apple 的avTouch iPhone 示例具有由 AVAudioPlayer 提供支持的条形图,您可以轻松查看它们是如何做到的。

于 2009-11-20T00:16:30.790 回答
0

我认为您不能AVAudioPlayer根据自己的限制使用。即使您可以在不实际播放声音文件的情况下让它“启动”,它也只会帮助您以与音频文件流式传输一样快的速度构建图形。您所说的是对声音进行静态分析,这将需要一种截然不同的方法。您需要自己读取文件并手动解析它。我认为没有使用 SDK 中的任何内容的快速解决方案。

于 2009-11-20T02:59:19.737 回答
0

好的,伙计们,似乎我要再次回答我自己的问题:http: //www.supermegaultragroovy.com/blog/2009/10/06/drawing-waveforms/没有很多具体的东西,但至少你会知道什么要阅读的 Apple 文档。

于 2009-11-20T11:48:53.433 回答