原谅/纠正下面的任何错误术语(我希望它有意义!):
我想检测给定样本中最大的动态音频变化(即声波“增长”/“加速”最多的时刻)。
例如,如果音频在采样期间的某些点变得安静,我想知道音乐何时回来,并按相对动态范围(音量?)增加(从最大到最小)的顺序对这些数据点进行排序
我的音频样本是float32[]
和采样率的缓冲区,我希望得到一个对象数组,每个对象都包含:
frameIndex/sampleRate
?)我的天真方法线性迭代并检测值开始上升的点,直到它不再上升,然后计算这些点之间每个子区间的上升超过...但这不会产生正确的结果。 / p>
执行此操作的任何想法或现有算法?
对语言不挑剔,但任何语法如C#,Java,JavaScript都是首选!
答案 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中对原型进行原型设计