• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

нужна помощь! Как увеличить TCP_WND в ESP8666/Arduino?

pvvx

Активный участник сообщества
Да, со скоростью это вопрос. Во-первых, когда потерь пакетов нет, или они минимальные - то даже мой "сложный" поток (Soma.FM кстати, можете сами потестить) воспроизводится стабильно, и даже постепенно буфер заполняет. Правда, как только что-то там теряется, то буфер довольно быстро снова опустошается(
Во-вторых, на других, более "быстрых" потоках (http://radio.mv.ru:8080/Radio_Cafe например, рекомендую)) буфер наполняется почти моментально, и его хватает даже при периодически потерях, тем более что сами потери восполняются гораздо быстрее.
Предполагаю, что на эту картину настройки буферизации сервера влияют. Т.е. если на сервере выделен достаточный буфер передачи, то он его выгружает на клиента, и как раз его содержимое накапливается в моем кольцевом буфере. Т.е. буфер передачи транслируется несколько быстрее стандартной скорости потока.
Этого не может быть. Просто выделен больший буфер и при соединении вам отдается более старые по времени семплы. Делается как раз для того, чтобы иметь запас на разность скорости воспроизведения у вас и трансляции до "шва". Шов на сервере обычно выполняется в паузу или вставляется заставка... Некоторые могут перекодировать поток с учетом вашей скорости.
Словом, подстройка скорости - оно может и правильно, но в нашем случае непонятно как делать.
Если у вас нет возможности управлять выходным, уже декодированным потоком на DAC, то декодируйте и пережимайте поток до вашей любимой микросхемы сами.
 

pvvx

Активный участник сообщества
Алгоритм подстройки скорости процесс нетривиальный и зависит от многих факторов. Можно выработать наипростейший, основанный на заполнении буфера. Тогда вам надо задать изначально слегка большую скорость вывода, и так и проигрывать, пока заполнение буфера не начет уменьшаться относительно подобранной под условия уже сетевых ошибок. К примеру взять порог на 75%. При уменьшении заполнения ниже этого threshold уровня постепенно вставлять дополнительные семплы... Но это совсем примитивный алгоритм, не учитывающий множество других проблем.
 

pvvx

Активный участник сообщества
При нормальном кварце, а не стекляшке и когда дискретизация потока кратна выходному, тыркался вроде с RTL MP3 для RTLDuino… Выходило, что поток канала расходится не ранее пары часов проигрывания. Сейчас уже не помню точно, но вроде в RTL MP3 для RTLDuino пытался модифицировать корректор скорости, но ничего хорошего на все случаи не вышло, хотя управление учитывает не только буфер TCP, а и декодированные фреймы из потока. В потоке идет не только звук… Оставил в каком-то кривом состоянии – для Arduino это пофиг. (Зато в ручную крутить скорость - прикольно :))

Во многих видах сжатия внутренние разложенные фреймы можно дублировать, что не сильно влияет на выходной звук – ну будет повтор пары основных частот которые выдает кодек в какие-то микросекунды и что от этого на не HiFi проигрывателе? Форматы сжатия выкидывают всё остальное, что не относится к паре основных частот от разложения входного сигнала на определенное окно по времени… и дублирование этого окна или вырезки вы не заметите среди выходного звука в виде шума на проигрывателе с VS1053.
 

pvvx

Активный участник сообщества
Ну а к чему я веду – в любом декодере есть внутренние коэффициенты, на уровне формирования выходного буфера уже (4-х битного PCM c экспонентой :)) и лучше там там корректировать скорость, а не дискретно выбивать/вставлять отсчеты в DAC.

Приделайте к VS1053 костыль, в виде управляемого генератора вместо кварца :)
 

думка

New member
Да, темка с синхронизацией действительно весьма нетривиальная и заслуживает размышлений. Хотя у меня , в первом приближении, складывается мнение, что проще эту подстройку делать на стороне сервера, использую заполненность TCP-окна клиента как показатель. Думаю, так проще было бы исключить влияние потерь пакетов, не учитывая их при расчете скорости потока.
А вот заполненность кольцевого буфера на клиенте, при наличии потерь - косвенный показатель, и напрямую с ним работать не получится, нужно эти потери както учитывать. Я бы не хотел, чтобы звук начинал плавать в зависимости от качества приема. Мне кажется, это неправильно)
Думаю, надо бы углубиться еще в эту тему, и посмотреть, как в приличных плеерах эти проблемы решаются. На ПК или андроидах. Но это попозже, а сначала попробую с потерями еще побороться)
 

pvvx

Активный участник сообщества
Думаю, надо бы углубиться еще в эту тему, и посмотреть, как в приличных плеерах эти проблемы решаются. На ПК или андроидах. Но это попозже, а сначала попробую с потерями еще побороться)
"Потери" у вас с большой вероятностью именно от этого. Сервер просто не выдает новый пакет, пока не выйдет время его следования.
Я бы не хотел, чтобы звук начинал плавать в зависимости от качества приема. Мне кажется, это неправильно)
Он не "плавает", а выводится с правильной скоростью.
И как пример - попробуйте вставлять (дублировать) каждый 200-й семпл. Это изменит скорость на 1/200. Вы это заметите? :)
 

pvvx

Активный участник сообщества
На ПК или андроидах.
Там это совсем пофигу, т.к. буфер не менее 200 килобайт для самого низкого битрейта и до "шва" в трансляции на такое значение кварцы не разбегутся.
Например ваша ссылка http://radio.mv.ru:8080/Radio_Cafe открывается 4+ секунды. Т.е. буферизирует поток не менее чем на 4 сек. Время вывода "фрагмента" в среднем не более 10 минут. Т.е. допуск отклонения 100*4/600 = 0.7%, что уже достаточно для RC генератора со стабилизацией :) Типа третий знак, а уход у кварцев-стекляшек - до 4 десятичный знак.
Неправильный начальный подход к выбору компонентов... Есть ли смысл борьбы "с ветряными мельницами"?
 

pvvx

Активный участник сообщества
Возьмем простейший пример построения stereo sound HiFi колонок с нормальным звуком:
Это 2 выхода GPIO ключей из какого SoC коммутируемых для DSD 128 в 5.6448 Mbit/s, подключенных каждый к паре транзисторов (мостовая схема) и динамикам. Больше компонентов не требуется.
Wifi (даже у ESP8266) обеспечивает TCP поток немного более 1 мегабайт в сек при CLK CPU 160 MHz. Это за 10 Mbit/s и успевает принимать такой поток на древний одно-антенный модуль 2.4 ГГц (PHY у ESP8266 72 Мбит/с !!! ).
I2S дает и больший битрейт (но джиттер у ESP несовместим с HiFi и у ESP нет двух каналов вывода DSD, но есть и выше 32 Mbit/s у более дешевых микросхем).
 

pvvx

Активный участник сообщества
@думка - В итоге вы тратите время своей жизни на борьбу с причудами детского лепета в Arduino и морально-техническими устаревшими технологиями. Это называется “некромантией” – делать зомби из трупиков…
 

enjoynering

Well-known member
До WireShark руки пока не дошли. Но пробовал использовать IwIP v1.4. С ним действительно стабильнее на 320kbps (со стандартным окном) и больше свободного heap. Перенес весь код драйвера VS1053 отвечающий за наполнение буфера в IRAM. В место digitalRead() и digitalWrite() стал писать в регистры ESP8266 на прямую. 320kbps перестал рваться, главное правильно расставить optimistic_yield(xxx). Теперь можно пробовать экран прикрутить по SPI. :)
 
Сверху Снизу