В бета-версии Telegram для Android 13.0.3 (сборка 7179) записанное голосовое можно было отправить текстом: кнопка «Aa» рядом с паузой расшифровывала запись ещё до отправки, а пользователь выбирал, что уйдёт собеседнику — текст или сам звук. Функцию отметили как доступную только с Premium. Позже расшифровку из беты убрали как временный эксперимент одного из разработчиков; второе нововведение той же сборки осталось — экспериментальная запись голосовых с шумоподавлением на нейросети RNNoise. Касается это тех, кто ставит бету: в стабильной 13.0.2 нет ни того, ни другого.
Как это выглядело в бете
Кнопка «Aa» появлялась в режиме закреплённой записи — когда палец во время записи сдвигают вверх от значка микрофона и запись продолжается без удержания. Нажатие на «Aa» показывало расшифровку, дальше оставалось выбрать, что отправить. Если голосовое дописывали или обрезали, бета предлагала расшифровать его заново.
Запись с шумоподавлением включается в экспериментальных настройках беты. Шум убирается из звука до того, как он сжимается в Opus — формат, в котором Telegram хранит и пересылает голосовые. Предупреждение из той же сборки: шумоподавление может испортить запись музыки и очень тихой речи. Напеть мелодию в голосовом с этим режимом — плохая идея: для сети музыка выглядит как шум, о причине ниже.
Почему расшифровка до отправки — новая механика
Расшифровка голосовых в Telegram есть давно, но только для сообщений, которые уже лежат в чате. Её делает сервер: клиент вызывает метод messages.transcribeAudio, и у метода два параметра — чат и номер сообщения в нём. Ответ приходит с идентификатором расшифровки и текстом; длинная запись может вернуться с пометкой «в работе», и тогда текст дописывается отдельными обновлениями updateTranscribedAudio.
У неотправленной записи номера сообщения нет, поэтому этот метод к ней неприменим. Метода, который принимал бы сам файл, нет ни в публичной схеме API (TDLib на 8 октября), ни в исходниках Android 13.0.2 со слоем 231. Системный распознаватель речи Android (android.speech) в коде 13.0.2 тоже не используется.
Как бета обходила это ограничение, по открытым артефактам не видно: исходники сборки 13.0.3 не опубликованы, репозиторий заканчивается на 13.0.2 (7175), выложенной 13 октября. Строк новой кнопки нет и на платформе переводов — это сходится с версией про личный эксперимент, который не дошёл до локализации. Гипотеза, а не факт из кода: распознавание шло либо через серверный метод, которого ещё нет в публичной схеме, либо на самом устройстве.
Кому расшифровка доступна сейчас
Для полученных голосовых правила видны в коде клиента. Расшифровка без ограничений входит в Premium — в описании подписки это строка про расшифровку любого входящего голосового. Без Premium сервер выдаёт пробные расшифровки: их число в неделю и предельную длину записи клиент читает из серверной конфигурации, ключи transcribe_audio_trial_weekly_number и transcribe_audio_trial_duration_max. Предел длины в октябрьских снимках конфигурации — 300 секунд, число пробных в неделю менялось между 0 и 2. Когда пробные кончаются, клиент показывает дату, до которой ждать, или предлагает Premium.
Как устроен RNNoise
RNNoise — открытая библиотека шумоподавления от Xiph.Org под лицензией BSD. Автор — Жан-Марк Валин, один из создателей кодека Opus; устройство описано в его статье 2017 года.
Подход гибридный. Классическая обработка сигнала режет звук на кадры по 10 мс (480 отсчётов при 48 кГц) и раскладывает спектр каждого кадра на 22 полосы, по ширине близкие к тому, как частоты различает слух. Небольшая рекуррентная сеть — такая, что помнит предыдущие кадры, — смотрит на признаки полос и для каждой выдаёт коэффициент от 0 до 1: сколько энергии в этой полосе оставить. Отдельный фильтр по высоте тона подчищает шум между гармониками голоса. Попутно сеть выдаёт вероятность того, что в кадре вообще есть речь.
Сеть управляет 22 коэффициентами, а не сотнями частотных отсчётов, поэтому она маленькая и работает в реальном времени на процессоре телефона. Обратная сторона — обучали её отделять речь от шума, и всё, что на речь не похоже, она считает шумом. Отсюда предупреждение про музыку; тихий голос теряется по той же причине — его признаки в полосах близки к фону.
RNNoise уже был в приложении
Библиотеку не пришлось добавлять. Исходники лежат в репозитории Android-клиента в jni/voip/rnnoise, собираются в статическую библиотеку и вшиваются в основную нативную библиотеку приложения. Работала она до сих пор в видеочатах: звонковый модуль пропускает каждый кадр с микрофона через RNNoise, берёт оценку речи для индикатора говорящего и подменяет звук очищенным, когда в настройках видеочата включено «Шумоподавление».
Голосовые сообщения клиент пишет с микрофона в моно на 48 кГц и сжимает кодером Opus в режиме для голоса. Частота записи совпадает с той, на которой работает RNNoise, так что эксперимент беты сводится к одному звену между микрофоном и кодером — тому самому, которое в видеочатах стоит давно.




