检测音频样本中最大的动态范围变化



原谅/纠正以下任何错误的术语(我希望它有意义!

我想检测给定样本中最大的动态音频变化(即声波"增长"/"加速"最多的时刻(。

例如,如果音频在采样过程中的某些点变得安静,我想知道音乐何时恢复,并按相对动态范围(音量?(增加(从大到小(对这些数据点进行排序。

我的音频样本是float32[]和采样率的缓冲区,我想要一个生成的对象数组,每个对象都包含:

  • 起始帧索引
  • 开始时间(秒...frameIndex/sampleRate
  • 结束帧索引
  • 结束时间(秒(
  • 动态变化值

我的天真方法是线性迭代并检测值开始上升直到不再上升的点,然后计算这些点之间每个子区间的上升......但这并没有产生正确的结果。

有什么想法或现有的算法可以做到这一点吗?

对语言不挑剔,但任何语法如 C#、Java、JavaScript 都是首选!

我有点不确定你有多少音频DSP背景,所以如果踩到旧领域,请道歉。

从本质上讲,这是一个试图在任何给定点找到信号包络的问题。 由于音频信号将在 -1 和 1 之间波动,因此任何单个样本的值都不会产生太多结果 有关响度或动态范围的信息。

最好找到的是信号在某个音频数据帧上的均方根

用伪代码编写,假设您已经拥有音频数据,则获取 rms 数据的函数和方法可能是:

function rms(frame[], frameSize)
{
var rmsValue = 0;
for(int i = 0; i < frameSize; i++)
{
rmsValue += frame[i] * frame[i]; // square the sample and sum over frame
}
rmsValue = sqrt(rmsValue / frameSize);
return rmsValue;
}


// Main
var frameNum = floor(numberOfAudioSample / frameSize) // for analysis just floor to a whole number of frames, if thi is real-time, you will need to deal with a partial frame at the end
var frame = []   // an array or buffer to temporarily store audio data
var rmsData = [] // an array or buffer to store RMS data  
for (var i = 0; i < frameNum; i++)
{
for (var j = 0; j < frameSize; j++)
{
sampleIndex = j + (i * frameSize)
frame[j] = audioData[sampleIndex]
}
rmsData[i] = rms(frame, frameSize)
}

然后,您可以比较 RMS 数据的元素,以了解动态何时变化以及变化幅度。 对于数字音频,RMS 将限制为 0 到 1 之间。要获得dBFS,那么您需要做的就是20 * log10(rmsData)

找到动态范围变化的确切样本将很棘手。帧索引应足够准确,帧大小足够小。 但是,帧越小,RMS 值就越不稳定。以秒为单位找到时间简直是sampleIndex / samplingRate

对于较小的帧尺寸,您可能还希望对 rms 数据进行低通滤波。这取决于这是用于实时应用程序还是非实时分析。

为了方便起见,我会先在Octave或MATLAB中制作原型。

最新更新