我有一个小型的karaoke风格的应用程序,用户在其中唱歌4行,每行之间有一秒的间隔。没有背景音乐,所以只有声音,希望可以使问题更容易解决。

我正在寻找最可靠的方法来准确检测用户在录音中开始和结束第1条歌声的起点和终点,等等。

我拼凑了一个思路简单的算法,该算法可以在录音中的背景噪音很小时起作用(例如什么时候发生?),但是在出现最小噪音的情况下会崩溃。

有人能指出我更强大的东西吗?

评论

我的答案可能会帮助您-dsp.stackexchange.com/a/1543/440

在某些录音中,语音是唯一在两个通道中以相同幅度播放的乐器。您可以使用此信息从立体声录音中提取语音。

#1 楼

如果背景噪声为白色,则可以测量频谱平坦度,并在幅度高于某个阈值且频谱平坦度低于某个阈值时将其视为语音。

基本上,您只需进行FFT信号的一部分,然后将频谱幅度的几何平均值除以算术平均值。

您还可以使用带通滤波器来仅强调人声的频率区域通常位于(只需在测量频谱平坦度之前将FFT的不需要区域设置为0)

评论


$ \ begingroup $
根据您的经验,Endolith如果在测量光谱平坦度之前仅取幅度平方VS与幅度成正比,会有很大的不同吗?
$ \ endgroup $
–太空
2012年5月15日18:42

$ \ begingroup $
@Mohammad:我没有任何经验。 :)我问了一个先前的问题,因为我不了解该规范,并且仍然不确定哪种方法正确。不过,我认为平方不具有任何实际意义。如果您只是在超过阈值时触发,则无论平方与否,它都应做出相同的反应(假设您调整阈值以使其匹配),因此仅幅度在计算上更便宜。
$ \ endgroup $
– Endolith
2012年5月16日14:04



$ \ begingroup $
@Endolith,这有点远:您知道如何在matlab中实现这种方法吗?我想测试一下在matlab(实际上是八度)中提到的所有方法,看看哪种方法最好?
$ \ endgroup $
–迈克·霍根(Mike Hogan)
2012年6月4日下午4:56

$ \ begingroup $
@MikeHogan:不,我已经很长时间没有使用过matlab了。 :/同样,这需要做真实的工作。 :)我没有任何预先写好的东西。将信号分成小块,进行每个FFT,然后对每个FFT,将幅度的几何平均值除以幅度的算术平均值。较高的数字嘈杂,较低的数字为音调。
$ \ endgroup $
– Endolith
2012年6月4日13:55



#2 楼

我过去曾经使用过光谱通量,它似乎工作得很好。基本思想是,在您关心的频段上创建信号的频谱图。让我们假设您的频率在y轴上,您的时间在x轴上,就像这样。

这意味着您的频谱图是一个矩阵。每列代表信号一次快照的FFT的FFT绝对值,每一行代表一个频段的能量随时间变化的方式。

现在,只需考虑不同的列。也就是说,取一列,并从其自身减去前一列,然后对所有列进行计算。 (显然,不要将开始列放在首位)。然后汇总所有频段。也就是说,将所有行加在一起。

您最终将获得一维信号,可将您的信号开始进行编码。这将告诉您声音的开始位置。

编辑:

现在,您已经检测到发作,如果要检测相反的情况(即,当信号从有活动变为无活动时),频谱通量实际上会为您提供该信息。无论在何处发作,都会有一个正峰,而在任何“偏位”(因为缺少更好的单词)都会有一个负峰。

我只用第一个正峰值和最后一个负峰值来标记信号的总起止时间。

评论


$ \ begingroup $
穆罕默德,“行”是什么意思?
$ \ endgroup $
–迈克·霍根(Mike Hogan)
2012年5月15日15:49

$ \ begingroup $
@MikeHogan请查看我的修改,我重新写下了答案。
$ \ endgroup $
–太空
2012年5月15日16:14

$ \ begingroup $
但是,这找不到任何发作吗?还会检测到鼓声敲击或其他脉冲噪声。它无法区分音调和嘈杂的声音。
$ \ endgroup $
– Endolith
2012年5月16日下午14:17

$ \ begingroup $
@endolith您提出了一个很好的观点-但是我相信它可能仍然有效。我的推理是,在这种情况下,您处于语音+音乐状态,或者仅处于音乐状态。因此,在计算频谱通量时,您实际上只是在计算语音+音乐与音乐之间的增量。 (当然,我需要对其进行更多分析,但这就是我现在的看法):-P
$ \ endgroup $
–太空
2012年5月16日在18:28

$ \ begingroup $
@endolith我刚刚重新阅读,OP表示只有声音,(显然它是一个简单的应用程序),因此在这种情况下,声音就是VS没有声音。
$ \ endgroup $
–太空
2012年5月16日18:40

#3 楼

根据我的经验,我会尝试研究梅尔频率倒谱系数(MFCC)。如果有FFT,MFCC相当容易实现,并且在语音处理中非常普遍。

使用MFCC,您应该能够将实际的语音数据与噪声区分开。

评论


$ \ begingroup $
@endolith,该链接完全超出了我!您是否知道我能看到的任何开放源代码实现,或更详细地逐步了解它的工作原理?
$ \ endgroup $
–迈克·霍根(Mike Hogan)
2012年5月29日7:42

#4 楼

“谱通量”(也称为“谱差”)是“发作检测”的常用方法。基本上,您需要对信号进行顺序FFT,然后对一个采样点到下一个采样点的FFT桶差异的大小求和。 “开始”通常用此值中的一个实质性“跳跃”来表示。

Google的“开始检测”用于其他想法。

#5 楼

单独使用频谱通量可能会对某些噪声产生误报,并检测到歌声。

唱歌通常意味着信号内容包含音高,因此可以使用音高检测器或估计器(倒谱等) )。您可以理智地检查被检测为音调的能量与总信号能量之比,以及估计的音调是否在人类语音范围内。这样可以减少未加急的噪音以及正常人声范围之外的音乐声音的误报率。