На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Как определить длительность звучания файлов wma, midi, ogg и flac? , На голом Си
    Привет всем :)

    Необходимо определять длительность звучания и прочих параметров (частота, битрейт и т.д.) файлов wma, midi, ogg и flac.
    Причём надо это делать на голом Си, без всяких DirectShow и прочих супер библиотек, т.к. конечное предназначение - портативный плеер на микроконтроллере.

    Всё, что там есть - стандартные файловые операции Си - fopen, fread, fwrite, lseek и fclose. lseek ущербный, умеет позиционироваться только вперёд и только от начала. Но это я уже успешно преодолел :) .

    На настоящий момент я умею вытягивать всю информацию из mp3 (иногда наблюдаются глюки с определением частоты, но это уже мелочи :) ), считывать название и исполнителя из wma (успешно выдрал из какой-то проги на VB.NET) и получать всю инфу из wav.
    Я знаю, что midi - это не оцифрованный звук, поэтому тут стоит вопрос только о длительности звучания.

    Просьба поделиться информацией, как это делать. Желательно примерами кода, т.к. из голых спецификаций фиг что поймёшь. Я пытался читать многочисленные описания midi и спецификации WMA (ASF), ничего про длительность звучания я там не нашёл, а то, как там хранятся ноты, объекты и всё прочее меня совершенно не волнует, т.к. абсолютно все форматы проигрываются специальной микросхемой, которая их прекрасно понимает без каких-либо усилий с моей стороны.

    Интересует исключительно описательная часть для вывода на дисплей.

    Спасибо.

    PS. Я создал эту тему не в разделе про микроконтроллеры, потому что чтение этой информации может потребоваться и в программе на компе, а не только в МК.
    Если я не прав, то сорри :)
    Сообщение отредактировано: hd44780 -
      hd44780
      А почему не взять готовый код на Си?
      Выкинуть лишнее проще чем добавлять новое. Поэтому предлагаю разобраться с исходниками на FFMpeg тем более они простые.
      https://github.com/FFmpeg/FFmpeg/tree/master/libavformat
      или Lame
      http://lame.sourceforge.net/download.php
      Для Midi первое что попалось это
      https://wiki.videolan.org/Midi
        И самое смешное это то, что контейнеры кроме собственно дорожек имеют чанк заголовка в котором и указаны все атрибуты. Эти атрибуты и читают медиа библиотеки. Если их нет или они записаны неверно или повреждены - контейнер нечитаем. Посмотри хедеры нужных форматов контейнеров. Создай указатель на структуру типа чанка и из полей читай нужные данные.
          Да, посмотрю, спасибо.
          Сейчас накопал CoolPlayer, он читает ogg, смотрю, как он его длительность определяет.

          ffmpeg смотрел, там, похоже, из аудио только mp3. Который у меня уже есть. Но может я и неправ..
          А видео мне пока не нужно, проц дохлый для этого.
          Сообщение отредактировано: hd44780 -
            Круто. А проект будет открытый? (в плане исходного кода)
              Цитата hd44780 @
              успешно выдрал из какой-то проги на VB.NET

              Может, Audio Tools Library сможешь портировать? Там есть всё кроме midi. Для midi можно поковырять исходники MODlist, но там тоже Delphi...
                Цитата DIS @
                Круто. А проект будет открытый? (в плане исходного кода)

                Да. Потом где-нибудь статью опубликую.
                Пока оно ещё не готово - плейлистов фактически нет, просто сканирую USB-флэшку/SD карту и пишу туда же текстовый файлик с путями к нужным файлам, оттуда же их и читаю потом, интерфейс не доработан и прочее.
                Ну это уже не для этого форума.

                Добавлено
                Цитата Filka @
                Цитата hd44780 @
                успешно выдрал из какой-то проги на VB.NET

                Может, Audio Tools Library сможешь портировать? Там есть всё кроме midi. Для midi можно поковырять исходники MODlist, но там тоже Delphi...

                Может гляну ...
                Но с делфи у меня туго...
                Я в основном C/C++/C#. VB.NET довольно близок с C#, поэтому я его довольно легко понял. Но та прога, которую я потрошил, длительность WMA не определяет, только теги :(
                    packages.ubuntu.com/ru/lucid/mpg321
                    packages.ubuntu.com/ru/lucid/libmpg123-0
                    тоже линуксовые, первый вроде попроще, а у второго зависимостей меньше
                    если может воспроизвести, наверно и инфу покажет
                    Сообщение отредактировано: Romzecs -
                      Ну я в процессе, как что будет получаться/не получаться, буду отписываться.
                        Снова привет всем :) . Долго меня тут не было ...
                        В Донецке, который в "самостийной" т.н. стране украине довольно хреновая обстановка, мало способствующая какому-либо программо-писанию. Ну да ладно ..

                        Теперь по делу.
                        Перерывши тонну разных исходников программ на предмет получения информации из .ogg файлов, я убедился, что все они построены на официальных vorbis-овских либах, которые довольно древние (2007 год, если правильно помню) и в современных VS2010/2012 даже не компилятся, выдавая кучу разных ошибок.
                        Нормально компилится лишь вышеупомянутый coolplayer. Видать, его автор неплохо потрудился в плане адаптации ворбисовского старья под новые компиляторы.
                        Но и с него оказалось крайне мало толку, т.к. официальная либа написана крайне путанно и очень неоптимально с точки зрения расхода памяти. Чего стоит только выделение 64 кил блока динамической памяти и чтения туда куска файла ради получения какого-там заголовка длиной в 15-20 байт...
                        Короче, потраченное время ушло совершенно впустую.
                        Потом, довольно случайно я наткнулся вот на эту - http://getid3.sourceforge.net/ штуковину.
                        Это набор PHP библиотек для получения различной информации из кучи разных аудио/видео файлов.

                        Тоже читает кучу лишнего, но хоть без ненужных выкрутасов и выделения диких объёмов памяти.
                        На нём я и остановился.
                        На его основе сделал "считыватель" информации из OGG - прилагаю. Делал в VS2010. Имя файла вшито в программу.

                        Вложение здесь - Как определить длительность звучания файлов wma, midi, ogg и flac?
                        Тот вариант, который был здесь, неверно читал русские комментарии.
                        Сообщение отредактировано: hd44780 -
                          Всё, и в плеере алгоритм работает. Приступаю к mid, там только время звучания вычислить.

                          По OGG только один вопрос остался. Я так и не понял, в какой кодировке там русские названия хранятся?
                          Перекодировал mp3 с русскоязычными тегами в OGG каким-то он-лайн перекодировщиком, он туда какой-то фигни написал. Каждый символ 2-байтный, а-ля Unicode, но я даже на компе на 100% не сумел прочитать эти строчки. Они только в режиме DOS кодировки наполовину читабельны. Естественно, через один символ.
                          Сообщение отредактировано: hd44780 -
                            То же самое для WMA.
                            Также под VS.NET 2010, имя читаемого файла вшито в программу.

                            Прикреплённый файлПрикреплённый файлWMA_Reader.zip (11,55 Кбайт, скачиваний: 232)
                            Сообщение отредактировано: hd44780 -
                              Цитата hd44780 @
                              По OGG только один вопрос остался. Я так и не понял, в какой кодировке там русские названия хранятся?

                              Рискну предположить, что в UTF-8.
                                Да хз ...
                                Я даже не нашёл нормальной проги для конвертирования в OGG. Пробовал Total Audio Converter - на конвертировании в OGG он вылетает :(

                                WMA в плеере работает :) .
                                  Цитата korvin @
                                  Рискну предположить, что в UTF-8.

                                  Да, нашёл какую-то прогу, переконвертировал ею mp3 в ogg, comments получились в UTF-8.
                                  Ща буду какой-то конвертер UTF-8 -> Win-1251 сочинять/искать готовый. Знакогенератор в плеере понимает только Win-1251.
                                  Стандартные виндозные функции мне не подходят, даже если они и существуют.
                                  Сообщение отредактировано: hd44780 -
                                    Вариант для OGG с конвертированием инф. тегов из UTF-8 в Win-1251.
                                    Конвертер свой, встроенный, без каких-либо виндозных функций.
                                    Прикреплённый файлПрикреплённый файлOGG_Reader.zip (11,08 Кбайт, скачиваний: 244)
                                      Если я правильно понял спецификацию ogg, то comments должны быть в UTF-8.
                                        Да, всё верно, там UTF-8.
                                        То тот онлайн-перекодировщик наглючил, выдал комментарии в полубредовой полу-DOS кодировке.
                                          MIDI.
                                          Определяет длительность звучания и битрейт.
                                          Понятие "битрейт" для MIDI я, честно говоря, не понимаю, по-моему просто прикол. Определяется делением длины файла на длительность в секундах :D .

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

                                          Проверял на файлах нулевого формата, т.к. используемая в плеере микросхема VS1053 понимает только его.
                                          Прикреплённый файлПрикреплённый файлMIDI_Reader.zip (8,6 Кбайт, скачиваний: 233)
                                            Да, на многодорожечных моё изделие глючит. Ну и фиг с ним :D .
                                            VS1053 их тоже не понимает, потому не смертельно.
                                              Последний формат - FLAC.
                                              Для себя пока считаю тему закрытой. Всем участвующим спасибо.
                                              Но если кто-то улучшит предложенные программки, просьба поделиться :)

                                              Тут выше интересовались проектом целиком - если кто знает, куда здесь класть подобные вещи, напишите плиз.
                                              Когда я всё закончу - выложу. Когда - не знаю, тут ещё кое-что осталось доделать по функционалу...
                                              Прикреплённый файлПрикреплённый файлFLAC_Reader.zip (14,39 Кбайт, скачиваний: 191)
                                              Сообщение отредактировано: hd44780 -
                                                Пришлось снова вернуться к этой теме.

                                                Использовавшийся у меня код для чтения MP3 безбожно врал - правильно читались только ID3v1/v2 тэги, всё остальное в 98% случаях оказывалось полной чушью.
                                                Пришлось заняться им вплотную. Нашёл на просторах приемлемый образчик проги на VB.NET, перевёл на чистый Си, доработал её с учётом статьи.
                                                Оригинал на VB.NET не выкладываю, т.к. он имеет существенные недоработки:
                                                1. Не учитывает версию MPEG и Layer при определении битрейта и частоты, из-за чего частенько выдаёт неверный результат
                                                2. ID3v2 тег в начале не пропускался (его наличие/отсутствие никак не проверялось), поэтому он иногда думал, что фрейм начинается где-то на середине имени исполнителя или названия песни со всеми вытекающими ...

                                                К тому же автор забыл приложить один из файлов формы окна программы - в итоге полная некомпилируемость проекта. Восстанавливать его руками мне стало лениво :D .
                                                Хорошо хоть .exe и основной файл со всеми расчётами дал... Ну а про конвертирование байтов в строки вида 1110101001 и вырезанием из неё нужных битов функцией substring вместо лог AND и сдвигов я вообще молчу - эт вообще ещё тот шедевр :wacko: :blink: . Ну да ладно, его исходник помог во многом разобраться.
                                                Если кто-то захочет - выложу.

                                                ******************************************************
                                                Следующее замечание касается wav-файлов.
                                                Казалось бы, что может быть проще - формат простой, как 3 копейки, разжёван на каждом углу, статей о нём - тьма-тьмущая, даются даже готовые исходники по чтению всех параметров, включая расчёт длительности звучания - http://audiocoding.ru/article/2008/05/22/w...-structure.html

                                                Но не тут-то было. При детальном рассмотрении выяснилось, что:
                                                1. Все (те, которые попались мне на глаза) имеющиеся статьи описывают исключительно подформат PCM.
                                                2. Другие подформаты (коих насчитывается больше сотни - http://audiocoding.ru/assets/meta/2008-05-...wav_formats.txt) вообще не рассматриваются. Иногда делается замечание, что они есть и всё :rolleyes: . Но как и на что влияет не PCM формат - тишина.
                                                3. В заголовке файла кроме "стандартных" секций fmt и data никто не запрещает иметь там кучу других, например, аналоги MP3 ID3 тегов оформляются как доп. секции в заголовке WAV файла. Даже в PCM. Это вообще большой-большой секрет и строжайшая "военная тайна", о которой никто и не заикается :lol: .

                                                В итоге авторы статей делают существенное упрощение - они считают, что всегда имеют дело только с PCM (хоть реально это никак не проверяют), структура заголовка строго фиксирована и в ней есть только 3 подряд идущие части:
                                                1. Первый подзаголовок RIFF длиной 12 байт
                                                2. секция fmt (24 байта - 8 байт заголовок секции + 16-байтовая структура WAVEFORMATEX - см. ниже)
                                                3. первые 8 байт секции data (сигнатура и длина).

                                                Они просто вычитывают эти 12+24+8=44 байта в единую структуру и выполняют необходимые расчёты.

                                                Исходя из вышесказанного, здесь есть 2, я бы сказал даже 3 грубейшие ошибки:
                                                а) Длина секции fmt не 16 байт WAVEFORMATEX (без 8-байтового заголовка секции), её реальная длина хранится в поле subchunk1Size (название из статьи на audiocoding.ru). Её реальное содержимое - не всегда WAVEFORMATEX, а совершенно разные структуры, всегда начинающиеся с WAVEFORMATEX, остальное зависит от её поля wFormatTag.
                                                Если там 0 - т.е. это PCM, то в секции больше ничего нет. Т.е. длина секции - 16 байт WAVEFORMATEX.
                                                Если, например, там 0055h (подформат MP3), то длина секции 30 байт (структура MPEGLAYER3WAVEFORMAT)

                                                б) Не учитывается (никак не проверяется) возможное наличие других секций.
                                                У меня, например, есть очень много wav файлов, которые на самом деле mp3 и в которых между fmt и data есть некая секция fact с длиной данных 4 байта. Для чего она нужна я не знаю, но при чтении файла её необходимо правильно "переступать", чтобы корректно выйти на секцию data, длина которой необходима для расчёта длительности звучания файла.

                                                в) Алгоритм расчета длительности звучания в вышеупомянутом примере некорректен, он опять же пригоден только для WAV PCM без "лишних" секций в заголовке. Его ошибки анализировать не буду, т.к. из вышесказанного и так всё ясно.

                                                Поэтому, если, например, скормить примеру из http://audiocoding.ru/article/2008/05/22/w...-structure.html wav/mp3 файл, то мы получим заведемо неверную информацию.

                                                "Ну и несколько слов о погоде" ©
                                                Cтруктура WAVEFORMATEX в файлах WAV имеет вид:

                                                ExpandedWrap disabled
                                                  typedef struct {
                                                    WORD  wFormatTag;            2
                                                    WORD  nChannels;             2
                                                    DWORD nSamplesPerSec;        4
                                                    DWORD nAvgBytesPerSec;       4
                                                    WORD  nBlockAlign;           2
                                                    WORD  wBitsPerSample;        2
                                                  } WAVEFORMATEX;


                                                Т.е. 16 байт., а не 18, как в описании на сайте Microsoft, где в ней есть ещё одно 2-байтовое поле cbSize, но в файле оно отсутствует.

                                                Прикладываю 2 простенькие программки на голом Си для определения параметров wav и mp3 файлов.
                                                ID3v2 тег для MP3 не дешифруется, просто пропускается, как описано выше.
                                                Прикреплённый файлПрикреплённый файлMP3_Reader.7z (16,72 Кбайт, скачиваний: 204)
                                                Прикреплённый файлПрикреплённый файлWAV_Reader.7z (12,08 Кбайт, скачиваний: 161)
                                                Сообщение отредактировано: hd44780 -
                                                  Новая версия MP3reader.
                                                  В предыдущей был найден ряд ошибок:
                                                  1. Ошибка с указателем. На некоторых файлах его иногда выносило в космос. Прога в лучшем случае выдавала неправильную инфу, в худшем её прибивала винда молотком по голове. Ну оно и понятно.
                                                  2. В некоторых MP3 файлах бывает по 2 ID3v2 тега (а может и больше :lol: ). На фига оно надо я не знаю, но из-за этого некорректно обнаруживался первый фрейм со всеми вытекающими ошибками. Добавил детектирование подобных ситуаций. Насколько корректно - хз, время покажет. Пока работает.
                                                  3. Не ошибка, но всё же - немного оптимизировал алгоритм.

                                                  Из недостатков пока могу отметить только одно - моё изделие иногда врёт :D .
                                                  Попадаются какие-то "ненормальные" MP3 файлы, на которых спотыкаются многие программы, включая всем известный WinAmp. У меня есть один такой файл (может и больше - не знаю), в плейлисте длина равна 0 мин 00 сек, инфо вообще пустое (кроме, разве что ID3 тегов), но при проигрывании он правильно показывает длительность звучания, частоту, битрейт и моно/стерео.
                                                  Даже MPAHeaderInfo, который очень часто хвалят, выдал длительность 00:00. Даже при полном сканировании.

                                                  И только лишь огромная похапешная либа - http://getid3.sourceforge.net/ выдала всю инфу без ошибок.
                                                  Но разбирать её и переделывать на си у меня пока нет вдохновения :D Чтение MP3 там дико мутное :crazy: Может как-нибудь потом ...

                                                  Если кому интересно - могу выложить данный файл.

                                                  Прикреплённый файлПрикреплённый файлMP3_Reader.zip (12,16 Кбайт, скачиваний: 146)
                                                  Сообщение отредактировано: hd44780 -
                                                    У меня была аналогичная задача.

                                                    Выкладываю для WMA, она у меня получилась заметно короче.

                                                    Звуковые параметры заполняются в структуру WAVEFORMATEX, длительность в секундах - в переменную DWORD по ссылке, текстовая информация - в структуру ID3v1.

                                                    Касаемо поиска в mp3.
                                                    Я использовал вариант: ищем с начала файла ff, а когда нашли, проверяем, что байт после него &0xe0 ==0xe0.
                                                    Считаем это началом условного mp3 фрейма, вычисляем его длину, и убеждаемся, что после этого фрейма в файле также стоит ff,
                                                    причем параметры заголовка второго фрейма должны совпадать с первым, 4 байта.
                                                    Если (((l ^ next_l) & 0xffff0c00) !=0), то типы фреймов разные, и это вообще не фреймы, продолжаем поиск следующего ff.

                                                    А если одинаковы, считаем первый фрейм началом звуковых данных, берём из фрейма битрейт, делим на него длину файла за минусом текущей позиции.
                                                    Заголовок Xing пока не ищется и не анализируется, но он может оказаться только в первом фрейме.



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

                                                    Если интересно, выложу исходники программы, там только голый си, никаких библиотек.

                                                    Хелп от программы:

                                                    MP3 filelist generator v1.14

                                                    support filetypes: mp3,wma,asf,wmv,ogg,ape,flac,wav,avi

                                                    Usage: MP3LIST <dir> <outfile> [format_string]
                                                    <format_string>==string with plain or control characters
                                                    control characters:
                                                    _ => space character
                                                    %% => "%" character
                                                    %_ => "_" character
                                                    %\ => "\" character
                                                    %[<NNN>]<field> => first <NNN> character of ID3tag field, space alignment
                                                    if <NNN>=255 then no aligment
                                                    if <NNN>=0 or skipped then used default field's width
                                                    where
                                                    <field>={f|v|t|a|l|c|y|s|b|r|d|D}
                                                    (Filename,VolLabel,Title,Artist,aLbum,Comment,Year,Size,Bitrate,fReq,duration,DurationHMS)

                                                    default format string: "%f_%a_%t_%y_%c"


                                                    Прикреплённый файлПрикреплённый файлWMAtag.rar (2,65 Кбайт, скачиваний: 87)
                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                    0 пользователей:


                                                    Рейтинг@Mail.ru
                                                    [ Script execution time: 0,0596 ]   [ 30 queries used ]   [ Generated: 26.04.24, 14:53 GMT ]