检测音频样本

时间:2018-06-10 13:03:59

标签: algorithm audio

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

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

例如,如果音频在采样期间的某些点变得安静,我想知道音乐何时回来,并按相对动态范围(音量?)增加(从最大到最小)的顺序对这些数据点进行排序

我的音频样本是float32[]和采样率的缓冲区,我希望得到一个对象数组,每个对象都包含:

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

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

执行此操作的任何想法或现有算法?

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

1 个答案:

答案 0 :(得分:1)

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

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

最好找到的是某些音频数据帧的root mean square信号

以伪代码编写,假设您已经拥有音频数据,获取有效值数据的功能和方法可能是:

   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中对原型进行原型设计