【问题标题】:Timing in C# real time audio analysisC# 实时音频分析中的时序
【发布时间】:2010-11-18 18:25:08
【问题描述】:

我正在尝试从 C# 中的实时音频中确定“每分钟节拍数”。我发现的不是音乐,只是持续不断的敲击声。我的问题是确定这些点击之间的时间,以便我可以确定“每分钟的点击次数”我曾尝试使用 WaveIn.cs 类,但我并不真正了解它的采样方式。我一秒钟没有得到一定数量的样本来分析。我想我真的只是不知道如何在一秒钟内读取确切数量的样本来了解样本之间的时间。

如果能帮助我找到正确的方向,我们将不胜感激。

【问题讨论】:

    标签: c# sampling audio-processing


    【解决方案1】:

    我认为您可能会将示例与“水龙头”混淆。

    样本是一个数字,表示给定时刻声波的高度。一个典型的波形文件可能每秒采样 44,100 次,因此如果您有两个立体声通道,则每秒有 88,200 个 16 位数字(样本)。

    如果你把所有这些数字都画出来,你会得到这样的结果:


    (来源:vbaccelerator.com

    What you are looking for is this peak ------------^
    

    那是水龙头。

    【讨论】:

      【解决方案2】:

      假设我们讨论的是同一个 WaveIn.cs,WaveLib.WaveInRecorder 的构造函数将 WaveLib.WaveFormat 对象作为参数。这允许您设置音频格式,即。采样率,位深度等。只需扫描音频样本的峰值,或者您正在检测“轻拍”并记录峰值之间样本的平均距离。

      既然您知道音频流的采样率(例如 44100 个样本/秒),请取平均峰值距离(以样本为单位),乘以 1/(采样率)以获得两次轻击之间的时间(以秒为单位) ,除以 60 得到点击之间的时间(以分钟为单位),然后反转得到每分钟的点击次数。

      希望有帮助

      【讨论】:

        【解决方案3】:

        我不确定您使用的是哪个 WaveIn.cs 类,但通常使用录制音频的代码,您要么 A) 告诉代码开始录制,然后在稍后的某个时间告诉代码停止,你会得到一个数组(通常是 short[] 类型),其中包含在此时间段内记录的数据;或 B) 告诉代码以给定的缓冲区大小开始记录,并且当每个缓冲区都被填充时,代码会回调到您定义的方法,并引用已填充的缓冲区,并且此过程将继续进行,直到您告诉它停止录制。

        假设您的录制格式是每个样本 16 位(也就是 2 字节),每秒 44100 个样本,单声道(1 个通道)。在 (A) 的情况下,假设您开始录制,然后在 10 秒后停止录制。您最终将得到一个长度为 441,000 (44,100 x 10) 个元素的 short[] 数组。我不知道您使用什么算法来检测“抽头”,但假设您在此数组中的元素 0、元素 22,050、元素 44,100、元素 66,150 等处检测抽头。这意味着您正在查找每个 . 5 秒(因为 22,050 是每秒 44,100 个样本的一半),这意味着您每秒有 2 次敲击,因此是 120 BPM。

        在 (B) 的情况下,假设您以 44,100 个样本(即 1 秒)的固定缓冲区大小开始录制。随着每个缓冲区的进入,您会在元素 0 和元素 22,050 处找到抽头。按照与上述相同的逻辑,您将计算出 120 BPM。

        希望这会有所帮助。一般来说,对于节拍检测,最好记录相对较长的时间,并通过大量数据来计算节拍。试图估计“瞬时”速度更困难,也更容易出错,就像实时估计录音的音高比录制完整的音符更难。

        【讨论】:

        • 所以如果我做单声道,我数组中的每个数字都代表一个通道的一个样本?如果我要做 2 个通道,那么我的阵列的大小会是 88200 吗?在频道之间交替?
        • 是的,立体声意味着你每秒有两倍的样本,并且样本是交错的(左、右、左、右等),所以元素 0、2、4、6 等代表左声道数据,元素1、3、5、7等代表右声道数据。
        • 另一个问题:当我对此进行 fft 以获得振幅时,它返回原始数组大小的一半。根据我的阅读,这是因为它将其转换为实部和虚部,并使用这两者来获得幅度。这个数组中的每个值现在说明了什么? 2 个样本?
        • 这取决于您使用什么代码来执行 FFT。对于音频 DSP,FFT 函数通常采用两个数组,1 个用于实部,1 个用于虚部。在 FFT 之前,实数数组包含记录的样本值,虚数数组全为零。转换后,两个数组的大小与以前相同,但现在都包含不同的非零值。无论您使用什么代码,都可能将这两个转换后的数组组合成一个包含频率分量的半尺寸数组。续...
        • 此数组中的值现在包含通常称为频率“bin”的内容,其中每个 bin 中的数字表示该范围内频率分量的幅度。例如,如果您的原始音频为 44100 Hz(普通 CD 音频)并且您的幅度数组大小为 1000 个元素,那么每个 bin 代表原始音频的 44.1 Hz 片段的幅度。所以 element[0] 中的值表示 0 到 44.1 Hz 的频率响应,element[1] 中的值表示 44.1 到 88.2Hz 的幅度,element[2] 是 88.2 到 132.3 Hz 等等。
        猜你喜欢
        • 2010-10-16
        • 2022-01-17
        • 2011-11-16
        • 2012-04-08
        • 2020-08-05
        • 2017-04-24
        • 2013-08-20
        • 2015-12-09
        • 2016-03-14
        相关资源
        最近更新 更多