Совместите два aud ios с аналогичными деталями. - PullRequest
1 голос
/ 27 мая 2020

У меня есть два трека aud ios, извлеченных из двух видео.

Они звучат почти одинаково, за исключением нескольких отличий.

  • Разная продолжительность. Например, длина первой дорожки составляет 10 минут, а длина второй дорожки - 10,5 минут, потому что она растянута.
  • Первый звук имеет только английский sh голос. Второй звук содержит английский sh + голос на иностранном языке, и вы можете слышать оба, потому что они смешаны как закадровый голос. Другими словами: audio 1 имеет Musi c, Noises, Engli sh Speech ; audio 2 имеет Musi c, Noises, Engli sh Speech, Foreign language speech .
  • Первая и вторая дорожки могут отличаться windows или пропусками. Например, первая дорожка может быть сцена 1, промежуток 1se c, сцена 2, промежуток 1se c, сцена 3, , а вторая дорожка может быть сцена 1, промежуток 2se c, сцена 2, промежуток 2se c, сцена 3.

Интересно, есть ли какие-нибудь решения, которые могли бы выровнять эти две дорожки.

Вот что я пробовал далеко:

  • Cubase 10.5. https://www.youtube.com/watch?v=BGXkHdzjzMg Не работает, если у треков разные голоса.
  • Revoice Pro. Same - не распознает треки с разными голосами. Скорее всего не поддерживает long aud ios.

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Dynami c Time Warping (DTW) - это канонический алгоритм выравнивания последовательностей данных, которые могут иметь небольшие различия в длине / скорости. Библиотека Python librosa содержит краткое руководство по ее использованию для музыки c синхронизация .

В некоторых графических аудиоредакторах также могут быть реализации DTW, но я не знаком с любой.

0 голосов
/ 27 мая 2020

Я бы попытался устранить промежутки тишины между каждой сценой из aud ios, чтобы у вас осталась только пара списков чистых аудиоклипов для каждой сцены.

Тогда я бы воссоздал оба звуковых сигнала. Растянутый сигнал будет иметь промежуток постоянной длины между каждой сценой. Исходный (нерастянутый) сигнал будет иметь переменные промежутки между сценами, равные [length of constant gap] + [length of stretched scene - length of normal scene]. Это заставит каждую сцену начинаться в одно и то же время.

Если промежутки между сценами снижают звуковой сигнал до идеального нулевого уровня, обнаружение и удаление промежутков должно быть тривиальным. , это может быть немного сложно (обычно присутствует некоторый сдвиг D C и / или некоторый фоновый шумовой сигнал, что немного затрудняет обнаружение «тишины» из волнового представления во временной области). Раньше я успешно использовал вычисление энергии acousti c, чтобы точно определить, где начинается / заканчивается звуковой сигнал. Это подразумевает скольжение преобразования Фурье по звуку (обязательно используйте сужающееся преобразование с окном Ханна или Хэмминга). Получив результаты преобразования, вы можете вычислить энергию, выполнив следующие вычисления:

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

Где x идет от 0 до [длина вашего преобразования Фурье] / 2 - 1, r представляет реальную часть каждой ячейки результатов, а i - мнимая часть каждой ячейки результатов.

Это вычисление выполняется многократно при скольжении преобразования Фурье по звуку, в то время как вы записываете энергию по пути. При правильном установлении порога вы, вероятно, могли бы успешно изолировать звуковые части для каждой сцены.

Длина преобразования Фурье может быть небольшой (вероятно, что-то между диапазоном 64-256 будет достаточно , поскольку вам не нужно точное частотное разрешение, а просто оценка общей энергии, присутствующей в определенный момент времени)

Вот пример вызова конического преобразования Фурье ( с использованием fftw3 библиотека ) вычисление энергии в диапазоне частотных диапазонов:

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;
}
...