Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

FFT на mp3 файле, Java

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

А кто в проектах делал fast fourier transform на mp3 файлах на java?

Мне нужно вытащить частоты из mp3 файла. Для этого мне нужно получить декодированный массив байтов. Я нашел либу jLayer, которая умеет проигрывать mp3, поковырялся в ее исходниках и набросал вот этот код, который должен декодировать mp3 файл:

        public static short[] getDecodedMp3Stream(String pathToMp3File) {
        short[] decodedMp3StreamInBytes = new short[]{};
        Bitstream bitStream = new Bitstream(new FileInputStream(pathToMp3File));
        Decoder decoder = new Decoder();
        Header frameHeader;
        while ((frameHeader = bitStream.readFrame()) != null) {
            SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitStream); //returns the next 2304 samples
            short[] next = output.getBuffer();
            decodedMp3StreamInBytes = appendToArray(decodedMp3StreamInBytes, next);
            bitStream.closeFrame();
        }
        return decodedMp3StreamInBytes;
    }

Проблема в том, что массив pcmOut всегда заполнен 0. Как пофиксить данный момент?

Если кто-то посоветует кросс платформенную либу на C/C++ для работы с mp3 (суть — получить декодированный поток байтов из mp3 файла), то буду признателен.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

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

А что мешает взять AIMP или ещё какой плеер? Халява же. В чём цацка — вытащить его API общения с графическими плагинами, ну те которые рисуют красивые фракталы. То есть поискать готовый такой плагин в исходниках среди бесплатного софта. И собственно проиграть файл в /dev/null

Если нужно «на вчера» — тупо поищи готовый код, в качестве строки поиска подбрось гуглу полное имя класса Bitstream и слово «new» перед ним.
// И не стесняйся почитать таки к нему документацию. Это не больно.

Если кто-то посоветует кросс платформенную либу на C/C++ для работы с mp3 (суть — получить декодированный поток байтов из mp3 файла), то буду признателен.
LAME MP3: lame.sf.net и openinnowhere.sourceforge.net/lameonj — он не самый быстрый, но уши у него растут у reference реализации, поэтому он самый качественный. Последний раз была задача жать в реалтайме звук с 8 каналов на дохлом SiS 552×86 процессоре 200MHz (многие даже не слышали о таком: www.cpushack.com/SC55x.html ) в 2004 — и он справлялся. Поэтому сегодня я бы не заморачивался над скоростью вообще.

Я тут наваял кода на Джаве: github.com/terancet/Mp3FftProcessor

Проблема в том, что оно как бе работает (те считает FFT на mp3), но я дупля не шарю, что оно мне выдает на этапе декодирования mp3 файла.

Собирается Maven’ом. Буду смотреть в дебри мп3 формата, ибо без знаний предметной области — никуда не деться.

Насколько я помню, то MP3 и так содержит все нужные данные, переведенные в частотные характеристики, поскольку именно так он их и пакует.
Поэтому, если уж и лезть в глубины декодера, то нужно сделать на 1 шаг больше: добраться до кода расшифровки/распаковки фрейма и отловить те данные, которые потом поступают на вход алгоритму обратного FFT — как раз это и будут искомые частоты.

Насколько я помню, то MP3 и так содержит все нужные данные, переведенные в частотные характеристики

А можно ссылку?На вики ничего толкового не нашел. Я думал, что mp3 содержит в себе time domain characteristics.

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

blog.bjrn.se/...ts-build-mp3-decoder.html, About MP3 и дальше по тексту.
Bitstream это по сути отфильтрованный и сжатый Huffman’ом результат FFT.

Статья классная. Спасибо.

мне кажется, это будет пустая трата времени — для реализации онного нужно разобраться в том, как работает mp3, а на выходе будет неуниверсальное решение.
ИМХО логичнее делать fft на простом wav формате, а в wav перегонять готовыми декодерами из любого другого.
+ обычно уже есть готовые реализации fft для wav и чтобы реализовать пруф оф концепт не понадобится много времени
я бы вообще взял python — там много всяких готовых либ в научной плоскосте (numpy тот же)

Ого, превращаемся в хабр ! Требуется именно частотная характеристика блока ?? По поводу декодирования частот — сначала блок надо распаковать хафманом, провести IMDCT и в завершающей фазе не забыть про сглаживание. При всем этом помнить по битрейты / частичные либо урезанные либо масштабируемые окна частот ... на 2 года работы если разбираться.

если задача просто получить стрим — то любой открытый сишный кодек легко использовать : инициализация Init(), поиск синхробайтов, декодировка блока > стерео/моно стрим на выходе ...

А что за проект если не секрет ? Сравниваете качество кодеков ??

p.s. лично я лет 10 пользуюсь mp3lib от Helix-а

У меня в голове зудит идея реализовать аналог Shazam: хочу на основании частотных характеристик треков построить рекомендательную систему.

Flow следующий:

1. человек загружает в систему свою коллекцию mp3 файлов, проставляет метку на каждый файл (нравится/не нравится),
2. система переводит каждый трек в массив спектров (sqrt(realPart[i]^2+imaginaryPart[i]^2),
4. потом этот массив скармливается какому-либо алгоритму (например, kMeans),
5. на выходе выдается список других треков, которые похожи по частотным характеристикам на исходную коллекцию юзера.

По-сути, есть вопрос: я сейчас вытягиваю декодированный стрим из каждого mp3 frame, потом собираю все декодированные стримы в один массив. Можно ли сделать FFT на отдельно взятом стриме, а потом их Фурье образы сложить в один массив? Чую, что нельзя так сделать, но хотелось бы понять, мб для моей задачки такая оптимизация подойдет.

Круто !

Впринципе удастся обойтись малой кровью — без хирургического вмешательства во внутренности кодека )) Я бы просто декодировал/восстанавливал стрим закачанного файла, и «вручную» повторно пересчитывал бы основные частоты интересующих участков трека.

Похоже львиная доля работ припадет на создание и поддержку баз данных сервиса, а MP3 декодеры есть и на яваскриптах уже как пару лет )

Надеюсь у коллектива авторов хватит сил, энергии и упорства довести стартап до первого пуска !

По-сути, есть вопрос: я сейчас вытягиваю декодированный стрим из каждого mp3 frame, потом собираю все декодированные стримы в один массив. Можно ли сделать FFT на отдельно взятом стриме, а потом их Фурье образы сложить в один массив? Чую, что нельзя так сделать, но хотелось бы понять, мб для моей задачки такая оптимизация подойдет.

Похоже будет «средняя температура по больнице» трека ) Надо подумать как классифицировать частотные характеристика аудиофайлов. По каким критериям.

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

пс. будет озарение — напишу. ...

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

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

github.com/audiocogs/mp3.js — вот собственно либа на яваскриптах, на клиентской машине можно прокручивать файлы и собирать статистик, перед отправкой ...

Насколько я знаю, современные рекомендационные системы кроме fft анализирует много чего еще. Например onset detection — грубо говоря определить характер и временные метки атак инструментов в треке.

за первый проход можно определить широту спектра / узкие участки.
за второй проход определять BPM / тональности / частотные показатели участков / количество инструментов etc ... и выгрузить весь этот дамп/массив параметров участков на сервак, где есть возможность сопоставить показатели ))

насколько я понимаю определение кол-ва инструментов уже частично затрагивает этот самый onset detection.
bpm одного трека может сильно варьироваться, если шазамить записи с радио/живое исполнение/сеты, т.к. их подгоняют. Так же будет сильно отличаться и частотный диапазон (разная компрессия, скорость, удаленность от источника итд)
я вообще не претендую на эксперта в этой областе, просто имел опыт общения с человеком, который интересовался темой. Он мне скидывал ссылку на такой документ в качестве примера dataset’а, который может быть полезен: developer.echonest.com/.../AnalyzeDocumentation.pdf

просто я клоню к тому, что скорее всего у шазама лвиная часть работы — определение инструментов и последовательности их атак, т.к. точность с которой он определяет всякие ремиксы одного трека впечатляет.
Шазам отлично справляется и с определением треков, которые програмно (например при сведении dj сета) были изменены — измененный темп (bpm), тональность (key) и при этом сильно заэквализированы.
anyway — интересно посмотреть на результат, т.к. самого эта тема тоже немного интересует, но в другой плоскосте

Да, забавно посмотреть на результат, даже промежуточный ... Хохма будет если окажется что каждая вторая композиция — плагиат, а остальные 50% еще не загрузили ... ))

хочу на основании частотных характеристик треков построить рекомендательную систему.

Копнул глубже — походу это не только распознавалка стилей композиций, а и Speech Recognition :) при определенных вариантах использования ...

Підписатись на коментарі