将两个音频的相似部分对齐

问题描述 投票:1回答:2

我有两个音频轨道,从两个视频中提取。

它们听起来几乎一样,除了一些区别。

  • 持续时间不同。例如。第一条轨道的长度为10分钟,第二条轨道的长度为10.5分钟,因为它已拉伸。
  • [第一音频只有英语声音。第二音频包含英语+外语语音,您可以听到这两种声音,因为它们混合为旁白。换句话说:音频1具有音乐,噪声,英语语音;音频2具有音乐,噪音,英语语音,外语语音
  • 第一和第二轨道的窗口或间隙可能不同。例如。第一轨可能是场景1,间隔1秒,场景2,间隔1秒,场景3,第二轨可能是场景1,间隔2秒,场景2,间隔2秒,场景3。

我想知道是否有任何解决方案可以使这两条路线保持一致。

这是我到目前为止尝试过的:

audio-processing
2个回答
0
投票

我会尝试消除两个音频中每个场景之间的静音间隔,以便您仅获得每个场景的一对干净音频片段列表。

然后我将重新创建两个音频信号。拉伸的信号在每个场景之间将具有恒定长度的间隙。原始(未拉伸)信号在场景之间具有可变的间隙,等于[length of constant gap] + [length of stretched scene - length of normal scene]。这将使每个场景都在同一时间开始。

如果场景之间的间隙将音频信号降低到理想的零电平,则检测和消除间隙应该很简单。

否则,这可能会有些棘手(通常会有一些DC偏移和/或某些背景噪声信号,使得从时域波表示中检测“静音”有点困难)。之前,我已成功使用声能计算来精确检测音频信号的开始/结束位置。这意味着沿着音频滑动傅立叶变换(确保使用带有Hann或Hamming窗口的锥形变换)。获得变换结果后,就可以通过执行以下计算来计算能量:

E = Sum(r[x]*r[x] + i[x]*i[x])

x从0到[傅立叶变换的长度] / 2-1,其中r代表每个结果仓的实部,而i代表每个结果仓的虚部。

此计算在沿音频滑动傅立叶变换的同时重复记录,同时沿途记录能量。 通过适当的阈值处理,您可能可以成功隔离每个场景的音频部分。

傅立叶变换的长度可以很小(可能在64-256范围内就足够了,因为您不希望有很好的频率分辨率,只需估算某个时间点上存在的总能量即可)

这是一个锥形傅立叶变换调用(using the fftw3 library)的示例,用于计算频带范围内的能量:

double EnergyAnalyzer::GetEnergy(array<double>^ audioFrame, Int32 startIndex) {
   if( startIndex + FrameSize > audioFrame->Length ) {
      throw gcnew ArgumentException("The value of startIndex would overflow the array's boundary", "startIndex");
   }
   // Prepare input to the fourier transform.  The signal is tapered using a Hann window
   for( int i = 0; i < FrameSize; i++ ) {
      _pIn[i] = audioFrame[startIndex + i] * _hann[i];
   }
   fftw_execute(_fftPlan);
   double energy = 0.0;
   for( int i = _binStart; i <= _binStop; i++ ) {
      energy += _pOut[i][0] * _pOut[i][0] + _pOut[i][1] * _pOut[i][1];
   }
   return energy;
}

0
投票

Dynamic Time Warping(DTW)是用于对齐长度/速度可能略有不同的数据序列的规范算法。 Python库librosa有使用它的简短教程for music syncronization

[某些图形音频编辑器中也可能有DTW实现,但我不熟悉。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.