Погодите, не тот MP3, ТОТ MP3? Идентификация музыки и аудио…

Грег Дункан

Недавно мы кое-что слышали об идентификации музыки. Где некий сервис или что-то другое смотрит на «дактилоскопические отпечатки» вашей музыки и потом что-то делает с этими данными. Если вы похожи на меня, то удивитесь тому, как снимаются с музыки отпечатки пальцев и как можно самостоятельно сделать нечто подобное. До сих пор я не встречал никаких технических объяснений или примеров кода. Лишь до сих пор…

«Детекторование дублирующихся песен по аудиодактилоскопии

Как специалист по разработке ПО, я всегда интересовался тем, как компьютер может обучиться вести себя разумно, по крайней мере, на некоторых простых задачах, которые мы (человек разумный) легко решаем в доли секунды. Одна из них относится к распознаванию аудио, которая в последние годы была тщательно проанализирована. По этой причине, в статье вам будет предложено введение в одну из самых сложных задач, возникших в области компьютерных наук: эффективное сравнение и распознавание аналоговых сигналов в цифровом формате…

Проще говоря, если вы хотите сравнить аудиофайлы на предмет одинаковости их восприятия, вы должны создать так называемые «отпечатки» (похожие на человеческие отпечатки пальцев, которые однозначно описывают идентичность персоны), и посмотреть, совпадают ли наборы таких объектов, полученных из различных аудиоэлементов. Логически, похожие аудиообъекты должны давать похожие отпечатки, в то время как разные файлы должны производить непохожие сигнатуры. Одно из требований для этих отпечатков заключается в том, что они должны действовать как «прощающие хеши» для того, чтобы справляться с различиями в форматах, шумом, «громкостью» и т. д. Упрощенная концепция аудиоотпечатков представлена ниже.

clip_image002

...

Общая схема (создание отпечатков)

Среда, которую мы собираемся создать (поверх которой будет располагаться завершенная система), будет состоять из нескольких различных концептуальных частей. На следующей картинке, вы можете увидеть диаграмму активности, абстрактно описывающую логическую последовательность создания аудиоотпечатков (эта последовательность соответствует теоретическим абстракциям, представленным в статье ContentFingerprintingUsingWavelets , на основании которой и был построен алгоритм). Далее я опишу более подробно каждых включенный этап и компоненты, ответственные за него.

clip_image004

Предварительная обработка входного сигнала

...

clip_image006

Резюме

Для построения аудиоотпечатка необходимо пройти много шагов, так что несложно потерять связь между ними. Чтобы упростить объяснение, дальше вы увидите обобщенный образ, который поможет представить их все вместе. Это полный пример обработки mp3-файла 44100 Гц, стерео (Prodigy - No Good). Конкретно, последовательность действий такова:

...

clip_image008

MVVM

Приложение, которое будет использовать описываемый алгоритм, предназначено для нахождения повторяющихся аудиофайлов на вашей локальной машине. Главная задача очень проста. Сначала оно обработает все аудиофайлы из заданной папки, а затем постарается выяснить, какие из них соответствуют одинаковой сигнатуре, таким образом – дублируют друг друга. Приложение будет создано с использованием технологии WPF, и конкретно – шаблона MVVM, которая становится все более популярной в связи с расширением последнего. Архитектурный шаблон Model``-``View``-``ViewModel`` ( ``MVVM`` ) используется в разработке ПО и происходит от Mirosoft, как специализация шаблона PresentationModel , введенного Мартином Фоулером ( MartinFowler ). Шаблон MVVM был разработан, чтобы воспользоваться специальными функциями WPF , способствующими лучшему отделению разработки слоя View от остального шаблона путем виртуального удаления всего «позади стоящего кода» из слоя View . Элементы шаблона MVVM включают:

…»

И это лишь кусочек. Всего в статье 18 печатных страниц…(Да, круто!)

Давайте посмотрим на это в действии.

Примечание: Когда будете скачивать Sources.zip прихватите также и Binaries.zip.

В binaries.zip есть одна DLL, которая понадобиться, и которой нет в Sources.zip (Bass.Net.DLL). Итак, разархивируйте Sources, вытащите the Bass.Net.DLL из binaries.zip и поместите ее каталог DuplicateTracks\NativeLibs\ и, если надо, исправьте проект так, чтобы он ссылался на нее. После этого проект прекрасно компилируется и запускается (по крайней мере, на моей машине).

Когда вы запустите приложение, выберите каталог (или файлы) и нажмите «Start».

clip_image010

Программа обработает файлы и выдаст результаты.

clip_image012

Большое дело, скажите вы, скорее всего это делается, используя размер файла или контрольную сумму MD5? Давайте взглянем на свойства этих двух файлов…clip_image014

Принимая во внимание, что размеры файлов различны, есть минимальный шанс, что стандартная хеш-функция MD5, или любая другая, даст одинаковые значения. Короче, похоже, проект работает именно так, как и рекламировалось! И у нас есть все исходные коды к нему… clip_image016

clip_image018

Как видно, проект содержит достаточно кода, не только относящегося к аудиообработке, но и того, где автор «делает всё» и переводит решение в MVVM. Некоторые могут назвать это перегибом, но я по-прежнему думаю, что это здорово

Как бы то ни было...

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

 public List<bool[]> CreateFingerprints(IAudio proxy, string filename, IStride stride, int milliseconds, int startmilliseconds)
  {
      float[][] spectrum = CreateLogSpectrogram(proxy, filename, milliseconds, startmilliseconds);
      int fingerprintLength = FingerprintLength;
      int overlap = Overlap;
      int logbins = LogBins;
      int start = stride.GetFirstStride()/overlap;
      List<bool[]> fingerprints = new List<bool[]>();

      int width = spectrum.GetLength(0);
      while (start + fingerprintLength < width)
      {
          float[][] frames = new float[fingerprintLength][];
          for (int i = 0; i < fingerprintLength; i++)
          {
              frames[i] = new float[logbins];
              Array.Copy(spectrum[start + i], frames[i], logbins);
          }
          start += fingerprintLength + stride.GetStride()/overlap;
          WaveletDecomposition.DecomposeImageInPlace(frames); /*Compute wavelets*/
 bool[] image = ExtractTopWavelets(frames);
          fingerprints.Add(image);
      }
      return fingerprints;
  }

Если ваше дело – аудио, аудиообработка, управление MP3-файлами, или вам просто нравится снимать звуковые отпечатки и нравится смотреть, как это делается, тогда эта статья и код должны быть вами прочитаны.