Посты

Голосовой кодек codec2 и его установка на Mac

Меня тут заинтересовала задачка о передаче голоса по радио, да не просто так, а на bleeding edge современных технологий.

Как вы думаете, насколько сильно можно сжать аудиопоток с речью, не очень потеряв в качестве? 64 кбит/с, как в стандарте для телефонной связи? 32 кбит/с, реальный минимум для mp3? Окей, может быть 13 кбит/с, как в GSM?

Кодек codec2 даёт возможность сжать голос до умопомрачительных 1.2 кбит/с, причём вы можете даже практически не заметить разницы, особенно в шумном окружении. И это не всё, есть ещё и тариф для настоящих скупердяев с битрейтом 700 БИТ В СЕКУНДУ!

UDP-передача в библиотеке lwIP для STM32

UDP-протокол — самый простой протокол для передачи данных, благодаря которому устройства могут обмениваться информацией, не создавая отдельного соединения. Да, это не гарантирует надёжности доставки, но зато вам не требуется инициализация подключения (как в TCP) и хранения данных о нём в дескрипторе соединения. Таким образом экономится как flash, так и оперативная память, и более того передача становится немного быстрее (потому что мы пропускаем этап рукопожатия TCP).

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

Но тогда для чего может быть полезен UDP? Во-первых, это многочисленные протоколы для передачи некритичных данных, таких как Telnet или Syslog. Даже если вы потеряете одну строчку лога какого-то события — зачастую это не стоит того, чтобы запрашивать её вновь (как в TCP).

Predefined macros в компиляторе IAR

Во многих компиляторах C есть такая штука как predefined macros — предзаданные (встроенные) макросы.

Как и обычные макросы, их раскрывает препроцессор на самом первом этапе сборки кода. Поэтому эти макросы рассматриваются именно с позиции конкретного файла исходного кода, и конкретной текущей строки.

Среди них макросы даты и времени:

  • __DATE__ — текущая дата в формате «May 20 2015″. Дни меньше 10 числа месяца будут дополнены пробелом слева.
  • __TIME__ — текущее время в формате «13:20″. В IAR это только часы и минуты, а в GCC добавлены секунды.

Дата и время, конечно же, текущие на момент трансляции файла.

И макросы, указывающие на файл и строку в нём:

  • __MODULE__ — короткое имя текущего файла, типа того как указывается в директиве #include.
  • __FILE__ — полный путь к текущему файлу. Не короткое имя, как в __MODULE__, а именно полный путь.
  • __LINE__ — номер строки, вместо этого макроса подставляется номер строки в которой он находится, в виде десятичного числа. Необычный макрос, который изменяется (инкрементируется) с каждой новой строкой.

Макросы __FILE__ и __LINE__ очень удобны для отладки, поскольку вы можете выводить отладочные сообщения или сообщения об ошибках сразу с прямым указанием на положение ошибочного места в коде. Это может выглядеть, например, так:

printf("Serious error occurred in file %s, line %d\n", __FILE__, __LINE__);

Я думаю, что их можно сразу добавить в функцию DEBUG_PRINTF для Syslog — можно будет в веб-интерфейсе логгера видеть файл и строку для каждого сообщения.

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

  • __TARGET_ARCH_xx и
  • __TARGET_CPU_xx

Это самые полезные предопределённые макросы, а об остальных макросах вы можете прочитать на сайте ARM.

SysLog — протокол журналирования сообщений

Продолжая тему ведения журналов событий и отладки, поговорим про Syslog. Это протокол передачи текстовых сообщений, прежде всего логов — сообщений о происходящих событиях, разработанный в 1980 году. Формат этого протокола очень прост и удобен, и практически не изменился за последние 35 лет.

Формат достаточно гибок, и предусматривает отправку как простых текстовых сообщений:

Use the BFG!

(но надо сказать что информативность в таких сообщениях практически отсутствует), так и более сложных, включающих в себя маркер уровня важности, метку времени и текстовый комментарий:

<13> Feb 5 17:32:18 10.0.0.9 Use the BFG!

Стандарт рассматривает также отправку ещё более сложных сообщений, в том числе со специальными указаниями для дальнейшей пересылки, но суть остаётся прежней — это всё то же текстовое сообщение не длиннее 1 килобайта, отправленное на порт 514 (UDP) / 6514 (UDP) или 601 (TCP) / 6514 (TCP).

Сжатие данных в микроконтроллере, DEFLATE и библиотека miniz

Когда речь заходит о передаче больших объёмов информации, особенно текстовой, логично вспомнить о сжатии данных. Существует множество алгоритмов сжатия, многие из которых имеют давнюю историю, некоторые алгоритмы вплотную подбираются к теоретическому пределу степени сжатия — но требуют много времени и памяти, другие работают быстро и скверно, какие-то из них прямо предназначены для определённых типов данных, но стандартом в HTTP давно стал gzip.

Этот формат воплощает метод DEFLATE, который базируется на двух базовых алгоритмах: LZ77 и кодировании Хаффмана.

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

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

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

Эти алгоритмы можно использовать, к примеру, для сжатия JSON-сообщений — в типичном случае вы получите степень сжатия от 30% (для коротких сообщений) до 2 раз (если сообщение длиннее 500 байт) и больше.