Когда приходится часто общаться в целом зоопарке мессенджеров: Slack, Discord, Zoom, Google Hangouts, Skype, Telegram, появляется проблема, что во всех них почему-то совершенно разные хоткеи для мьюта микрофона и часто их нельзя сделать глобально-системными. Кроме того иногда хочется немного постримить на твитче ради фана и хотелось мьютить микрофон когда ничего не собираешься говорить, чтобы за зря не шуметь механической клавиатурой.
Вижу три решения:
- Глобальный системный хоткей
- Педаль
Последний вариант выглядит самым удобным (не нужно шуметь клавиатурой; куда-то тянуться руками; в будущем можно использовать в Vim для перехода в дефолтный режим).
Исключительно случайно, тут недалеко в кустах у нас есть рояль, у меня есть швейная машинка и педать уже в наличии:
Остаётся как-то приделать её к компьютеру. Этот аудиоджек мы вряд ли куда-нибудь впихнём напрямую, поэтому идём в магазин радиодеталей, берём штекер под него, проводов, набор резисторов, светодиодов и, конечно, ардуинку (я взял Arduino Nano и товарищ, который консультировал меня по этому всему уговорил взять ещё esp32, но хватило и Nano, а еспшка ещё найдёт своё применение).
Берём паяльник, криво-косо (паяю второй раз в жизни) подпаиваем к штекеру провода и полуслучайным образом накидываем перемычки к штекеру и светодиоду:
... объясню, почему я сделал всё именно так, иначе получается совсем как в инструкции по рисованию совы.
Первое что я сделал с ардуиной (которую я до этого так же ни разу не тыкал) — скачал Arduino IDE, подключился к плате, загуглил arduino nano pinout, нашёл такую картинку:
Подключил светодиод через один из цифровых пинов (D8, он же 8/12), сделал типичный «Hello, World!»
Загрузил на плату, диод стал мигать. Только светился он настолько ярко, что мне стало слегка страшно (откуда мне знать, точно ли на эти нонэймовые светодиоды столько вольт можно подавать, да и слепит, поэтому подобрал резистор между ним и землёй, чтобы светило не так агрессивно).
Взяв мультиметр и включив его на измерение сопротивления определил, что когда педаль не нажата — она имеет сопротивление больше 2 мегаОма (т.е. я не могу измерить, будем считать за бесконечное), а как начинает нажиматься — плавно меняет сопротивление до ~10 килоОм на полном зажатии. Т.е. является реостатом.
Взяв питание с ардуины (3.3 вольта), пропустив его через педаль в аналоговый вход (в нашем случае ADC0, 23) мы можем измерить напряжение, которое дойдёт до аналогового входа и знать, насколько сильно нажата педаль.
Я не силён в электронике, но как программисту мне показалось, что пропускать питание через педаль, в которой я не уверен на 100% и пускать ток сразу в контроллер — опасная затея. Вдруг я когда-нибудь так по ней ногой в порыве экшена стукну, что её сопротивление каким-то образом окажется нулевым? (скорее всего это не проблема и на аналоговых входах внутри контроллера уже должно быть гигантское сопротивление, но мне резисторов не жалко)
Поэтому сначала добавил резистор между педалью и аналоговым входом. Зачем нужен второй резистор, который ведёт к земле — честно, не знаю. Просто во всех мануалах, которые я находил в интернете делали так. Рад был бы узнать.
Номиналы подбирал так, чтобы выводя значения, считываемые с аналогового входа и нажатое и отжатое состояние педали влазило в диапазон значений, которые я получаю (analogRead() возвращает число от 0 до 1023). Т.е. чтобы не было так, что я нажму педаль наполовину и получу 1023, или наоборот нажму на треть, а значение всё ещё остаётся нулём. В итоге получилось не совсем идеально и значения оказались в диапазоне 500-700.
Пишем такой скетч (так называются ардуиновые программы):
Здесь мы решаем проблему дребезга следующим образом:
- Если получаем значение больше максимума, считаем, что педаль нажата
- Считаем педаль отжатой только если значение опустится меньше минимума
Если бы мы сравнивали показания с фиксированным значением (например, 600), то лёгкое нажатие/отжатие педали, либо любые другие помехи могли бы крайне часто переключать состояние туда-сюда. А так получается, что чтобы активировать педаль нужно довольно сильно на неё надавить, а чтобы деактивировать — практически полностью отпустить. В средних положениях она всё равно будет оставаться активной.
Состояние нажатия/отжатия передаём через serial port. В некоторых версиях ардуин можно эмулировать USB-клавиатуру и отправлять хоткеи, будто их нажали на клавиатуре, но Nano такого не умеет.
Звук с микрофона, который мне нужно мьютить проходит предобработку (вычитание комнатного шума, гейт, компрессор) в Reaper прежде чем будет отдан в качестве системного микрофона/OBS. Находим библиотеку reapy, которая предоставляет удобный API для управления рипером.
Т.к. библиотека питоновая, то на нём же пишем клиент для последовательного порта ардуино и рипера.
При запуске оно пытается найти трек под названием mic, сразу же мьютит его, затем слушает, что говорит ардуино о состоянии педали, выполняет соответствующие действия.
Даже если вы захотите повторить этот квест и не используете Reaper, то просто вместо операций с ним можно другими библиотеками либо посылать нужные хоткеи, либо контролировать PulseAudio, либо что угодно ещё.
На все эксперименты ушёл один вечер времени (вру, были промежутки между закупкой недостающих комплектующих и необходимо дать им настояться в коробке неделю-другую). Без какого-либо опыта работы с микроконтроллерами до этого.
После такого опыта иногда возникает желание прикупить шаговых двигателей и начать собирать миниатюрный ЧПУ (который, например, будет фломастером на бумаге картины печатать). Нужно всего-то подавать сигналы на включение/отключение моторов через реле (а может даже как-то проще, нужно разбираться), а код к этому добру я написать уж точно смогу. Но это уже другая история :)