Zvukovik & Nullpath
Zvukovik Zvukovik
Привет, я тут немного поколдовала с адаптивным кодеком квантования – он сохраняет чёткость среднего диапазона, при этом снижая полосу пропускания. Интересно, как бы ты спроектировал распределённую систему для потоковой передачи этого звука в реальном времени, чтобы задержки были минимальными?
Nullpath Nullpath
Чтобы задержка была минимальной, разбей поток на микрофрагменты, скажем, кадры по 10 миллисекунд. Запусти кодек на легковесном процессе, который берёт кадр, квантует его и отправляет в брокер ZeroMQ. На принимающей стороне один поток снимает данные из очереди, декодирует их и подгружает в аудио-буфер с низкой задержкой. Используй UDP для передачи, добавь номера последовательности и отбрасывай устаревшие пакеты. Держи сеть как можно ближе к границе; если нужна избыточность, пусть второй брокер дублирует поток, но активируй его только если потеря пакетов превышает 1%. Так ты получишь адаптивное качество и мгновенную доставку.
Zvukovik Zvukovik
Звучит неплохо, но 10 миллисекундные кадры всё равно немного громоздки для аудио высокого разрешения; будет слышно артефакты, если кодек даст сбой. Подумай о 2–3 миллисекундных окнах и более надёжном буфере джиттера. UDP + zeroMQ тоже подойдет, но сам брокер может стать узким местом — попробуй использовать разделяемую память с кольцевым буфером, если узлы на одном хосте. И просто отбрасывать пакеты без уведомления испортит восприятие качества; лучше добавить простую коррекцию ошибок, чем просто отбрасывать кадр. Идея с дополнительным брокером умная, но убедись, что при переключении не будет сдвига по синхронизации.
Nullpath Nullpath
Получил параметры. Переходим на кадры по 3 мс, оставляем буфер джиттера в 30 мс и используем общий буфер памяти, если узлы находятся на одном хосте. Применяем FEC Reed-Solomon для каждого блока, чтобы восстанавливать потерянные кадры, а не отбрасывать их. Для брокера переключения при выходе из строя, фиксируем последовательность и ставим монотонную метку времени для потока; когда резервный брокер берет на себя, синхронизируемся по этой метке, чтобы избежать расхождения. Это должно сделать артефакты незаметными и поддерживать низкую задержку.
Zvukovik Zvukovik
Замечательная доработка – 3 миллисекунды уже лучше, но не забудь про look-ahead кодека. Если ты всё ещё используешь буфер в 30 миллисекунд, у тебя будет 9 миллисекунд времени на предварительную декодировку. Для большинства сетей этого достаточно, но любой скачок джиттера больше 5 миллисекунд запустит цепную реакцию. Да, и Reed–Solomon на каждом блоке в 3 миллисекунды добавляет накладные расходы; они ощутимы, если размер твоих пакетов всего несколько сотен байт. Подумай о группировке нескольких кадров в один блок FEC, чтобы сбалансировать задержку и надёжность. Захват метки времени при переключении работает хорошо, просто убедись, что счётчик монотонности – 64-битный, чтобы избежать переполнения при длительных сеансах. В целом, ты двигаешься в правильном направлении – просто следи за накладными расходами.
Nullpath Nullpath
Понял. Объединяем кадры третьей группы в один FEC-пакет, используем 64-битный монотонный счетчик для синхронизации при переключении, и подтягиваем буфер джиттера до 5 миллисекунд. Так мы находим баланс между накладными расходами и задержкой.