Различный размер PCM файлов до и после декодирования

Список разделов Ogg Vorbis Ogg Vorbis

Описание: Обсуждение всех вопросов касательно Ogg Vorbis

Сообщение #1 Karr » 10.07.2012, 11:04

Столкнулся с проблемой. По заданию необходимо писать данные с микрофона, жать их в ogg page, хранить на сервере, а потом проигрывать по желанию пользователя. Одно из условий декодирования - постоянный размер pcm кадров до сжатия и после разжатия. Но у меня размеры pcm кадров варьируются, причем иногда в пределах 100% от размера. Может ли кто нибудь объяснить, почему я беру pcm кадр фиксированного размера, жму его по всем правилам в ogg page (потом стал жать в ogg packet), а после расжатия получаю pcm кадр иного размера?
Karr
Репутация: 0
С нами: 11 лет 8 месяцев

Сообщение #2 VEG » 10.07.2012, 14:17

Karr, возможно в исходных WAV файлах у вас есть какая-то мета-информация. После декодирования она, конечно же, теряется. Что такое Ogg Page и Ogg Packet?
При кодировании в Ogg Vorbis размер каждого сэмпла не должен изменяться. Какие у вас входные характеристики?
VEG M
Администратор
Аватара
Откуда: Finland
Репутация: 40
С нами: 18 лет 4 месяца

Сообщение #3 Sojindox » 10.07.2012, 23:09

Посмотрите битность, до и после :wink:
кадр - это у вас имеется ввиду "файл" ? =)
Sojindox
Аватара
Откуда: תל-אביב-יפו
Репутация: 21
С нами: 14 лет 11 месяцев

Сообщение #4 Karr » 11.07.2012, 09:42

VEG: В соответствии со спецификацией:
http://www.fileformat.info/format/wave/stanford.html
метаинформация в WAV файле - это первые 44 байта (данные о битрейте, количестве каналов и тп). Но я на сжатие я ее не отправляю, только сами данные из wav файла (блок data на картинке). То есть входные характеристики - звук с заданным битрейтом, известным числом каналов и тп.
Я смотрел API на vorbis, чтобы написать свой кодировщик/декодировщик, скачал пример на C, и стал писать что то похожее (только на C#), вот.
По алгоритму ты берешь кусок файла wav (например 1 kB данных - кадр или наверно правильно называть сэмпл), затем функцией vorbis_analysis_buffer получаешь указатель на буфер и пихаешь туда свой килобайт, потом вызываешь vorbis_analysis_wrote, она пихает блоки в структуру _ptrVorDsp, и затем вызываешь vorbis_analysis_blockout, она определяет доступные несжатые данные и разбивает их на блоки - возвращается структура vorbis_block. Потом для vorbis_block ты вызываешь vorbis_analysis и vorbis_bitrate_addblock, они проводят анализ блока данных и сжимают его, и затем ты вызываешь vorbis_bitrate_flushpacket, и получаешь пакет Ogg_packet (или несколько) в котором уже хранятся данные в сжатом виде(!! вот здесь пакет который я упоминал, немного сумбурно, но это чтоб понять откуда берутся ogg пакеты, а функции которые привел - они есть в описании к библиотекам vorbis и ogg).
Вот, то есть ogg packet - это минимально возможная единица сжатых данных. По идее несколько пакеты можно уложить в ogg_stream и объединить еще в одну единицу сжатых данных ogg_page. В итоге когда я разжимаю ogg_packet или ogg_page у меня получаются wav куски других размеров((

Sojindox: битность смотрел до и после, одинаковая, там различие в размерах не в разы (как было бы если, скажем, битрейт был в два раза меньше), различие в пределах процента, например сжал 533488 байт, а получил на выходе 531242 байт, из за того, что при сжатии данных кусками по 4096 байт на выходе эти куски превращались либо в 3200 байт, либо в 8128, бывали и в 4096, но разброс размера выходных wav кусков присутствует, хотя в сумме размер выходного файла не сильно отличается.
PS кадр - это вот кусок wav файла

а требуется именно получить определенность по заданию на входе кадр 1 кВ, и на выходе должен быть такой же длины кусок
читал документацию на vorbis, но там стока, не нашел об этом инфы исчо

во скока понаписал!!!)))
Karr
Репутация: 0
С нами: 11 лет 8 месяцев

Сообщение #5 VEG » 11.07.2012, 14:32

Karr, так сразу бы и написал, что пишешь свой кодер. К сожалению, никогда не программировал с использованием Ogg Vorbis. Попробуйте сжимать ваши данные стандартным кодером oggenc.exe. С ним проблема есть? Если нет, можете воспользоваться не очень красивым решением: запускать программно oggenc.exe в режиме, где он считывает данные из stdin, а выводит всё в stdout. Если нужно на вход подать не wav, а raw — соответствующий параметр имеется.
А ещё лучше написать обёртку для libvorbis.dll на C#. И чтобы на выбор можно было использовать либо libvorbis.dll, либо oggenc.exe :) Я бы сам был бы рад появлению такого класса на codeplex.
Внешний файл кодера будет лучше, потому что их много разных, и каждый может выбрать себе наиболее подходящий. Я вот, например, люблю Lancer за его скорость.
Сэмпл — это одно 16 разрядное значение амплитуды в данный момент. Так что то что вы называли кадром всё-таки не сэмпл :)

Добавлено спустя 1 минуту 1 секунду:
Karr:метаинформация в WAV файле - это первые 44 байта
Ошибочно. Там может быть заведена отдельная секция с дополнительной инфой. Сам не раз видел такие WAV файлы.
VEG M
Администратор
Аватара
Откуда: Finland
Репутация: 40
С нами: 18 лет 4 месяца

Сообщение #6 Karr » 11.07.2012, 15:12

Ага, я сделал обертку для libvorbis.dll и libogg.dll, юзаю оттуда функции; запускать программно кодер типа oggenc.exe низзя( потому чт требуется налету работать с отдельными кадрами, там во время работы сервера постоянно ведется аудиозапись, и пишутся сжатые блоки ogg, а на клиенте надо чтобы эти сжатые блоки обязательно распаковывались в блоки wav такой же длины, там типа блоки привязываются по времени, и вот нужна эта однозначность. Сча смотрел документацию на vorbis, там сказано, что размер выходного файла равен:
window_blocksize(previous_window)/4+window_blocksize(current_window)/4
окна - это куски файла ogg packet, которые подаются на вход обратного преобразования (Фурье что ли, или какого то похожего)
и вот в vorbis длины этих окон могут меняться, видимо из-за этого различный размер wav кадров на выходе. VEG, можт знаешь как зафиксировать размер этих окон? я ужо копаю код libvorbis.dll, но пока не получается((

Про метаданные wav - я снимаю данные с микрофона, так что там wav в чистом виде. Читаю блоками по 4096 байт, кодирую в ogg, и потом сразу обратно в wav, и вот полученные wav куски имеют другую длину(((
Karr
Репутация: 0
С нами: 11 лет 8 месяцев

Сообщение #7 VEG » 11.07.2012, 17:29

Karr, ну так сохраните на диск исходные PCM данные и данные что у вас получились. Затем исходные данные сожмите через oggenc.exe и сравните с тем, что у вас получается. Ogg Vorbis не выкидывает сэмплы (это одна из его фишек), так что чевидно у вас какая-то ошибка закралась.
VEG M
Администратор
Аватара
Откуда: Finland
Репутация: 40
С нами: 18 лет 4 месяца

Сообщение #8 Sojindox » 16.07.2012, 09:55

"в vorbis длины этих окон могут меняться, видимо из-за этого различный размер wav кадров на выходе"

я конечно не профи, но припоминаю, что ворбис такого не должен уметь. нет у него переменного MDCT. возможно в декодере возникает выброс семплов.
Sojindox
Аватара
Откуда: תל-אביב-יפו
Репутация: 21
С нами: 14 лет 11 месяцев



Вернуться в Ogg Vorbis



cron