Делаем с ИИ интернет-радиоприемник на базе ESP32-S3 за один вечер

Всем привет, дорогие читатели! Расскажу вам о том как сделать интернет-радио на «скорую руку» без особых хлопот.

Типизированный язык программирования

Всем привет, дорогие читатели! Расскажу вам о том как сделать интернет-радио на «скорую руку» без особых хлопот.

Ключевые аспекты проектирования и реализации SCADA-систем в автоматизированных системах управления технологическими процессами (АСУТП). Основное внимание уделяется интеграции с базами данных, такими как SQL Server, и использованию протокола OPC UA для взаимодействия с контроллерами.
Рассматривается процесс подключения к контроллерам с использованием библиотеки open62541, включая настройку безопасности и создание подписок для мониторинга данных.

В прошлую пятницу я объяснял джуну, почему его код на отсортированном массиве работает в шесть раз быстрее, чем на неотсортированном. Тот же массив, тот же алгоритм, и те же данные. Просто в другом порядке. Джун смотрел на меня как на сумасшедшего и, честно говоря, я его понимаю.
Потому что ответ звучит безумно: процессор внутри вашего ноутбука постоянно пытается предсказать будущее. Буквально. Он гадает, какая ветка if выполнится ещё до того, как условие будет вычислено. И на отсортированных данных ему угадывать проще.
Ну, давайте разбираться.

Логирование есть практически в каждом C++ проекте. Почти любой сервис, демон или библиотека рано или поздно обрастает строками вроде LOG_INFO(...) или logger.debug(...).
Чаще всего библиотека выбирается по привычке или популярности — spdlog, quill, easylogging++ и т.п. При этом редко кто проверяет, какую цену приложение платит за логирование.
В высоконагруженных системах логирование может выполняться:

В конце 2020 года я купил MacBook Pro 13 на процессоре Apple M1, очень хотелось испытать процессоры на архитектуре ARM. Почти сразу на чипе Apple M1 был найден вычислительный блок для матричных операций Apple AMX. Для Apple AMX не было документации, он не использовался в Apple Accelerate, но несколько энтузиастов занимались реверс-инжинирингом и анализом производительности ("https://github.com/corsix/amx").
В 2024 году вышли компьютеры на базе семейства процессоров Apple M4, у которых блок AMX задействован для выполнения инструкций из Scalable Matrix Extension 2 (сайт ARM недоступен в РФ) (ARM SME2).
В статье рассмотрим использование расширения ARM SME2 на примере умножения заполненных матриц. Увидим, как выжать максимум из процессора и получить прирост производительности в десятки раз.

Привет, Хабр! Я — Владимир Балун, и это — вторая часть материала о пакете с отпугивающим названием «unsafe» в Go и том, чем он может быть реально полезен. В первой части мы рассмотрели его содержимое, особенности и нюансы, оптимизации кода с использованием unsafe — все это вы можете освежить в памяти по ссылке.
Сегодня перейдем непосредственно к той самой «магии»: трюки, хаки, советы и лучшие практики с моей стороны.

Итак, я решил довести до реально работающего проекта превосходный эмулятор синтезатора Roland JV880. Это рэковый модуль (без клавиатурный), сделанный на базе синтезатора JV80. Соответственно он поддерживает все карты расширения этого синтезатора и почти все MIDI команды.

Это не отдельная статья, а продолжение статьи про теорию объектов в с++, почему объекты в плюсах такие какие есть. Все завершенные главы я также выкладываю на github'e в английском и русском варианте. Продолжаем разбираться в теории С++...
Отдельного разговора заслуживает идентичность объектов, потому что в реальном мире конкретные сущности обладают идентичностью и Сократ останется Сократом независимо от того, перекрасил ли он волосы, сменил адрес или умер, а государство остаётся тем же государством, даже если меняет флаг, конституцию или размер населения.
Чтобы отразить это в программе, объекты, представляющие конкретные сущности, нуждаются в своём определении идентичности, которая отделена от текущего состояния. Удобный способ ввести такую идентичность будет сделать некий токен идентичности, уникальное значение, которое выражает "кто это", а не "в каком он сейчас состоянии". Таким токеном может быть, например, адрес объекта в памяти, индекс в массиве, или табельный номер сотрудника в кадровой системе и проверяя равенство токенов идентичности, мы фактически проверяем тождественность объектов: один и тот же объект или разные.
На протяжении жизни программы конкретный объект может менять свои токены идентичности, потому что его могут переместить в другой участок памяти или переложить из одного контейнера в другой, или назначить ему новый идентификатор, но логическая идентичность сохраняется, если мы поддерживаем сопоставление между "старым" и "новым" токеном.

Множество Мандельброта. 80-бит FPU x87. OpenMP - параллельным программированием на уровне многопоточности. Синий, зеленый и красный - синусоидальными и косинусоидальными волнами: 127 + 127 cos(2 PI a / 255) и 127 + 127 sin(2 PI a / 255). DwmFlush - синхронизация с монитором 60 fps. Суперсэмплинг 2x2 (4 прохода). Делал я. Посмотрите - движется! Я сделал на g++. Свободно распространяемого компилятора языка C++. Скачайте и посмотрите! Это экзешник, в ГитХаб.
github: Download Latest Version Windows And Source code
Самое полезное - это увеличиваем / уменьшаем и центрируем. Вы на экран любое из множество Мандельброта. Какое вам нравится? Какое интересное? Вы можете все! И потом запишется в файл Mandelbrot.txt - три строки из файла. Вещественная часть центра и мнимая часть центра и ширина видимой области. Потом другая программа читает Mandelbrot.txt и создает Mandelbrot.bmp и уже не суперсэмплинг 2x2 (4 прохода) а 8x8 (64 прохода)!

Всё началось с эксперимента. На основной работе руководство довольно настойчиво рекомендовало использовать ИИ в разработке. В какой-то момент мне стало интересно, насколько далеко можно зайти в этом направлении. Можно ли написать реальное десктопное приложение так, чтобы основную часть кода писал ИИ?
Не в смысле «иногда подсказать синтаксис» или «помочь найти ошибку». А именно в буквальном смысле — чтобы код писал ИИ, а человек формулировал задачи и проверял результат.
Для эксперимента нужна была задача, которая, с одной стороны, достаточно реальная, а с другой — не связана напрямую с рабочими проектами.
В итоге кандидатов оказалось два.
Первый вариант — написать утилиту для расчёта коэффициентов цифровых фильтров. Такие инструменты используются для расчёта фильтров с заданными характеристиками — например, с нужной формой АЧХ, ограниченной задержкой и длиной фильтра.
Задача инженерная и интересная.
Но была причина отказаться от этой идеи. Похожий инструмент уже существовал внутри рабочих проектов, и смешивать рабочий код с личными экспериментами мне не хотелось.
Поэтому в итоге победил второй вариант — написать десктопное приложение для записи звука с бинауральной головы.
Про саму голову я уже писал на Хабре:
https://habr.com/ru/articles/1007864/
Если коротко, идея бинауральной записи довольно простая. Берётся макет головы с ушами, в ушных каналах устанавливаются микрофоны, и звук записывается примерно так, как его слышал бы человек.

Привет, Хабр!
В одной из прошлых своих статей, пару лет назад, я уже описывал реализацию дешевого самодельного датчика качества воздуха на базе сенсора BME680. Но прошло время, многое изменилось, и теперь возникла потребность в подобном устройстве на новом месте. Недавно на одном маркетплейсе мне попалась комбинированная плата с датчиками ENS160+AHT21, которая подходит под мои задачи, а что в итоге получилось, читайте далее.

UHT сгенерировал 4294 строки кода из одного моего заголовочного файла. Имена свойств, смещения в памяти, флаги сериализации, exec thunks для каждой функции - всё, чтобы движок в runtime знал о классе то, что C++ забывает после компиляции. Это третья и последняя статья в серии про внутренности Unreal Engine: K2Node → Blueprint VM → рефлексия. Разбираем, что внутри этих четырёх тысяч строк, зачем каждая из них, и как ими пользуются Details panel, GC, репликация и сама Blueprint VM.

Вот так. Впервые в мире. Суперсэмплинг (SSAA) — ресурсоемкий метод сглаживания, увеличивающий число выборок на пиксель для повышения качества изображения. При значении 8x (N=8) сцена рендерится в разрешении, в 8 раз превышающем целевое, по обеим осям, создавая 64 (или 8 х 8) выборки на пиксель. Изображение просчитывается в более высоком разрешении, а затем принудительно уменьшается до разрешения дисплея, устраняя лесенки и улучшая чёткость. Это очень высокая нагрузка! Это не 1920 на 1080 пикселя а в 8x8 больше - 15360 на 8640 пикселя! Такое никто, кроме меня, делает в мире. Для множество Мандельброта.
Это маленькая утилита из командной строке. Которая либо читает Mandelbrot.txt три строки из файла - клавиша 7. И создает Mandelbrot.bmp
Либо клавиша 1-6 - это одно из шести разных мест множество Мандельброта и создает Mandelbrot.bmp
Скачайте и посмотрите. Это экзешник, в ГитХаб
Скачать последнюю версию (Windows и Linux)

"Поскольку вы программист на C++, вероятность того, что вы слегка одержимы производительностью, выше среднего. А если нет, то вы, вероятно, по крайней мере с пониманием относитесь к такой точке зрения. (Если производительность вас совсем не интересует, аудитория Python разработчиков дальше по коридору)"
— Из пункта 42 книги С. Майерса “Effective Modern C++”, 2015.
Эта заметка описывает мой личный взгляд на то, как писать эффективный и надежный код для CPU. Статья ориентируется на С++, но значительная часть обсуждения CPU, кэшей, паттернов доступа к памяти и профилирования применима к Rust, Go и другим компилируемым языкам. Статья задумана как краткое введение и больше всего подходит студентам, имеющим опыт программирования на занятиях, но не в реальных проектах. Для профессионалов статья может быть полезной в качестве референса, чтобы не пугать новичков чем-то в духе Что каждый программист должен знать о памяти.
В статье опишу "набор новичка": godbolt.org, профилирование, бенчмарки, особенности CPU и его взаимодействия с памятью, когда есть смысл от асимптотических оптимизаций и почему важно при этом пользоваться санитайзерами, отслеживать coverage и вообще более трепетно относится к надёжности.

Привет, Хабр!
Меня зовут Антон Леонтьев, я старший разработчик в команде ядра редакторов МойОфис. Мы создаём офисные приложения, которыми ежедневно пользуются более 12 500 организаций, и совместное редактирование — одна из ключевых возможностей наших продуктов.
И знаете, что самое обидное в этой теме? За 35 лет исследований были опубликованы сотни научных работ. Google Docs работает с 2006 года. У Figma, Notion и Linear свои реализации. Казалось бы, задача давно решена, но стоит копнуть глубже, и становится понятно: универсального решения нет.
В Google Drive и Dropbox до сих пор всплывают баги с одновременным перемещением папок. В Notion при параллельном редактировании одного и того же абзаца можно потерять часть изменений. Даже Yjs — самая популярная CRDT-библиотека — не хранит полную историю документа в привычном для нас виде.
В этой статье разберём теорию, узнаем, какие проблемы решают Operational Transformation (OT) и Conflict-free Replicated Data Types (CRDT), на каких математических идеях они основаны, чем отличаются архитектурно и какие компромиссы неизбежно возникают в каждом подходе.
Интересно узнать, почему даже Google не смог сделать идеальное решение? Детали под катом.

Добро пожаловать в чистилище препроцессора — место, где здравый смысл уступает место макросам. Сегодня мы заставим C++ притвориться Haskell-ем и внедрим do-нотацию, за которую любой адепт «чистого языка» предаст нас анафеме.
Программисты на C++ делятся на два типа: те, кто боится препроцессора, и те, кто познал сие древнее чудо с сишных времён.
Сегодня мы перейдем черту. Функциональное программирование манит своими абстракциями, но когда дело доходит до цепочек вычислений в монадах, C++ встречает нас бесконечными лямбдами и вложенностью, от которой рябит в глазах. В Haskell эта проблема решена элегантным do-синтаксисом. А что, если я скажу, что мы можем получить то же самое в C++, используя лишь тёмную магию макросов, простые шаблоны и полное пренебрежение здравым смыслом?
Приготовьтесь: мы будем дорабатывать парсер и превращать ваш код в нечто, что заставит коллег вызвать экзорциста. Это история о том, как затащить чистую красоту монад в суровый мир C++.

Я не участвую в разработке Jami и не являюсь профессиональным разработчиком этого проекта. Однако я потратил достаточно времени, изучая архитектуру Jami, тестируя его в российских сетях и разбираясь в документации.
В процессе стало очевидно две вещи:
· У Jami огромный технический потенциал.
· В реальных сетевых условиях (особенно в мобильных сетях России) он работает значительно хуже, чем мог бы.
Эта статья — попытка разобрать проблему с инженерной точки зрения и предложить возможные направления развития.
Если вы разработчик, знакомый с C++, сетевыми протоколами, ICE или распределёнными системами — возможно, этот разбор будет вам интересен.

Привет! Меня зовут Николай, я C++-разработчик в SimbirSoft. Это третья часть цикла статей о проектировании библиотек на примере решения геометрических задач.
В предыдущих частях статье мы разобрали классическое наследование с виртуальными функциями и использование шаблонов, потом рассмотрели архитектуру на основе признаков (traits), тегов и концептов и показали, как этот подход помогает создавать расширяемые алгоритмы и снижать жёсткую связность между типами и реализациями.
В этой части мы продолжим развивать предложенную архитектуру и разберём, как она позволяет интегрировать в алгоритмы сторонние типы, контейнеры стандартной библиотеки и пользовательские структуры без изменения исходного кода алгоритмов. Мы покажем, как с помощью признаков можно адаптировать внешние классы к интерфейсу библиотеки и как организовать расширение алгоритмов собственными реализациями.
Также рассмотрим практические примеры: адаптацию стандартных контейнеров, расширение алгоритмов через частичную специализацию и добавление альтернативных реализаций. В завершение покажем, как возможности стандарта C++20 позволяют упростить архитектуру за счёт использования концептов и отказаться от части вспомогательных сущностей.
Для комфортного чтения потребуется уверенное понимание шаблонов, частичной специализации и базовых принципов обобщённого программирования в C++. Материал ориентирован на разработчиков уровня middle и выше, которые интересуются проектированием расширяемых библиотек и архитектурой современных C++-систем.

Цель статьи – объяснить разницу между CEF и WPE после года работы с этими фреймворками, предоставить инструкцию сборки и запуска полноценных JS+HTML+CSS веб-страниц с WPE на RaspberryPi 5 с zero-copy в 60+ FPS на FullHD. Посетовать, что такое нельзя сделать вместе с CEF. В конце мы будем иметь:
WPE для arm64 и amd64, OpenGL пайплайн вместе с EGL, работать всё это будет на встроенной системе Wayland. Wayland не должен никого пугать, на RaspberryPi 5 он идёт сразу в коробке, так что вы можете запускать и приложения на Wayland, и без перезагрузки приложения на X11. Но WPE zero-copy работает ТОЛЬКО с Wayland. Код будет представлен на языке С++.
Задался вопросом - как связаны порядки (в смысле перебора от begin к end) элементов в хеш-таблице, если её сначала сериализовать, а потом результат распарсить. Друими словами - смотрим на преобразование
T RefillSimple(T& x) { T res; for(auto& p : x) {res[p.first] = p.second;}; return res; }
Вариант перекладывания, сохраняющий порядок, получить удалось - и для меня это стало неожиданностью.
п.с.
(сори за форматирование - предпросмотр для ленты не сохраняет переносы в коде )