Hi [some silence] My name is Bob [some silence] How are you?
然后我想从中制作三个音频剪辑。一个说
Hi
,一个说My name is Bob
,一个说How are you?
。 我最初的想法是通过音频缓冲区不断检查是否存在低振幅区域。也许我可以通过获取前十个样本来进行此操作,取平均值,如果结果较低,则将其标记为无声。我将通过检查接下来的十个样本来继续处理缓冲区。以这种方式递增,我可以检测到信封的开始和停止位置。
如果有人对好的,简单的方法有任何建议,那就太好了。就我的目的而言,该解决方案可能非常初级。
我不是DSP的专业人士,但了解一些基本概念。另外,我将以编程方式进行此操作,因此最好讨论算法和数字样本。
感谢您提供的所有帮助!只是想澄清一下,这不是实时音频,我将自己用C或Objective-C编写算法,因此使用库的任何解决方案都不是真正的选择。
#1 楼
这是语音检测的经典问题。首先要做的就是使用Google的概念。它广泛用于数字通信中,并且对此主题进行了大量研究,并且那里有很好的论文。通常,您需要处理的背景噪声越多,您的方法就越复杂。必须进行语音检测。如果您使用的是在安静的房间中拍摄的录音,则可以轻松完成(以后再做)。如果您在说话时有各种各样的声音(卡车经过,狗叫,碎片砸碎,外星人发动攻击),则必须使用更巧妙的方法。附件,您的噪音很小,所以我建议:
提取信号包络
选择一个好的阈值
检测包络幅度超过阈值的地方
这是什么意思?信号的包络是描述其幅度随时间变化的曲线,而与信号的频率成分如何振荡无关(请参见下图)。
包络提取可以通过创建一个包含原始信号绝对值的新信号来完成,例如$ \ {1,45,-6,2,-43,2 \ ldots \} $变成$ \ {1,45,6,2,43,2 \ ldots \} $,然后对结果进行低通滤波。最简单的低通滤波器可以通过用两侧的N个邻居的平均值替换每个样本值来实现。 N的最佳值可以通过实验找到,并取决于诸如采样率之类的几件事。
从图像中可以看出,您没有太多的噪声,信号包络将始终高于某个阈值(响度级别),您可以将这些区域视为语音检测区域。
评论
$ \ begingroup $
我实际上已经将它实现为good'ol winamp的插件之一。您所描述的是好的,但还不够。通常有浊音(元音)和清音(辅音)。如果只有语音声音,那么您所描述的内容就可以使用-但非语音声音的能量非常低,与一般的噪音很难区分开。而且即使在演播室中,无噪音条件也非常罕见。
$ \ endgroup $
– Dipan Mehta
2012年2月22日15:51
$ \ begingroup $
如何在python中实现呢?
$ \ endgroup $
–kRazzy R
17年12月14日在20:39
#2 楼
实际上,您真正想要做的是称为“语音活动检测”或“语音检测”。基本上任何纯语音信号(不包含音乐)都包含三个部分。
有声声音-基本上是由元音引起的
无声声音-包含辅音。
人类声音的特征是,尽管浊音中使用了大量能量,但真实信息却包含在辅音中。同样,浊音通常是较低的频率,而清浊音是较高的频率。 [确切地说,对于给定的人,所有声音都或多或少地以恒定频率共振,这是他/她的音调。]
现在,任何系统都存在噪音。浊音通常足够强大,可以将其清晰可见。当您应用较低频率的过滤时,可能会收集到足够数量的浊音,但是清音(包含所有丰富的信息)将会丢失。
提出问题的解决方法:
诀窍在于,清音仍然来自共振源。并固有地限制在一定的频率上。那里,噪音是相当均匀的。因此,区分这三个指标的简单方法是“局部功率”,或者等效但等效的方法是采用窗口自相关。
如果您一次要说100个样本-并自动进行自我关联,则如果仅包含噪声,则结果将几乎为零(这是白噪声的属性),对于语音信号因为信号仍然具有更好的结构,所以可以观察到该幅度。过去这对我有用。
VAD一直是活跃的研究领域-因为几乎所有的移动电话通信都希望检测非语音部分并将其从编码中删除。但是,如果他们删除无声音的语音,这将使电话无用。
G.729标准基于以下特性计算VAD:线频谱频率,全频带能量,低频带能量(<1 kHz)和过零率。
GSM标准的工作原理如下所示:选项1计算9个频段中的SNR,并将阈值应用于这些值。选项2计算不同的参数:信道功率,语音度量和噪声功率。然后,它使用根据估计的SNR变化的阈值对语音指标进行阈值设置。 (来自维基百科)
有关更高级的技术,我在此列出了一些参考资料。
最常用的参考文献:Jongseo Sohn;南秀金; Wonyong Sung; “基于统计模型的语音活动检测”,信号处理快报,IEEE,1999年1月,第6期:1页:1-3
与您最相关:Mark Marzinzik和Birger Kollmeier“语音暂停检测噪声通过跟踪功率包络动力学进行频谱估计”,IEEE语音和音频处理事务,卷。 10号2002年2月2日,第109页
Ramírez,J .; J.M.Górriz,J.C。Segura(2007)。 “语音活动检测。基本原理和语音识别系统的鲁棒性”。在M. Grimm和K. Kroschel中。强大的语音识别和理解能力。 1-22页。 ISBN 978-3-902613-08-0。
简介:Jonathan Kola,Carol Espy-Wilson和Tarun Pruthi“语音活动检测”
评论
$ \ begingroup $
如何在python中实现呢?
$ \ endgroup $
–kRazzy R
17年12月14日20:40在
#3 楼
我完全同意吉姆·克莱(Jim Clay)的观点,但是使用包络线会稍微改变其口味:我们知道语音主要出现在1-2kHz左右。您的数据采样可能是44kHz(这取决于您的记录设备)。因此,我首先要做的是在10个点上实时对平方信号进行移动平均,以得到信号功率的包络线。这会导致检测延迟,因此您希望将其保持在较低水平。
然后,我将在您的系统上添加一个校准阶段:要求用户保持沉默,按下按钮并进行记录假设背景噪音为10秒。取包络线的均值或中值幅度乘以2即可得到安全,这将自动为您提供Jim一直在谈论的阈值。
如果不是实时记录,您可能会发现使用0相移动平均值来减少由延迟引起的烦恼是有用的。告诉我们它是否对您有效。
#4 楼
埃里克(Eric),如果您真心想要快速又肮脏的东西,那么您首先需要得到的就是信封,我可以通过以下方式(在MATLAB中)简单地执行此操作: >
envelope = abs(hilbert(yourSignal));
此时,我只是简单地设定阈值,如果您超过某个阈值,则“声音存在”。
顺便说一句,这是一个非常简单的解决方案,但它可能对您有用。
评论
$ \ begingroup $
+1。也许您可以详细说明此代码行背后的方法?我确定OP对通过希尔伯特变换进行包络提取不熟悉。
$ \ endgroup $
– Phonon
2012-2-21在17:16
$ \ begingroup $
@Mohammad谢谢!但是,请参阅我的编辑1。我绝对希望快速又肮脏,但是我也需要自己做算法:)
$ \ endgroup $
–埃里克·布鲁克托(Eric Brotto)
2012年2月21日在17:19
$ \ begingroup $
@EricBrotto好的,我可以告诉您如何实现希尔伯特转换器,但是我假设您具有在C / Obj-C库中执行FFT的能力?如果不是这样,那将是一个问题... :-)
$ \ endgroup $
–太空
2012年2月21日17:59
$ \ begingroup $
如何在python中实现呢?
$ \ endgroup $
–kRazzy R
17年12月14日20:40在
$ \ begingroup $
亲爱的先生/女士,您能为我提供有关如何在Python中实现该希尔伯特的资源吗?
$ \ endgroup $
–kRazzy R
17年12月19日在4:38
#5 楼
我假设您正在处理的是真实的而不是复杂的信号-如果不是这种情况,请告诉我,我可以修改答案。信号样本乘以自己)。您可以将功率与某个阈值进行比较,以确定是否存在语音。您可能需要对录音进行一些测量以凭经验找到一个好的阈值。如果您的录音是“干净的”(即没有太多噪音),我可能会通过比较来简化瞬时功率(即单个样本)达到阈值。这意味着,即使您不想对它进行平方,也只需要绝对值并将其与功率阈值的平方根进行比较即可。当您检测到语音时,请抓住它并进行一定数量的录音,以确保获得全部语音(可能是1/10秒)。继续进行直到发现没有样品超过阈值的长时间为止。同样,需要根据经验确定周期的长度。
冲洗并重复。
#6 楼
我已经用Java编写了一个活动检测器类。这是我的开源Java DSP集合的一部分。您可以使用测试程序WavSplitter.java以WAV文件作为输入将其检出。评论
$ \ begingroup $
请记住,OP特别指出,他需要自己用C编写算法。
$ \ endgroup $
–山姆·马洛尼(Sam Maloney)
13年8月29日在18:05
$ \ begingroup $
将此类算法从Java转换为C非常容易。
$ \ endgroup $
–克里斯蒂安·德·赫里乌斯(Christian d'Heureuse)
13年8月31日在13:02
$ \ begingroup $
先生,如何在python中实现呢?
$ \ endgroup $
–kRazzy R
17年12月14日在20:41
评论
听起来您正在尝试使用无声的时间作为中断点。为什么不只使用功率阈值确定“沉默”,又有阈值时间来确定是否足够长以构成中断?@JimClay是的,这正是我想要做的。我从未听说过功率阈值,但这听起来像是我可以使用的东西。复杂吗?您能对此进行扩展吗?
@EricBrotto也许您应该向我们介绍一下您的库中具有哪些功能。这将使我们能够更好地为您按摩实际方法。
这种沉默检测的方法更好?应将阈值级别设置为0.05 x = wavread('s1.wav')以外的值; i = 1;而abs(x(i))<0.05%沉默检测i = i + 1;结束x(1:i)= []; x(6000:10000)= 0;