пятница, 17 марта 2023 г.

[prog.c++] Очередные шаблоны против копипасты: упоролся тут на почве обеспечения гарантии strong exception safety

Делаю новую фичу в SObjectizer и в одном месте потребовалось реализовать вставку элемента в словарь из словарей словарей. Сначала сделал просто. Потом начал делать нормально ;)

И дошел до такой жести, которая пока что шокирует даже меня. Уж не знаю, останется ли это как оно есть сейчас или же будет еще как-то переделано, но захотелось рассказать о том, что получилось. Не то, чтобы "чистапаржать", но где-то в этом духе :)

Итак, есть вот такая вот структура данных (ключевой тип -- это bindings_map_t):

среда, 15 марта 2023 г.

[life.music] Продолжение саги про выбор недорогих, но хороших наушников на Aliexpress

Два года назад в блоге появилась первая часть истории, которая продолжается до сих пор: Введение в сагу о выборе недорогих, но хороших наушников на Aliexpress. Точнее говоря, два года как исполнилось вчера и я было хотел этот пост написать вчера...

Но вернувшись с работы умудрился сломать только-только полученные на почте динамики пытаясь сделать пару внутриканальных наушников-затычек :( Сильно расстроился по этому поводу и плюнул на все. Сегодня уже не так обидно, поэтому попробую поделиться своими ощущениями от этого увлечения за истекший период.

Несколько общих слов

Сразу хочу сказать, что готовых наушников именно для прослушивания уже очень давно не покупаю. Еще года с 2021-го. Как начал собирать самодельные вкладыши, так и продолжаю. Если и беру что-то готовое, то буквально копеечное ради корпусов, в которые затем можно будет вставить отдельно купленные динамики.

Правда, пик наушнико-строительства пришелся на 2021-й. В 2022-ом уже собирал гораздо меньше. Отчасти потому, что многое из того, что хотел попробовать, уже попробовал. Отчасти потому, что тупо некуда девать готовые наушники, почти все из которых можно слушать с удовольствием и особо не задумываться о качестве звучания.

Отчасти потому, что с марта 2022-го из РБ на Aliexpress закупаться стало сложнее, чем до того. Да и посылки, по ощущениям, стали идти дольше. Что сильно снижает удовольствие от процесса: одно дело, когда ты просто оплатил с карточки в белорусских рублях и посылка у тебя уже через 2-3 недели. Другое дело, когда нужна валютная карта, да еще и не любого банка. И ждать потом 1.5-2 месяца.

На самом-то деле вся эта бодяга с поиском "своего звука" -- она же не про звук, она же про ожидания. Какая-то разновидность дофаминовой ловушки, когда вся суть в предвкушении новинки и знакомства с новинкой. А потом в ожидании следующей новинки и т.д. Претензии к звуку конкретной модели наушников здесь, конечно же, имеют место быть, но как повод, а не как причина.

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

Какие наушники использую больше всего?

Вкладыши с 15.4mm динамиками. Одна пара с DLC-диафрагмой (на работе), она пара с LCP-диафрагмой (дома). Забавно, что изначально DLC- и LCP-динамики были для меня слишком светлыми, мне в них не хватало басов.

Но время идет, вкусы и привычки меняются. Больше обращаешь внимания на какие-то детали и особенности звучания. Так что сейчас что DLC, что LCP даже чуть темноватее, чем хотелось бы. Что меня до сих пор удивляет. Т.к. все еще помню свое разочарования от количества баса в LCP-динамиках летом 2021-го года :)

Иногда слушаю вкладыши с синей PET-диафрагмой. Но рано или поздно начинаю ощущать, что мне в них (пока?) недостаточно веса на НЧ, поэтому все равно возвращаюсь к DLC и LCP-динамикам.

Иногда слушаю внутриканальные затычки с 10mm драйвером, переделанные из Yincrow RW-919. Но пока что не смог подобрать себе подходящие для этого корпуса амбушюры. Так что основными они (пока?) не стали. Хотя по качеству звука, наверное, это самое лучшее из имеющегося. По деталям, возможно, вкладыши с PET-диафрагмой чуть посолиднее, но в этих затычках больше массы на низких частотах.

Еще у меня был эксперимент с 40mm накладными наушниками. Но пока что не удалось сделать нормальное оголовье (не встретились пока на барахолке подходящие доноры), так что здесь еще исход не ясен. Но общие впечатления прикольные. Что-то в этом направлении есть.

Какие источники у меня сейчас?

Как и прежде: телефон + USB ЦАП ("свисток").

До недавнего времени было четыре основных свистка. На работе долгое время пользовался X1 на базе AK4452 (реплика того самого Trasam Q1). Но на днях он стал барахлить, поэтому пришлось от него отказаться.

Tempotec Sonata BHD. Непревзойденное сочетание цены (брал на распродаже чуть ли не за треть стоимости), качества звука и низкого энергопотребления. Но когда долго слушаешь, что начинает казаться, что в звуке не хватает драйва и жизни. Все технично, все детально... Но как будто пресно, что ли.

Безымянный чуть ли не самодельный USB-цап на базе PCM2706 + ES9023 в качестве усилителя. Ценой что-то вроде 13USD. С заметным фоновым шумом, из-за чего приходится применять дополнительное сопротивление на 75ом. Не такой техничный и детальный, как Sonata BHD. Поддерживающий только 16bit/44.1kHz. Но зато очень приятный и драйвовый звук. Почти что тёплый, ламповый :) И, что немаловажно, такой же экономичный, как и Sonata BHD.

Hiby FD3 на двух ES9038Q2M. Просто самый лучший из всего, что у меня побывало. Единственная проблема -- жрет батарейку в три раза активнее, чем Sonata BHD :(

Про Hiby FD3 в Интернете не так много говорят, хотя, судя по тому, что я читал, это прямой конкурент таким распиаренным моделям, как xDuoo Link2 Bal и Moondrop Moonriver 2. Собственно, из-за того, что у меня есть FD3, пробовать Link2 Bal или Moonriver 2 даже и не хочется.

Еще не могу не отметить один ЦАП от HaaFee на базе AK4493EQ (из тех, что до пожара на фабрике Asahi Kasei). Отличный был ЦАП за свои деньги. Но, в какой-то момент у меня на руках этих самых ЦАПов скопилось очень уж много, распродал часть, вместе с ними и HaaFee. Сейчас жалею. Тот самый velvet sound от AK, чего нет в FD3.

HiFi-плееров у меня пока не было. Хотя уже задумываюсь о том, чтобы каким-то обзавестись, т.к. надоело уже таскаться со "свистками" и подключать/отключать их постоянно. Однако, хороший плеер (который бы переиграл бы FD3) для меня сейчас слишком дорогая штука, так что пока не обзавелся. Ну да поживем, увидим.

Некоторые выводы, которые я сделал для самого себя

  • Если ударяться в качественный мобильный звук, то хороших наушников мало. Надо приобрести мало-мальский приличный свисток. Благо выбор сейчас просто огромный.

    Так-то, конечно, хорошие наушники будут играть и от телефона. Однако, даже "копеечный" (по аудиофильским меркам) USB-ЦАП за 30-40USD сразу даст вам почувствовать насколько хорошие наушники могут звучать лучше.

  • Сменные кабеля -- это, наверное, must have. Т.к. со временем кабеля изнашиваются. Такова се ля ви, с этим ничего не поделаешь. Силикон на оплетке кабеля под действием времени, жира с нашей кожи, Солнца и других факторов теряет свои свойства, кабель дубеет и затем переламывается. Да и пользоваться задубевшим кабелем... Ну такое себе.

    Цены на кабеля сильно варьируются. Но нормальный кабель на распродажах вполне можно взять в диапазоне от 10 до 20USD, иногда и дешевле. У меня есть несколько кабелей от NiceHCK, пока доволен.

  • Наушники, как не крути, все-таки расходный материал. Конечно, если наушниками пользоваться аккуратно, то они могут прослужить годы (лет пять-шесть запросто, особенно если кабель сменный). Но, т.к. наушники используются активно (тем более, если используются и на улице), то случайно повредить их -- это как нефиг делать. Так что я не вижу смысла в очень уж дорогих наушниках для повседневного применения. Дорогие для меня -- это дороже 50USD (т.е. если мне их комплектующие обошлись больше чем в 50USD). Подозреваю, что брендовые наушники с таким же качеством обойдутся в разы дороже, но это уже совсем другая история.

    Если слушать музыку в фоновом режиме, то качество источника+наушников, по большому счету, не суть важно. ЦАП за 15-20USD и вкладыши с динамиками за 10USD + приличный кабель за 15USD -- и этого хватит с лихвой. Ну а если уж музыку начинаешь выслушивать специально, отгородясь от всего мира, тогда да, тогда придется раскошелиться :)

  • Амбушюры очень сильно влияют на звук. Особенно во внутриканалках. Так что если вы все еще ищете "свой звук", то имеет смысл собрать большую коллекцию разнообразных амбушюр. Чем больше, тем лучше.

    Самое забавное для меня сейчас в плане амбушюр то, что в последнее время я все вкладыши слушаю вообще без амбушюр. Не знаю почему так произошло, но как-то стал замечать, что мне четкость и резкость звука (что скрадывается амбушюрами на вкладышах) стала важнее, чем объем и масса (что добавляется амбушюрами). Еще полгода назад в такой поворот я бы не поверил.

  • Среди всех магазинов, в которых можно приобрести запчасти для самодельных наушников, я безусловно выделяю NSC Audio DIY Store и XinYue Audio Store. Тут и выбор большой, и цены низкие, и обслуживание быстрое и адекватное. Подавляющее большинство моих закупок было сделано в этих двух магазинах. Есть еще Chitty's Store. Там встречаются экзотические штуки, которые в другие магазины доезжают с изрядным опозданием (если вообще доезжают). Но зато цены... По некоторым моделям я видел разницу в 1.5-2 раза.


Вот как-то так.

Если у кого-то возникнут вопросы, то задавайте в комментариях, постараюсь ответить.

Ссылок на разное не давал, т.к. эти самые ссылки имеют неприятное свойство "протухать" (т.е. устаревать). Если что-то интересует, то я дам в комментарии актуальную, на текущий момент, ссылку.

понедельник, 13 марта 2023 г.

[prog.c++] Кратко про свои впечатления от библиотеки WebSocket++

В текущем проекте потребовалось поработать с библиотекой WebSocket++, которая, как мне видится, является чуть ли не самой часто рекомендуемой библиотекой по работе с WebSocket-ами в C++.

Ряд моментов в дизайне WebSocket++ вызывают недоумение.

Например, в именах некоторых типов используется суффикс _ptr, но где-то это означает shared_ptr (acceptor_ptr), а где-то просто голый указатель (io_service_ptr).

Тип connection_ptr вроде как является shared_ptr-ом, но и вроде как пользоваться им напрямую можно только до тех пор, пока не будет вызван connect у endpoint-а. Потом можно оперировать исключительно connection_hdl. Но connection_hdl -- это weak_ptr, который нужно вручную трансформировать в connection_ptr, что захламляет код обработчиков. Могу предположить, что отдавать готовый connection_ptr в обработчики событий -- это создавать просадку производительности в тех редких случаях, когда обработчикам достаточно только connection_hdl. Но насколько это разумный баланс между производительностью и удобством использования -- это для меня открытый вопрос.

Не смог найти никаких идентификаторов для соединений. Подозреваю, что в качестве connection_id нужно использовать сам connection_hdl + std::owner_less. Но connection_hdl суть weak_ptr и, как мне кажется, в полный рост может встать ABA проблема.

Еще в WebSocket++ я не нашел никаких способов узнать было ли сообщение записано в соединение или еще нет. В принципе, без этого можно и обойтись, но когда есть нотификаторы о завершении записи в канал, то контролировать поток исходящих данных, имхо, проще.

Качество и количество примеров не впечатлило. Качество и количество документации впечатлило еще меньше :(

Но в исходниках разобраться можно, что и спасает. И хотя у нас в RESTinio шаблонных наворотов, может быть, еще побольше, но временами кажется, что разработчики WebSocket++ обобщенным программированием увлеклись ну очень уж сильно :)))

PS. RESTinio для задачи не подходит, т.к. у нас нет реализации клиента (да и вообще поддержка WebSocket только самая базовая, до более продвинутого варианта руки так и не дошли). Но познакомившись с WebSocket++ без ложности могу сказать, что RESTinio как продукт выглядит более чем достойно ;)