MPEG 2 и 2.5 - проблемы с вычислением размера кадра в байтах

У меня есть консольная программа, которую я использую в течение многих лет (среди прочего) для отображения информации об определенных форматах аудиофайлов, включая mp3. Я использовал данные с сайта mpegdr для расчета размеров кадров, чтобы в дальнейшем рассчитать время воспроизведения треков. Уравнение, которое я получил от mpegdr, было:

// Read the BitRate, SampleRate and Padding of the frame header. 
// For Layer I files use this formula: 
// 
//     FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4 
// 
// For Layer II & III files use this formula: 
// 
//     FrameLengthInBytes = 144 * BitRate / SampleRate + Padding 

Это хорошо работает для большинства mp3-файлов, но всегда было небольшое подмножество, для которого это уравнение не сработало. Недавно я просматривал набор очень маленьких mp3-файлов и обнаружил, что для этих файлов эта формула терпит неудачу намного чаще, поэтому я пытаюсь, наконец, понять, что происходит. . Все эти mp3-файлы были сгенерированы с помощью Lame V3.100 с настройками по умолчанию в 64-разрядной версии Windows 7.

Во всех случаях я могу успешно найти заголовок первого фрейма, но когда я использовал приведенную выше формулу для вычисления смещения до следующего заголовка фрейма, иногда это неверно.

В качестве примера у меня есть файл «волчий вой.mp3»; аналитические файлы, такие как MPEGAudioInfo, показывают размер кадра как 288 байт. Однако когда я запускаю свою программу, она показывает длину первого кадра как 576 байт (2 * 288). Когда я смотрю на файл mp3 в шестнадцатеричном редакторе с первым кадром в 0x154, я вижу, что следующий кадр имеет размер 0x154 + 208 байт, но этот расчет действительно фактически дает 576 байт. ..

File info:
mpegV2.5, layer III

frame: bitrate=32, sample_rate=8000, pad=0, bytes=576
mtemp->frame_length_in_bytes =
   (144 * (mtemp->bitrate * 1000) / mtemp->sample_rate) + mtemp->padding_bit;
which equals 576

Я просмотрел множество других ссылок, и все они показывают это уравнение ... Сначала я подумал, что это проблема с MPEG 2.5, который является неофициальным стандартом, но я также видел это с файлами MPEG2. Однако происходит только с небольшими файлами.

У кого-нибудь есть идеи о том, что мне здесь не хватает ??

//**************************************

Более поздние примечания:

Я подумал, что, возможно, аудиоформат будет иметь отношение к этой проблеме, поэтому я выгрузил channel_mode и mode_extension для каждого из моих тестовых файлов (3 рассчитываются правильно, 2 нет). К сожалению, все они cmode=3, mode_ext=0 (т.е. последний байт заголовка 0xC4)... так что это не помогает...


person Gorlash    schedule 23.06.2020    source источник


Ответы (1)


Хорошо, я нашел ответ на этот вопрос... он был в программе MPEGAudioInfo на сайте CodeProject. Вот жизненно важный ключ:

//*************************************************************************************
//  This reference data is from MPEGAudioInfo app
// Samples per Frame / 8
static const u32 m_dwCoefficients[2][3] =
{
   {  // MPEG 1
      12,   // Layer1   (must be multiplied with 4, because of slot size)
      144,  // Layer2
      144   // Layer3
   },
   {  // MPEG 2, 2.5
      12,   // Layer1   (must be multiplied with 4, because of slot size)
      144,  // Layer2
      72    // Layer3
   }  
};

К сожалению, ни одна из справочных страниц не упоминает эту деталь !! Теперь моя программа успешно вычисляет размеры кадров для всех моих mp3-файлов, включая маленькие.

person Gorlash    schedule 23.06.2020