我正在尝试确定音频样本的感知音高(仅语音,无背景或音乐),然后将语音识别为低音、男高音、中音、女中音、女高音。
为此,我使用了 aubio,它返回时间码列表和任何给定音频文件的相应频率。
我很难找到如何使用数据来确定音高的最佳方法。我最初的想法要么根本不好,要么执行得不好:
- 我获取 aubio 返回的频率列表并计算如下中位数:
exec('aubiopitch /pathtomp3file/audio.mp3',$output);
// iterate through the time/frequencies returned by aubio
// $output is a list of number pairs (one pair per line):
// The timecode followed by a whitespace followed by the frequency
// at that timecode in hertz.
foreach($output as $sample) {
// extract frequency information
$freq_sample=substr($sample,strpos($sample,' '));
// add frequency to array
$freqs[]=floor($freq_sample);
}
// to calculate median frequency: sort array with frequencies
// and fetch the element in the middle
sort($freqs);
$median=$freqs[floor(count($freqs)/2)];
- 然后我将找到的中值频率映射到“bass”、“baritone”、“tenor”、“alto”等。
不幸的是,结果不一致。很多时候,例如,一个非常深沉的声音的中频太高了。
我相信我尝试确定基频的方式存在缺陷,但我很难想出更好的方法。
例如,会出现以下问题:
我是否应该丢弃任何高于 400hz 的频率,因为它们可能来自诸如“s”之类的声音等?
当人类感知到声音的音高时,我们实际上在听什么?基频?某些频率的能量?
总结它的总体问题是:
“使用 aubio 的数据,计算语音记录(说话,而不是唱歌)的感知音高的正确编程方法是什么?”
编辑——我如何使用 AUBIO
exec('aubiopitch /pathtomp3file/audio.mp3',$output);