LINUX.ORG.RU

Меня доконала эта помойка (*.mp3)

 , ,


1

3

Для всех:

Если ты не работал руками (апи либ не в счет) с *.mp3 форматом — проходи мимо. Однако, если будет нормальная мысль - я весь внимание.

Для тех кто «в теме»:

Всякие ID3, LYRICS, AiD и прочую шелуху я скипнул.

И вот, парсю mp3-фреймы. Если ориентироваться на позиции sync-word-ов (ессно проверяю и все остальные данные в этих 4-х чарах) найденных в файле, то, можно вычислить размер каждого фрейма. Ага, я то вычисляю, но, эти размеры, а равно и их позиции, а равно и общее кол-во фреймов, не совпадает с тем кол-вом фреймов найденных libmp3lime (mad я пока не пробовал, надо будет поковырять).

Есь такая формула:

if (!header->layer) {
    header->frame_size = (size_t) (((12000 * header->bitrate / header->samplerate) + header->padding_bit) * 4);
} else {
    header->frame_size = (size_t) ((144000 * header->bitrate / header->samplerate) + header->padding_bit);
}

Но она выдает размеры (300-8000 байт) не равные ни тому что я напарсил по синк-вордам, ни тому что напарсил libmp3lime.

А вот еще интересно, libmp3lime имеет в своем апи ф-цию «hip_decode1()» она, как написано, должна принимать на вход ОДИН мп3-фрейм, но, эксперименты дали понять, что ей вообще похер, что ты туда пихаешь, лишь бы не менее ~1200 байт, т.е. читай из файла и все.

Но мне то надо обрыскать весь файл и узнать точное число RAW-PCM фреймов закодированных в мп3.

Недавно видел тут в новостях про какой-то плеер чот тип того: «более-точное определение длительности мп3-трека», я смотрю, не один я с этой херней совладать не могу )))

UPD: А, да, кратко по проблеме. Кто подскажет где скопипастить:

1) правильную формулу вычисления длины мп3-фрейма. 2) правильный алгоритм выпарса и валидации этих самых фреймов.

Либы? Либы я копаю, и даже несколько великов нашел на гитхабе. Но там либо помойка, костыли и говнокод, либо поддержка одного лайера.

★★★★★

Последнее исправление: deep-purple (всего исправлений: 1)

«более-точное определение длительности мп3-трека», я смотрю, не один я с этой херней совладать не могу )))

Не, это про теги. Обычно декодеру для вычисления длины трека нужно передать заголовок (первые несколько кб) и сообщить длину файла. А фишка в том, что в файле могут быть теги. Причем, как в начале, так и в конце. Причем по несколько штук, даже однотипных (!!!). Я когда такое у себя фиксил (делал embedded-плеер по работе), то увидел, что даже WMP неправильно считает длину - все из-за тегов.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Нет, тут суть что я не ориентируюсь на инфу в тегах, я вообще их типа проигнорил и все. Т.е. если даже вырезать все теги и оставить тока мп3-фреймы - ТРИ (синк-ворды, формула и лайм) алгоритма выдают разные результаты. Ну лайм понятно - что-то там усредняет или проверяет совпадения по синкам и формуле.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от Pavval

первые несколько кб

Самый первый фрейм (актуально для VBR) содержит Xing/VBRI заголовок в котором написано общее кол-во фреймов и закодированных в них PCM.

А еще есь free-формат, это когда битрейт равен нулю )) Тогда надо декодировать этот фрейм чтоб узнать битрейты и прочие..

Ну и самый обычный вариант - ищем первый фрейм, если он не VBR и не free, тогда берем оттуда битрейты и режимы, берем общий размер полезных данных в файле и узнаем длительность.

В общих чертах как-то так.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от ee1337a

Есть такое слово «надо». Вот надо проиндексировать файл и корректно определить его длительность. Ибо узнавать точную длительность через полное декодирование - это жесть. Тем более, как я уже говорил, и выше писали - декодер декодеру рознь.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Ну насчёт «надо» (в гдобальном контексте, а не только про декодеры) я бы поспорил, но мне лень.

Есть ведь уже реализации. Почему бы не подглядеть?

ee1337a
()
Ответ на: комментарий от ee1337a

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от ee1337a

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от redhat

Не сцы, до флака я еще доберусь, а щас надо мп3 разгребсти.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Тем более, как я уже говорил, и выше писали - декодер декодеру рознь.

Ну теги вырезать - задача конкретного софта, а не декодера. Декодер работает с чистыми данными, а не с какими-то тегами, которые к mp3 не имеют отношения. Да, пропускать их он умеет, вот только длину неправильно определит. Проверено на каноничном Fraunhofer.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Яж написал в старте:

Всякие ID3, LYRICS, AiD и прочую шелуху я скипнул

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Вот надо проиндексировать файл и корректно определить его длительность.

А что мешает взять любой декодер и скормить ему?

Ибо узнавать точную длительность через полное декодирование - это жесть.

Вот не поверю, что декодеру потребуется весь файл сканить.

Не догоняю, зачем ты этим занимаешься.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Вот не поверю, что декодеру потребуется весь файл сканить

Вот это надо уточнить. Либо ты плохо знаешь, либо я.

Но я тебе скажу, что сканить надо весь файл (полезные данные посрединке, где уже не теги). Да, декодировать не обязательно, т.к. чаще вся инфа лежит в тех 4-х чарах в начале каждого фрейма, но бежать по всему файлу придется.

Я вот и, чтобы не бегать дважды и более раз, собираю найденные позиции и размеры фреймов в индекс-массив. Теоретически (да и практически, но сейчас с артефактами) - этот hip_decode1() воспроизводит с любого места в треке, я просто скармливаю нужные куски из файла.

Не догоняю, зачем ты этим занимаешься

Ну, во первых - мне интересно работать со звуком. Во вторых, прожка уже работает, хотя делов там еще и много. Надо доделать, не бросать же. Хочу подарить опенсорсу, кому-то может будет нужным.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Вот это надо уточнить. Либо ты плохо знаешь, либо я.

Я опираюсь на офф. доки Fraunhofer (mp3senc API). Если авторы формата говорят, что достаточно - знач достаточно.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Ну ты же видишь, мне надо не просто скормить декодеру, чтоб все за меня сделали. Я собираю индекс чтобы сикать по фреймам можно было. Почему не сразу распаковать трек в память? Ну прикинь будет какой-нить подкаст на часа четыре длинной. Этж сколько он места займет в распакованном виде? А сколько времени будет декодироваться полностью?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Не, это только копание в тегах. Я не нашел про сами фреймы. Ткни носом в место на странице.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)

Но разве не для этого придумали ТЕГИ? А вообще, не вижу смысла заморачиваться, единственное, время всех файлов получается от части выдуманное во всех моих раздачах с музыкой, но кого это беспокоит? Явно не меня.

з.ы. немного оффтопика: что делать, если не можешь спать больше 2-3 часов в сутки? это… мало, хотелось бы 5-6…

wakuwaku ★★★★
()
Последнее исправление: wakuwaku (всего исправлений: 2)
Ответ на: комментарий от wakuwaku

что делать, если не можешь спать больше 2-3 часов в сутки? это… мало, хотелось бы 5-6…

Занимай себя физ. упражнениями, но качественно так - спать будет хотется.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

ХМ! У меня не очень получается почему-то, надо попробовать большие нагрузки. Симптомы и проявления депривации сна не слишком приятные на самом деле, в лучшем случае, ощущение будто перманентно под веществами.

wakuwaku ★★★★
()
Ответ на: комментарий от wakuwaku

Но разве не для этого придумали ТЕГИ?

Оу, да ты не в курсе за длительность трека в тегах (в некоторых даже и не предусмотрено такое), не факт что её туда впишет утилита, которая этот трек запиливала. Просветись хоть поверхностно: https://ru.wikipedia.org/wiki/ID3_(метаданные)

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Бжє кто в наше время слушает mp3, это ведь то же самое что слушать кассетник! Мне казалось, APE умеет. В крайнем случае можно проанализировать файл и вписать самому, наверное.

wakuwaku ★★★★
()
Последнее исправление: wakuwaku (всего исправлений: 1)
Ответ на: комментарий от wakuwaku

Ты не поверишь - многие до сих слушают. Ну и еще прикинь ситуацию:

- А шэ, ваша прагырама не умеит эм-эр-зэ? - Нет. - Фууу...

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Тогда я не представляю, зачем ещё может потребоваться абсолютно точная продолжительность трека, я обычно удовлетворяюсь тем, что мне возвращает та или иная либа.

wakuwaku ★★★★
()
Ответ на: комментарий от wakuwaku

Тогда я не представляю

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

не надо

хорошо, но тогда меня беспокоит, почему я наблюдаю проблемы с копированием буферов в/из FBO в PPSSPP и нет ли в этом вины буста. Я, похоже, не могу в исходники, вероятно, для этого надо уметь в OpenGL ES, да ещё какой-то там версии. Самое подозрительное, что я вижу, связано как раз с перемещением буферов через буст, причём условия, при которых оно магическим образом не работает, не ясны.

wakuwaku ★★★★
()
Ответ на: комментарий от wakuwaku

Так создай отдельную тему и спроси.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

выдаём в safari/apple finder/etc разобрачительный попап, что mp3 — легаси для говноедского плебса и скоро не будет поддерживаться, вскоре диалог меняется на обратный

anonymous
()
Ответ на: комментарий от deep-purple

а в mp3split тоже костыли или через библиотеки

anonymous
()

Я не сильно в теме поэтому могу ляпнуть чтото не то, но насколько я понял в mp3 каждый фрейм содержит фиксированое ко-во аудио семплов (FrameSampleRate - FSR). Ко-во семплов зависит от версии

             MPEG 1   MPEG 2 (LSF)    MPEG 2.5 (LSF)
Layer   I      384       384             384
Layer  II     1152      1152            1152
Layer III     1152       576             576
Соотвецтвенно для того чтобы получить продолжительность фрейма в секундах нужно FSR/Clock (где клок частота дискритизации в герцах), если нужно получить длинну в байтах то нужно продолжительность умножить на битрейт/8 -> (FrameBitRate/8) * (FST/Clock)

Также следует учесть что в заголовке хранятся не значения битрейта и частоты а их индексы в таблицах. Вообще както странно что вы получили такой разброс в числах (разве что у вас VBR файл) ...

zaz ★★★★
()

Вот кстати нашел неплохое описание http://www.datavoyage.com/mpgscript/mpeghdr.htm

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

if (3 == header->layer) {
    header->frame_size = (size_t) (((12 * header->bitrate / header->samplerate) + header->padding_bit) * 4);
} else {
    header->frame_size = (size_t) ((144 * header->bitrate / header->samplerate) + header->padding_bit);
}
Но все равно есть подозрение что вы не правильно нашли все зашоловки фреймов, хотя если вы просто сканировали биты может нашлась пара ложных совпадений внутри пайлоада ...

zaz ★★★★
()
Ответ на: комментарий от zaz

каждый фрейм содержит фиксированое ко-во аудио семплов

Да, да.

не значения битрейта и частоты а их индексы в таблицах

Да, да.

разве что у вас VBR файл

Это не важно сейчас, т.к. я не дошел еще до VBR, тестирую на CBR.

формула выглядет не корректно

Таки нет, 12 и 144 супротив 12000 и 144000 это только потому, что в таблице я храню битрейты деленные на тысячу, т.е. например для 320 кбпс, так и записано 320, а не 320000.

не правильно нашли все зашоловки фреймов

Вот, об этом то я и говорю. Странно, что 4 чара в каждом фрейме парсятся как валидные. Ну оки. Повторю еще раз ситуацию другими словами:

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

У меня было два пути чтобы проверить где правда - записать в индекс размеры полученные по формуле или же «междуфреймовые расстояния». Оба варианта были проверены.

Тут нужно еще добавить, что для варианта с формулой, я, естественно seek'ал файл вперед на +размер фрейма, т.к. можно типа довериться и двигать анализ файла дальше.

Так вот, кое-как, с артефактами, заработал вариант с формулой. Однако, лайм в апи имеет еще и ф-цию hip_decode1_headers() которая дает инфу о распарсенном заголовке.

И... уа-хахаха - данные не совпали, я нашел гораздо больше фреймов чем лайм (возможно он их тоже нашел, но отбрыкнул по какой-то причине).

Соответственно в стартовом сообщении я и написал:

Кто подскажет где скопипастить: 1) правильную формулу вычисления длины мп3-фрейма. 2) правильный алгоритм выпарса и валидации этих самых фреймов.

И, т.к. формула у меня верная. Да? Осталось только узнать как корректно искать фреймы.

Показать что есть сейчас кусочком кода?

deep-purple ★★★★★
() автор топика

вместо тегов можно использовать ссылки на файлы и удалять будет проще

anonymous
()
Ответ на: комментарий от anonymous

ссылки

Лучше ярлыки, и чтоб все на рабочем столе были, расставленные в форме этого, ну ты понял, на боинг-боинг чтоб скриншот ушел.

deep-purple ★★★★★
() автор топика

1) правильную формулу вычисления длины мп3-фрейма. 2) правильный алгоритм выпарса и валидации этих самых фреймов.

судя по тому, что все плееры делают это по-своему, и везде есть нестыковки — правильной формулы пока никто не сделал.

понятие правильности у всех тоже разное.

+ костыли и подпорки накопившиеся за 5-10 лет (в зависимости от старости проекта), как ты и писал.

моя реализация — здесь, с подпорками в комплекте. в основном, функция cmp3_scan_stream

p.s. когда ты парсишь поток поиском sync-word'ов, учти, что они могут попадаться внутри тегов (не все теги используют unsync).

поэтому теги надо пропускать перед сканированием.

помойка, костыли и говнокод

угу, есть такое :) но постепенно расчищаю завалы, привожу код в порядок, и даже планирую тесты прикрутить.

waker ★★★★★
()

Объясните мне дураку. Ну на кой в 2015 году нужно mp3? Для лоуслс уже везде достаточно места, память для портативных плееров копеешная, там где лоуслс не нужен есть AAC.

SjZ ★★★★★
()
Ответ на: комментарий от waker

Во! Тебя и кастовать не нужно — ты тему за версту чуешь! ))

Обязательно загляну под капот твоего плеера, но через пару часов, ато тёща у нас..

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от SjZ

Оно есь, и будет плохим тоном не реализовать его поддержку. Для тебя - не нравится, не ешь. А другим может просто понадобиться.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Странно, что 4 чара в каждом фрейме парсятся как валидные.

Что значится парсятся как валидные ? Это же не текст чтоб его парсить, а бинарные данные - вы просто их интерпретируете. Единственный набор возможных проверок это: 1. Frame sync (12 первых бит) 2. Проверка других полей чтоб там были валидные значения (не резервед, хотя резервед тоже чтото может значить). Тоесть если вы возмете любые 4 байта (которые могут являтся просто куском аудио или куском ID3 тега) вы можете получить выполнения обоих условий, но при этом нет гарантии что это действительно заголовок фрейма.

Меня смущает вот это

Это не важно сейчас, т.к. я не дошел еще до VBR, тестирую на CBR.

Тоесть если вы работаете с CBR то по идее у вас в каждом фрейме должны быть обсолютно одинаковыми все параметры (ну разве что выравнивание и emphasis), но bitrate и samplerate (ну и версии медии сами собой) должны быть одинаковыми для всех фреймов. Как результат - не важно вы используете правильную или не правильную формулу она должны выдавать ОДИНАКОВЫЙ результат для всез фреймов (разве что для некоторыйх +1 байт на выравнивание но это тоже маловероятно). Но вы пишете:

Но она выдает размеры (300-8000 байт) не равные ни тому что я напарсил по синк-вордам

Это очень странно, у меня всего 4 предположения: 1) Вы не нашли заголовки фреймов (или часть это дейсвтительно заголовки, а вторая часть просто данные). 2. У вас mp3 таки с VBR поэтому все фреймы и разные. 3. Гдето просто баг в коде. 4. Вы (и получается я тоже) чтото не понимаем/не учитываем в формате.

PS. По поводу if в формуле почему

if (!header->layer)
а не
if(3 != header->layer)
так как
C	2	(18,17)	Layer description
00 - reserved
01 - Layer III
10 - Layer II
11 - Layer I

zaz ★★★★
()
Ответ на: комментарий от zaz

Что значится парсятся как валидные?

Так выразился.

в каждом фрейме должны быть обсолютно одинаковыми

В некоторых треках кстати попадался «мусор».

Гдето просто баг в коде

Я скинул выше ссылку на пастебин, и не утверждаю что код корректный.

По поводу if в формуле почему

Потому что сразу приводится к индексу таблицы:

header->layer = 3 - (buff[1] >> 1 & 0x03);

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

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

zaz ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.