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

| | english | | | русский | |

## FLAC: документация

### Документация

Эта страница разбита на следующие разделы:

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

- формат - описание формата FLAC для пользователя (более детальное описание для разработчика приведено на этой странице).
- `flac` - иcпользование кодека `flac`, работающего из командной строки.
- `metaflac` - использование редактора метаданных `metaflac`, работающего из командной строки.
- плагины - документация для различных плагинов.
- API для `libFLAC` - для разработчиков, желающих использовать поддержку FLAC в своих продуктах.
- ошибки - известные ошибки.

Помните, что онлайновая версия этого документа (на английском языке) включается в последний релиз.

### Формат

Опции по умолчанию для `flac` настроены на получение оптимального соотношения скорость/уровень сжатия для большинства типов входных файлов. Здесь описывается как можно попытаться увеличить уровень или скорость сжатия или с наибольшим эффектом использовать систему метаданных.

Основными частями потока являются:

> - Строка из четырех байтов "fLaC".
> - Блок метаданных STREAMINFO.
> - Другие необязательные блоки метаданных.
> - Один или более аудио фреймов.

Первые четыре байта идетифицируют поток FLAC. Следующие за ними метаданные содержат информацию о потоке, затем идут сжатые аудиоданные.

#### Метаданные

FLAC определяет несколько типов блоков метаданных (все они перечислены на странице формат). Блоки метаданных могут быть любого размера, новые блоки могут быть легко добавлены. Декодер имеет возможность пропускать неизветные ему блоки метаданных. Обязателен только блок STREAMINFO. В нем содержится частота дискретизация, количество каналов и т.п., а также данные позволяющие декодеру настроить буфферы. Сюда также записывается подпись MD5 несжатых аудиоданных. Это полезно для проверки всего потока после его передачи.

Другие блоки предназначены для резервирования места, хранения таблиц точек поиска, а также данных для конкретных приложений. Опции для добавления блоков PADDING или точек поиска приведены ниже. FLAC не нуждается в точках поиска, однако они позволяют значительно увеличить скорость доступа, а также могут быть использования для расстановки меток в аудио редакторах.

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

#### Аудиоданные

За метаданным следуют сжатые аудиоданные. Метаданные и аудиоданные не чередуются. Как и большинство кодеков FLAC делит входной поток на блоки и кодирует их независимо друг от друга. Блок упаковыватся во фрейм и добавляется к потоку. Базовый енкодер использует блоки постоянного размера для всего потока, однако формат предусматривает наличие блоков разной длины в потоке.

#### Разбиение на блоки

Размер блока - очень важный параметр для кодирования. Если он очень мал, то в потоке будет слишком заголовков фреймов, что уменьшит уровень сжатия. Если размер большой, то енкодер не сможет подобрать эффективную модель сжатия. Понимание процесса моделирования поможет Вам увеличить уровень сжатия для некоторых типов входных данных. Обычно при использовании линейного прогнозирования на аудиоданных с частотой дискретизации 44.1 кГц оптимальный размер блока лежит в диапазоне 2-6 тысяч сэмплов. В этом случае значение по умолчанию - 4608. Если использовать быстрые постоянные предикторы, предпочтительнее меньшие размеры блоков, так как в этом случае размеры заголовков фреймов меньше.

#### Межканальная декорреляция

Если на вход поступают стерео аудиоданные, они могут пройти через стадию межканальной декорреляции. Правый и левый канал преобразуются к среднему и разностному по формулам: `средний = (левый + правый)/2`, `разностный = левый - правый`. В отличие от joint stereo этот процесс не приводит к потерям. Для данных с аудио компакт-дисков это обычно приводит к значительному увеличению уровня сжатия. Для включения использования этого метода кодирования `flac` имеет две опции: `-m` всегда делает разностную и независимую версию блока и выбирает наименьший фрейм и `-M`, которая адаптивно выбирает схему сжатия.

#### Моделирование

На следующем этапе енкодер пытается аппроксимировать сигнал такой функцией, чтобы полученный после ее вычитания из оригинала результат (называемый разностью, остатком, ошибкой) можно было закодировать минимальным количеством битов. Параметры функций тоже должны записываться, поэтому они не должны занимать много места. FLAC использует два метода формирования аппроксимаций: 1) подгонка простого полинома к сигналу и 2) общее кодирование с линейными предикторами (LPC).

Во-первых, постоянное полиномиальное предсказание (`-l 0`) работает значительно быстрее, но менее точно, чем LPC. Чем выше порядок LPC, тем медленнее, но лучше будет модель. Однако с увеличением порядка выигрыш будет все менее значительным. В некоторой точке (обычно около 9) процедура енкодера, определяющая наилучший порядок, начинает ошибаться и размер получаемых фреймов возрастает. Чтобы преодолеть это, можно использовать полный перебор (опция `-e`), что приведет к значительному увеличению времени кодирования.

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

#### Остаточное кодирование

Когда модель подобрана, енкодер вычитает приближение из оригинала, чтобы получить остаточный (ошибочный) сигнал, который затем кодируется без потерь. Для этого используется то обстоятельство, что разностный сигнал обычно имеет распределение Лапласа и есть набор специальный кодов Хаффмана, называемые кодами Райса, позволяющие эффективно и быстро кодировать эти сигналы без использования словаря.

Кодирование Райса состоит из нахождения одного параметра, отвечающего распределению сигнала, а затем использования его для составления кодов. При изменении распределения меняется и оптимальный параметр, поэтому имеется метод позволяющий пересчитывать его по необходимости. Остаток может быть разбит на контексты или разделы, у каждого из которых будет свой параметр Райса. `flac` позволяет указать, как нужно производить разбиение, с помощью опции `-r`. Остаток может быть разбит на 2^n раздела, если использовать `-r n,n`. Параметр n называется порядком раздела. Также енкодер может искать в пределах от m до n порядка, выбирая лучший вариант, если указать `-r m,n`. Обычно выбор n не влияет на скорость кодирования. От разницы между m и n сильно зависит время работы, чем она больше, тем больше времени будет затрачиваться на поиск лучшего порядка. Выбор размера блока также влияет на оптимальный порядок раздела.

#### Составление фреймов

Аудиофрейму предшествует заголовок, который начинается с кода синхронизации и содержит минимум информации, необходимой декодеру для воспроизведения потока. Сюда также записывается номер блока или сэмпла и восьмибитная контрольная сумма самого заголовка. Код синхронизации, CRC заголовка фрейма и номер блока/сэмпла позволяют осуществлять пересинхронизацию и поиск даже в отсутствие точек поиска. В конце фрейма записывается его шестнадцатибитная контрольная сумма. Если базовый декодер обнаружит ошибку, будет сгенерирован блок тишины.

#### Разное

Чтобы поддерживать основные типы метаданных, базовый декодер умеет пропускать теги ID3V1 и ID3V2, поэтому их можно свободно добавлять. Теги ID3V2 должны располагаться перед маркером "fLaC", а теги ID3V1 - в конце файла.

У `flac` есть опция (`-V`) для проверки выходных данных при кодировании. В этом случае декодер работает одновременно с енкодером и его выход сравнивается с оригинальным вводом. Если будет найдено отличие, `flac` закончит работу с сообщением об ошибке.

### `flac`

`flac` - это кодек, работающий из командной строки. Входом для енкодера и выходом для декодера должен быть либо данные в формате RIFF WAVE, либо поток сэмплов без заголовка. `flac` использует только линейные PCM сэмплы (другими словами, A-LAW, uLAW, и т.п. не поддерживаются). Следующим ограничением является то, что во кодируемом файле сэмплы должны быть 8, 16 или 24-битными. Это не ограничение формата, просто так работают базовый енкодер и декодер.

`flac` предполагает, что файлы RIFF WAVE имеют суффикс ".wav"; это умолчание может быть переопределено специальным ключом. Для данных, поступающих из потока, `flac` пытается определить тип, просматривая начало файла в поиске заголовка. В остальных случаях `flac` не делает предположений о суффиксах, хотя по соглашению файлы FLAC имеют суффикс ".flac" (или ".fla" на старых файловых системах таких как FAT-16).

Перед полным описанием ключей, используемых `flac`, обратим внимание на то что: 1) по умолчанию `flac` сжимает файлы (для декодирования используйте ключ `-d`); 2) ключи `-0..-9`, управляющие уровнем сжатия, являются синонимами для различных групп настроек кодирования. Того же эффекта можно добиться, используя наборы соответствующих ключей; 3) модель обработки входных и выходных файлов у `flac` аналогична `gzip`.

`flac` вызывается одним из четырех способов:

> - Кодирование:
>   `flac [-s] [--skip #] [<настройки_формата>] [<опции_кодирования>] [входной_файл [...]]`
> - Декодирование:
>   `flac -d [-s] [--skip #] [<настройки_формата>] [<опции_кодирования>] [входной_файл [...]]`
> - Тестирование:
>   `flac -t [-s] [входной_файл [...]]`
> - Анализ:
>   `flac -a [-s] [--skip #] [<опции_анализа>] [входной_файл [...]]`

В любом случае, если входной файл не указан, подразумевается стандартный ввод. Если указан только один входной файл, то это может быть "-" для стандартного ввода (stdin). Когда используется стандартный ввод, `flac` пишет в стандартный вывод (stdout). В остальных случаях `flac` выполнит указанные действия для каждого входного файла и запишет результаты в файлы с аналогичными именами (при кодировании суффикс будет заменен на ".flac" или, если его не было, будет добавлен; при декодировании суффиксы также изменяются в соответствии с типом выходных данных.) Оригинал удаляется, только если указан ключ `--delete-input-file`.

Существуют особые формы вызова процедур кодирования/декодирования из стандандартного ввода в файл.

> - `flac [опции] - выходной_файл`
> - `flac -d [опции] - выходной_файл`

> которые лучше чем

> - `flac [опции] > выходной_файл`
> - `flac -d [опции] > выходной_файл`

так как в первом случае сохраняется возможность произвести при необходимости последующую обработку файла, например для записи заголовков `RIFF WAVE` или `STREAMINFO`.

Данные в стандартный вывод можно перенаправить с помощью ключа `-c`.

Опции кодирования влияют на скорость работы и уровень сжатия. Настройки формата определяют расположение сэмплов, если на вход поступает файл без заголовка. Если у файла есть заголовок `RIFF WAVE`, то настойки формата не нужны, так как они берутся из файла.

В режиме тестирования `flac` работает как и при декодировании, только выходной файл не записывается. Режимы декодирования и тестирования проверяют поток на наличие ошибок, а также сравнивают подпись MD5 декодированного потока с сохраненной подписью, даже если формат потока правильный.

#### Основные ключи

`-d` | Декодирование (по умолчанию `flac` кодирует). `flac` завершит работу с кодом выхода `1`, если будет встречена ошибка или контрольная сумма MD5 декодированного потока не совпадет с сохраненной. Если ошибок не будет, код возврата будет равен `0`.
`-t` | Тестирование (то же самое, что и декодирование, только выход не записывается в файл). Коды возврата те же.
`-a` | Анализ (то же самое, что и декодирование, только выходом является файл статистики). Коды возврата те же. Режим предназначен в основном для разработчиков. В выходной текстовый файл записывается информация о каждом фрейме и подфрейме.
`-c` | Направить результат в стандартный вывод (stdout).
`-s` | Не показывать статистику при кодировании/декодировании.
`-o файл` | Явно указать имя выходного файла, по умолчанию `flac` просто заменяет суффикс.
`--output-prefix строка` | Добавляет префикс к каждому имени выходному файлу. Может имспользоваться для кодирования/декодирования файлов в другой каталог. Если указанная строка является частью пути, убедитесь, что она заканчивается слэшем '/'.
`--delete-input-file` | После успешного окончания кодирования/декодирования входной файл будет удален. Если произойдет ошибка, исходный файл останется.
`--skip #` | Пропустить первые `#` сэмплов входного файла. Работает для кодирования и декодирования, но не для тестирования.

#### Опции анализа

`--a-rtext` | Добавляет в файл остаточный сигнал. Результирующий файл получается очень большим.
`--a-rgp` | Создает файлы-диаграммы для каждого подфрейма. В каждом файле будет остаточное распределение для подфрейма. Будет создано очень много файлов.

#### Опции кодирования

`--lax` | Позволяет енкодеру создавать файлы, отвечающие подмножеству формата FLAC. В результате работы будет получаться непотоковый файл, поэтому этот ключ следует использовать только для архивирования. Декодер будет поддерживать воспроизведение и поиск в таких файлах.
`--sector-align` | При кодировании нескольких WAVE файлов формата CD-Audio выравнивать их на границу сектора. Эта опция применима только для кодирования нескольких WAVE файлов, каждый из которых должен иметь частоту дискретизации 44.1 кГц и два канала. Если будет указана эта опция енкодер выровняет потоки .flac так, что их длины будут кратны размеру сектора CD-Audio (равны 1/75 секундам или 588 сэмплам). Это осуществляется переносом части сектора в конце каждого WAVE файла в начало следующего. Последний поток будет дополнен до границы выравнивания нулями. Использование этой опции не приведет ни к чему, если файлы уже выровнены (например, если правильно скопированы с аудио-CD). `flac` может выровнять только несколько файлов за один вызов. ВНИМАНИЕ: Порядок файлов имеет значение! Если вы сделаете следующий вызов '`flac --sector-align *.wav`', командный процессор может обработать шаблон не в том порядке, в каком вы рассчитываете. Поэтому лучше всего вызывать программу, явно указав список файлов, например, '`flac --sector-align 8.wav 9.wav 10.wav`'.
`-S {#|X|#x}` | Добавляет точки для поиска в таблицу `SEEKTABLE`. `#` : создается точка поиска для сэмпла с определенным номером. `X` : резервируемые точки (всегда помещаются в конце `SEEKTABLE`). `#x` : # равномерно распределенных точек поиска, первая соответствует 0 сэмплу. Опцию `-S` можно использовать несколько раз. В результате получится объединенная таблица, в которой будут присутствовать только уникальные значения. По умолчанию `flac` использует `-S 100x`. Если таблица поиска не нужна, укажите `-S-`. ПРИМЕЧАНИЕ: `-S #x` не будет работать, если енкодер не сможет определить размер входного файла в начале работы. ПРИМЕЧАНИЕ: если # больше или равен количеству сэмплов во входном файле, то точки добавлены не будут, если размер можно определить до кодирования, в противном случае будут записаны резервируемые точки.
`-P #` | Eнкодер запишет блок метаданных `PADDING`, указанного размера (в байтах), после блока `STREAMINFO`. `-P 0` указывает, что блок `PADDING` не нужен (значение по умолчанию). Этот блок полезен, если вы собираетесь добавить тэг в файл позже. Вместо того, чтобы переписывать файл полностью, можно будет записать информацию вместо блока `PADDING`.
`-b #` | Устанавливает размер блока в сэмплах. По умолчанию `1152` для `-l 0`, иначе `4608`. Стандартные потоки должны использовать одно из указаных значений: `192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768`. Сейчас енкодер использует постоянный размер блока для всего файла.
`-m` | Включает разностное кодирование (только для стерео потоков). Обычно увеличивает уровень сжатия на несколько процентов. Для каждого блока создается усредненная и стерео версия блока, сохраняется блок меньшего размера. Сейчас разностное кодирование доступно для файлов, где сэмпл имеет размер не больше 16 бит.
`-M` | Включает свободное разностное кодирование (только для стерео потоков). Работает аналогично `-m`, однако енкодер переключается между независимым и усредняющим кодированием адаптивно. Метод работает быстрее, но уровень сжатия меньше, так как `-m` производит полный перебор вариантов.
`-0..-9` | Быстрейшее сжатие ... максимальное сжатие. По умолчанию `-5`.
`-0` | Аналогично `-l 0 -b 1152 -r 2,2`.
`-1` | Аналогично `-l 0 -b 1152 -r 2,2 -M`.
`-2` | Аналогично `-l 0 -b 1152 -r 3 -m`.
`-3` | Аналогично `-l 6 -b 4608 -r 3,3`
`-4` | Аналогично `-l 8 -b 4608 -r 3,3 -M`.
`-5` | Аналогично `-l 8 -b 4608 -r 3,3 -m`.
`-6` | Аналогично `-l 8 -b 4608 -r 4 -m`.
`-7` | Аналогично `-l 8 -b 4608 -r 6 -m -e`.
`-8` | Аналогично `-l 12 -b 4608 -r 6 -m -e`.
`-9` | Аналогично `-l 32 -b 4608 -r 16 -m -e -E -p`. Работает очень медленно, но достигается максимальный уровень сжатия для данного размера блока.
`-e` | Полный поиск модели (работает медленно!). Обычно енкодер определяет лучшую модель и кодирует далее опираясь на нее. В данном режиме енкодер будет создавать подфреймы всех порядков и использовать наименьший. Если максимальное значение порядка LPC велико, время кодирования существенно возрастет. Выигрыш обычно составляет около 0.5%.
`-E` | Использовать управляющие коды в кодере энтропии. Эта опция позволяет записывать незакодированное представление остатка в разделе, если его размер меньше. При этом время работы увеличивается, а уровень сжатия обычно улучшается примерно на 1%.
`-l #` | Определяет максимальный порядок LPC (коэффициентов линейного прогнозирования). Число должно быть меньше или равно `32`. Если значение равно `0`, енкодер будет использовать вместо общего линейного прогнозирования постоянные коэффициенты. Этот метод увеличивает скорость работы, но файлы получаются на 5-10% больше.
`-q #` | Определяет точность дискретных коэффициентов линейного прогнозирования в битах. По умолчанию `-q 0`, что позволяет енкодеру принимать решение в зависимости от сигнала. Лучше оставлять значение по умолчанию.
`-p` | Производить оптимизацию LPC. Переопределяет любую опцию `-q`. Сильно замедляет работу, и уменьшает размер файла на долю процента. `-q` не работает, когда используется `-l 0`.
`-r [#,]#` | Установить [min,]max порядок раздела. Если минимальное значение не указано, то оно устанавливается равным 0. По умолчанию енкодер один параметр Райса для всего остатка подфрейма. Если использовать эту опцию, остаток будет разделяться на 2^min# ... 2^max частей, для каждой из которых будет определен собственный параметр Райса. С увеличением параметра max выигрыш будет все меньше. Наиболее оптимальный вариант достигается при использовании `-r 2,2` (и больших значений для больших размеров блоков). При этом сжатие обычно увеличивается на 1.5%. Выбор оптимального значения можно произвести по формуле `размер_блока/(2^n)=128`. Максимальный уровень сжатия достигается при использовании `-r 0,16`.
`-R #` | Установить пределы поиска параметра Райса. По умолчанию 0. Кодер остатков будет искать наилучший параметр Райса в указанном пределе для каждого раздела остатков. Использование этой опции не дает большого выигрыша, но сильно замедляет работу. В результате, опции `-0` ... `-9` не используют ее.
`-V` | Проверять процесс сжатия. В данном случае `flac` создает параллельный декодер, раскодирующий выход енкодера и сравнивает результат с оригиналом. Если будет найдено несоответствие, кодирование прекратится. Время работы с этой опцией увеличивается, однако, при этом гарантируется, что файл будет правильно декодирован.
| `-S-`, `-m-`, `-V-`, `-e-`, `-E-`, `-p-`, `--lax-`, `--delete-input-file-`, `--sector-align` используются для отключения соответствующих опций.

#### Настройки формата

`-fb | -fl` | Определяет порядок байтов в файле без заголовка big-endian | little-endian.
`-fc n` | Определяет количество каналов в файле без заголовка.
`-fp n` | Определяет количество бит на сэмпл в файле без заголовка.
`-fs n` | Определяет количество сэмплов в секунду в файле без заголовка.
`-fu` | Указывает, что сэмплы в файле без заголовка беззнаковые (по умолчанию знаковые).
`-fr` | Воспринимать входной (или выходной при декодировании) файл как raw поток сэмплов вне зависимости от суффикса.
`-fw` | Воспринимать входной (или выходной при декодировании) файл как RIFF WAVE вне зависимости от суффикса.

### `metaflac`

`metaflac` - это редактор метаданных, работающий из командной строки. Сейчас он только выводит содержимое блоков метаданных во .flac файле, но скоро с его помощью можно будет вставлять, удалять и редактировать блоки.

Cейчас `metaflac` вызывается только одним способом:

`metaflac [-v] входной_файл`

Входным_файлом может быть "-" для стандартного ввода (stdin). если использовать `-v`, будет получен более подробный отчет.

### Плагин для XMMS

Для его установки необходимо скопировать `libxmms-flac.so` в каталог, где находятся плагины ввода XMMS (обычно `/usr/lib/xmms/Input`). Больше ничего настраивать не надо. Для воспроизведения .flac файлов перезапустите XMMS.

### Плагин для Winamp

Для его установки необходимо скопировать `in_flac.dll` в каталог, где находятся плагины ввода Winamp (обычно `/Plugins`). Больше ничего настраивать не надо. Для воспроизведения .flac файлов перезапустите Winamp.

### `libFLAC`

Библиотека `libFLAC` является реализацией на C базового енкодера и декодера. Используя эту библиотеку и написав немного кода, можно добавить поддержку FLAC в свою программу. Условия распространения - LGPL. Исходные коды библиотеки `libFLAC`, также как и консольного кодека и плагинов доступны, и могут послужить хорошим примером для использования.

`libFLAC` требует стандартную и математическую библиотеки для языка C. Потоки не используются, однако, так как `libFLAC` не использует глобальные переменные, библиотека должна быть thread-safe.

Интерфейс `libFLAC` описан в публичных заголовочных файлах в каталоге include/FLAC. Для использования скомпилированной библиотеки нужны только публичные заголовки. Обратите внимание на то, что код из src/libFLAC/, включая защищенные заголовочные файлы из src/libFLAC/include/ не нужен.

В основном использование `libFLAC` состоит в следующем:

1. Программа создает экземпляр енкодера или декодера с помощью функций `*_new()`.
2. Программа устанавливает параметры экземпляра и предоставляет ему обратные вызовы для чтения, записи, сообщения об ошибках и работы с метаданными с помощью функций `*_set_*()`.
3. Программа инициализирует экземпляр, проверяет параметры и готовится к кодированию/декодированию, используя функции `*_init()`.
4. Программа вызывает функции `*_process_*()` для кодирования или декодирования данных, которые в свою очередь делают обратные вызовы.
5. Программа завершает работу экземпляра функцией `*_finish()`, которая сбрасывает буферы ввода и вывода.
6. Экземпляр может быть использован снова либо удален функцией `*_delete()`.

Для декодирования `libFLAC` предоставляет два уровня доступа. На нижнем уровне находится декодер потоков, а на верхнем - файлов (являющийся в свою очередь оболочкой для потокового декодера). Интерфейсы описаны в файлах `stream_decoder.h` и `file_decoder.h` соответственно. Файловый декодер сам осуществляет обратные вызовы для чтения и предоставляет функции поиска. Енкодер пока что реализован только на потоковом уровне (`stream_encoder.h`).

Структуры и константы, относящиеся к формату, определены в файле `format.h`.

ДЕКОДЕР ПОТОКОВ

Сначала обсудим декодер потоков. Тип его экземпляра `FLAC__StreamDecoder`. Обычно в программе экземпляр создается вызовом `FLAC__stream_decoder_new()` и инициализируется `FLAC__stream_decoder_init()`. Программа также может предоставлять указатель client_data на `FLAC__stream_decoder_init()`, который будет использоваться для обратных вызовов.

- Обратный вызов для чтения. Эта функция вызывается, когда декодеру необходимы данные. В качестве параметров передается адрес буфера, который нужно заполнить, и его размер в байтах. Обратный вызов может вернуть меньше данных и изменить счетчик байтов, но не должен переполнять буфер. Код возврата при выходе выбирается из `FLAC__StreamDecoderReadStatus`.
- Обратный вызов для записи. Эта функция вызывается после декодирования одного фрейма данных. Декодер передаст метаданные фрейма, а также массив указателей (по одному на каждый канал) на декодированные данные.
- Обратный вызов для работы с метаданными. Функция вызывается после разбора блока метаданных. Для потока всегда должен существовать блок метаданных `STREAMINFO`, за которым может следовать произвольное количество других блоков. Они будут возвращены декодером в том же порядке, в каком они расположены в потоке и всегда перед первым аудио фреймом.
- Обратный вызов для сообщения об ошибке. Эта функция вызывается, если при декодировании происходит ошибка.

Когда декодер инициализирован, программа может вызвать одну из следующих функций для декодирования:

- `FLAC__stream_decoder_process_whole_stream()` - Декодер начинает работу и продолжает обрабатывать поток пока функция обратного вызова чтения не передаст код `FLAC__STREAM_DECODER_READ_END_OF_STREAM` или `FLAC__STREAM_DECODER_READ_ABORT`.
- `FLAC__stream_decoder_process_metadata()` - Декодер обрабатывает поток до первого аудио фрейма.
- `FLAC__stream_decoder_process_one_frame()` - Декодеровать только один фрейм. Перед вызовом этой функции все метаданные должны быть обработаны.
- `FLAC__stream_decoder_process_remaining_frames()` - Декодировать все оставшиеся фреймы. Перед вызовом этой функции все метаданные должны быть обработаны. Перед вызовом этой фунции также может вызываться `FLAC__stream_decoder_process_one_frame()`.

Когда декодер заканчивает работу, экземпляр обрабатывается функцией `FLAC__stream_decoder_finish()`, которая проверяет состояние декодера и освобождает память. Затем экземпляр может быть удален функцией `FLAC__stream_decoder_delete()` или инициализирован заново для декодирования другого потока.

Обратите внимание на то, что потоковый декодер не имеет представления о позиции в потоке, он только преобразовывает данные. Чтобы осуществлять поиск в потоке функции обратного вызова могут только сбрасывать данные декодера функцией `FLAC__stream_decoder_flush()` и начинать подавать данные с новой позиции с помощью обратного вызова для чтения. Декодер файлов поступает именно так.

ДЕКОДЕР ФАЙЛОВ

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

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

Декодер файлов также предоставляет проверку подписи MD5. Если эта возможность будет включена перед инициализацией, `FLAC__file_decoder_finish()` сообщит, если подпись MD5 распакованных данных не совпадет с сохраненной в блоке STREAMINFO. Проверка MD5 автоматически выключается, если в блоке STREAMINFO нет подписи или при попытке осуществления поиска.

ЕНКОДЕР ПОТОКОВ

Енкодер потоков работает аналогично декодеру, однако имеет меньше обратных вызовов и больше опций. Тип экземпляра - `FLAC__StreamEncoder`. Для создания нового экземпляра в программе нужно вызвать функцию `FLAC__stream_encoder_new()`, а чтобы проинициализировать его - `FLAC__stream_encoder_init()`.

В отличие от процесса декодирования кодирование в формат FLAC имеет множество опций, влияющих на скорость и уровень сжатия. Когда программа вызывает `FLAC__stream_encoder_init()`, енкодер проверяет значения, поэтому необходимо убедиться, что возвращемое этой функцией значение - `FLAC__STREAM_ENCODER_OK`. Для установки параметров нужно иметь некоторое представление о формате (см. описание формата для пользователя или его формальное описание). Список необходимых параметров приведен здесь:

- `streamable_subset` - `истина`, если необходимо, чтобы выход соответствовал потоковому подмножеству формата, иначе `ложь`.
- `do_mid_side_stereo` - `истина`, если нужно использовать усредненное кодирование для стерео потоков. Значение `channels` должно быть `2`.
- `loose_mid_side_stereo` - `истина`, чтобы применить адаптивное переключение режима усредненного кодирования, иначе ложь. `do_mid_side_stereo` должно быть истина.
- `channels` (количество каналов) - должно быть <= `FLAC__MAX_CHANNELS`.
- `bits_per_sample` - количество битов на сэмпл.
- `sample_rate` (частота дискретизации) - должно быть <= `FLAC__MAX_SAMPLE_RATE`.
- `blocksize` (размер блока) - должен быть между `FLAC__MIN_BLOCKSIZE` и `FLAC__MAX_BLOCKSIZE`.
- `max_lpc_order` (максимальный порядок коэффициентов линейного прогнозирования) - `0` указывает, что енкодер не должен использовать LPC, а только постоянные предикторы. Должно быть <= `FLAC__MAX_LPC_ORDER`.
- `qlp_coeff_precision` - должно быть >= `FLAC__MIN_QLP_COEFF_PRECISION`, или `0`, чтобы енкодер мог выбирать коэффициенты в зависимости от размера блока. В текущей реализации сумма `qlp_coeff_precision`+`bits_per_sample` должна быть < `32`.
- `do_qlp_coeff_prec_search` - `ложь`, чтобы использовать заданное значение `qlp_coeff_precision`; `истина` для поиска и выбора лучшего значения `qlp_coeff_precision`.
- `do_escape_coding` - истина, если нужно искать управляющий код на стадии кодирования энтропии для небольшого увеличения уровня сжатия.
- `do_exhaustive_model_search` (производить полный поиск наилучшей модели) - `ложь`, to use estimated bits per residual for scoring; `истина` для перебора всех возможных вариантов и выбора наилучшего.
- `min_residual_partition_order` (минимальный порядок раздела остатков), `max_residual_partition_order` (максимальный порядок раздела остатков)= `0`, чтобы оценивать параметр Райса основываясь на дисперсии остатков; > `0` для разделения остатков и определения параметра для каждого раздела, основываясь на среднем. `min_residual_partition_order` и `max_residual_partition_order` определяют минимальный и максимальный порядок раздела Райса.
- `rice_parameter_search_dist` (интервал для поиска параметра Райса) - `0`, чтобы использовать только вычисленный параметр `k`; иначе пытаться кодировать со всеми параметрами из интервала [`k`-`rice_parameter_search_dist`..`k`+`rice_parameter_search_dist`] и выбирать лучший вариант.
- `total_samples_estimate` (количество сэмплов) - Может равняться `0`, если неизвестно. Иначе указывается количество сэмплов, которое нужно закодировать. Это позволяет создавать более точный блок `STREAMINFO` при первом же проходе в случае, когда енкодер не может вернуться к началу вывода, чтобы обновить блок `STREAMINFO`.
- `seek_table` (таблица для поиска) - создать необязательную таблицу для поиска в файле. `NULL` указывает, что таблица не нужна.
- `padding` (резервирование места) - размер блока `PADDING` (следует за таблицей для поиска); `0` означает, что блок `PADDING` добавлять не нужно.

Программа должна предоставить `FLAC__stream_encoder_init()` адреса для следующих обратных вызовов:

- Обратный вызов для записи. Вызывается, когда появляются закодированные данные для записи. Это могут быть метаданные смешанные с аудио фреймами, причем не гарантируется, что данные будут выровнены на границу блока метаданных или фрейма.
- Обратный вызов для работы с метаданными. Вызывается однажды по завершении кодирования с populated структурой `STREAMINFO`. Это нужно для того, чтобы енкодеры файлов могли вернуться к началу файла и записать в блок `STREAMINFO` корректные данные о кодировании, например минимальный и максимальный размер фрейма.

Вызов `FLAC__stream_encoder_init()` непосредственно производит обратный вызов для записи сигнатуры "fLaC" и всех определенных на данный момент метаданных.

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

- Разделенными по каналам через `FLAC__stream_encoder_process()`. В этом случае нужно определить массив указателей на буфферы одинакового размера, по одному на каждый канал. Выравнивать сэмплы на границу блока не нужно.
- В чередующихся каналах через `FLAC__stream_encoder_process_interleaved()`. Программа должна передать один указатель на аудио данные с чередующимися каналами (например, `канал0_сэмпл0, канал1_сэмпл0, ... , каналN_сэмпл0, канал0_сэмпл1, ...`). Данные могут быть не выровнены на границу блока, но должны быть выровнены на границу сэмпла, т.е. первым значением должно быть `канал0_сэмплX`, а последним - `каналN_сэмплY`.

Для завершения кодирования данных программа вызывает функцию `FLAC__stream_encoder_finish()`, которая кодирует оставшиеся данные из входного потока и делает обратный вызов для работы с метаданными с корректной статистикой о процессе кодирования. Экземпляр может быть удален функцией `FLAC__stream_encoder_delete()` или инициализирован снова для кодирования нового потока.

РАЗНОЕ

Необходимо отметить, что когда передаются указатели на аудио данные, их порядок имеет значение только для стерео потоков. Канал `0` соответствует левому каналу, а `1` - правому.

МЕТАДАННЫЕ

Программы, записывающие свои блоки метаданных `APPLICATION`, могут указать енкодеру, чтобы он записал блок метаданных `PADDING` нужного размера. В этом случае вместо перезаписи всего потока после кодирования программа сможет просто заменить блок `PADDING` на свой. Если известен только максимальный размер блока `APPLICATION`, программа может создать резервный блок чуть большего размера, а после кодирования разделить его на блоки `APPLICATION` и `PADDING`.

Если размер блока метаданных `APPLICATION` известен заранее, размер резервируемой области может быть легко вычеслен. Если размер блока `APPLICATION` (не включая заголовок блока) равен `N` байтам, то экземпляру FLAC__StreamEncoder перед инициализацией нужно передать значение `N+4`. Это нужно, чтобы учесть дополнительное место необходимое для хранения идентификатора приложения.

Когда известен только максимальный размер, скажем, `N` байт, нужно зарезервировать `N+8` байт. Четыре для ID приложения и четыре для дополнительного блока `PADDING`, который заполнит оставшееся пространство. По окончании кодирования, когда размер блока данных `APPLICATION` становится известной и равной, допустим, `M` байтам, на место первоначального блока `PADDING` будет записан блок `APPLICATION` и блок `PADDING` длиной `N-M` байтов.

### Известные ошибки

Отслеживание ошибок ведется на этой странице проекта, находящейся на SourceForge. Если Вы будете сообщать об ошибке, пожалуйста, оставьте e-mail для контакта.

Copyright (c) 2001 Josh Coalson