Пробуждение спящего института: как мы убираем ходунки у Python в REAPER

    КПДВ


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


    Однако, сегодня нежданно вырвался из локдауна ментейнер героя сегодняшнего обзора, и, буквально несколько часов назад в PyPi ушел reapy v0.6.0: пакет, который позволяет полноценно использовать Python для написания расширений для Reaper DAW.


    Итак: зачем нужен reapy, и что происходит с Python в REAPER.


    Экспозиция


    REAPER


    Это DAW, который стоит несколько особняком от своих собратьев, доставляя достаточно уникальный пользовательский опыт. Многие мои коллеги испытывают к нему патологическое отвращение, многие — патологическую любовь. А дело все в том, что взаимодействие с REAPER выглядит примерно следующим образом:


    Не нравится как работает — настрой. Вообще не работает — пиши код.

    Собственно, огромная гибкость и широкий API для 4‑х ЯП позволили вырастить вокруг проприеритарного софта огромное open-source сообщество.


    Писать можно на C++, eel, lua и Python; при этом, каждый язык интегрирован по-своему, и в зависимости от ситуации, предпочтительней писать то на одном, то на другом.


    Допустим, в большинстве случаев плюсы — оверкилл, как в вопросах написания расширений, так и в вопросах их установки. По большому счету, в народе широко распространились только три расширения: SWS, ReaPack (это типа npm) и, с недавнего времени JS_ReaScript.


    На eel писать почти также дорого, как и на C, т.к. там фактически ручное управление памятью, почти никаких абстракций, в т.ч. функций высшего порядка и вдобавок — почти все приходится писать самому: мало что можно использовать в качестве библиотек. Однако, eel обладает тремя шикарными свойствами: шустрый (в отличие от lua с Python), интерпретируемый (в отличие от C++), и общается с рипером лучше всех, за счет расширенного API и общего адресного пространства. Кроме того, на нем можно очень дешево писать DSP и MIDI плагины (типа VST, только JSFX).


    Lua де-факто стандарт для написания расширения общего назначения: для него уже написан ряд хороших библиотек, он ведет себя одинаково на всех платформах, устанавливается через ReaPack без танцев с бубном. Однако, при том, что я небольшой фанат этого языка в целом, Reaper умудрился его еще и поломать в нескольких местах, особенно — в части управления зависимостями. То есть, luarocks не работает, и я так и не нашел способа установки чего-то без расширения *.lua, тех же сокетов, например.


    Python


    Вот тут-то по идее должен выйти на белом коне Python, как язык с бездонным количеством библиотек, при этом не требующий танцев с бубном вокруг CMake. Однако, с его использованием в рипере просто проблема на проблеме.


    • надо устанавливать отдельно, еще и искать динамическую библиотеку ручками в настройках, что сильно повышает порог входа для конечных пользователей (а мы, типа, музыканты). В Linux python3.so приходится устанавливать отдельно как dev-пакет, что вообще не очевидно.
    • импортируются расширения тоже немножко через жопу, вследствие чего два скрипта, использующие один и тот же, скажем, numpy нельзя запускать в одной сессии.
    • нет биндингов к GUI. Если в lua и eel есть дополнительные функции gfx*, которые оборачивают LICE (часть библиотеки Cokos WDL), C++ может использовать WDL напрямую; то Python sucks. В то же время, всякие tkinter, pyqt и иже с ними запустить достаточно сложно, т.к. нет такого понятия как main loop, а есть просто возможность повесить функцию на отложенное выполнение (defer).
    • Вообще это характерно для всех расширений, но при использовании Python, почему-то от этого больнее: надо написать скрипт, сохранить файл, запустить его через Reaper, посмотреть на всплывающее окно с ошибкой, а то и словить креш, опять переписать в редакторе, опять запустить. Естественно, линтинг API функций не работает и т.п. Короче, кошмар поколения Z :)

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


    история стала легендой, легнда — мифом
    Кольцо всевластья

    reapy


    Если верить GitHub, в феврале 2019 (как раз где-то в это время я очередной раз пытался на коленке сварганить костыль на сокетах) Romeo Despres из Парижа выкатил первую редакцию reapy, который надежно и элегантно оборачивает ReaScript API. Более того, запускается он как изнутри, так и снаружи рипера. Библиотека старается обернуть все вызовы к API в нормальную ORM (если это так можно назвать), но, если какие-то функции еще не обернуты — можно вызвать оригинальные функции «напрямую». Устанавливается он через pip, и, пока что, еще отдельно его надо проинициализировать из нужной копии Reaper скриптом, который добавит веб-интерфейс для первоначальных рукопожатий внешней и внутренней части пакета.


    Когда мы запускаемся «снаружи» обертка работает так: все, что не должно исполняться внутри рипера исполняется в нормальном режиме. Классы же из reapy.core сериализуются и восстанавливаются на том конце, отрабатывают свой запрос и возвращают результат. Это не только решает проблему удобства запуска, но и нивелирует проблему падений от лишних импортов. По этому, за исключением ситуаций критичных к скорости реакции на события я бы рекомендовал все запускать снаружи: таким образом весь Python код, который исполняется внутри рипера, получает одну точку входа. Как раз в новом релизе мы добавили возможность наследования core классов, что попутно привело к импортированию пользовательских модулей изнутри.


    Багфиксы и сторонние расширения


    Мы не очень хотим полагаться на сторонние расширения. Дело не в отсутствие доверия стороннему коду, а просто в удобстве конечного пользователя, которому придется устанавливать все отдельно: самые частые вопросы по скриптам сообщества относятся к части установки доп расширений, вроде тех же JS_ReaScript или SWS. Ситуация еще больше обостряется в Linux. В то же время, подавляющая часть SWS API — это точно такая же «более удобная» обертка ванильного реаскрипта. По этому мы стараемся писать все недостающее ручками. Тем не менее, при установленном SWS — он доступен точно также как и основное «raw» API как объекты модуля reapy.peascript_api.


    Кроме того, оказалось, что сами C-биндинги к Python (peaper_python.py) тоже не без греха, и неизвестно, соберется ли Джастин это фиксить, или так и оставит висеть в баг-трекере. По этому я начал пилить свои C-биндинги в качестве надежного багфикса. Сейчас поставил вопрос о допустимости использования JS_ReaScript внутри reapy, т.к. там действительно оборачивается не сам реаскрипт, а Cokos WDL, которым можно рисовать корсс-платформенный нативный GUI. Конечно, можно попробовать доставлять свою копию WDL со своей оберткой, но это вопрос, с которым надо плотно разбираться.


    Где стоит использовать уже сейчас


    Благодаря последним нововведениям, а именно функции connect(host), reapy стал первым кандидатом для реализации микросервисов. Это звучит немного странно в контексте Digital Audio Workstation, но, серьезно, с возможностью подключения к любой инстанции Reaper в сети варианты использования вырастают многократно. Самый очевидный — сложный GUI, который может работать, допустим, с iOS или Android, почему нет? Reaper и так старался дать какие-то опции по дистанционному управлению, кроме OSC (а де-факто, Liine Lemur за многие тыщщи), но, прямо скажем, веб-интерфейс не идет ни в какое сравнение с прямым доступом к API без необходимости мараковать с подключением.


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


    Там, где нужно писать тесты. Я понятия не имею, как можно протестировать расширение на eel иди lua. Да, с тестированием пакета, завязанного на рипер все еще есть трудности, но это в принципе реализуемо.


    Роадмап


    В настоящее время стоят следующие задачи:


    • обернуть весь оригинальный API
    • завести в проект тесты. Да, задача оказалась нетривиальная, особенно потому что пока что в проект не приходил ни один ops… На сайд-проекте у меня тесты крутятся локально. Запустить же рипер в облаке и научиться его использовать в цепочке CI — было бы здорово.
    • научиться устанавливаться «в один клик». Собственно, приблизительный план действий есть, но дело стоит за реализацией. Скорее, все-таки, установка reapy и расширений на нем основанных будет организована на уровне setuptools и pip, а не через ReaPack.
    • сделать нативный GUI

    contributing


    Вы можете установить пакет, привязать его к своей инстанции рипера, начать кодить и уткнуться в место, которое «неудобно». Да, проект молодой, и вероятность такого развития событий велика. Так вот я в октябре понял, что не смотря на довольно человеко-читаемую обертку, у меня все вызовы reapy светятся цветами ошибок mypy. В общем, два вечера, и у меня на руках были стабы, которые отправились в пул-реквест. Потом я заметил, что в моем сайд-проекте также противно (а главное — нефальсифицируемо) светятся вызовы к «raw-API», и, недолго думая, я решил, что не буду использовать «raw-API» в сайд-проекте, а буду все оборачивать на уровне reapy. Собственно, теперь, получается, что в процессе кодинга на пользу себе-любимому половину работы я выполняю на стороне библиотеки, которая так похорошела за последние полгода. Мне кажется, в этом и есть смысл open-source: пользуйтесь им, и пушьте туда все, что отозвалось вам неудобством.

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 5

      +2
      Прочитал заголовок — не понял что это за библиотека, прочитал введение — не понял, зашел под кат — ничего не понял о том зачем нужна эта супер-популярная и очень нужная всем библиотека.

      Итак: зачем нужен reapy, и что происходит с Python в REAPER.

      Так и не рассказали зачем же он нужен. Пришлось гуглить чтобы понять, наконец, что моя область интересов не очень пересекается с этой темой (какой-то аудио-плагин?).

      Этим грешат все авторы, так что всем, кто это прочитет и захочет написать какую-то свою статью — во введнии вкратце опишите «для чайников» на какую именно тему вы хотите развить мысль?
        0

        Спасибо за критику, переписал введение, однако не совсем понимаю претензии к тому, что «ничего не понятно»:




        Так и не рассказали зачем же он нужен.

        рассказал, вроде бы. Перечислил проблемы, которые сопровождают разработку на Python, и reapy их в целом решает.


        Romeo Despres из Парижа выкатил первую редакцию reapy, который надежно и элегантно оборачивает ReaScript API. Более того, запускается он как изнутри, так и снаружи рипера. Библиотека старается обернуть все вызовы к API в нормальную ORM (если это так можно назвать), но, если какие-то функции еще не обернуты — можно вызвать оригинальные функции «напрямую».



        какой-то аудио-плагин?

        Скорее, просто плагин, а, точнее, инструмент их разработки. Плагин — примерно в том же значениии, что и «плагин для VSCode».


        А дело все в том, что взаимодействие с REAPER выглядит примерно следующим образом:
        Не нравится как работает — настрой. Вообще не работает — пиши код.
        Собственно, огромная гибкость и широкий API для 4‑х ЯП позволили вырастить вокруг проприеритарного софта огромное open-source сообщество.



        Пришлось гуглить чтобы понять, наконец, что моя область интересов не очень пересекается с этой темой

        Ну, с одной стороны, конечно, можно было бы вводных побольше дать. С другой стороны для тех, кому материал действительно был бы полезен — и так уже дадено на грани «водянистости». Вроде бы я поставил метку «аудио», может нужно еще как-то сократить выборку?

          +2
          Да, простите, теги не читает никто, по крайней мере они не очень видны. Я прихожу в статью из RSS, там тегов нет, в шапке — только хабы, а теги — в конце статьи.

          Так и не рассказали зачем же он нужен.

          рассказал, вроде бы. Перечислил проблемы, которые сопровождают разработку на Python, и reapy их в целом решает.

          Еще раз простите, но не рассказали. В заголовке — спящий институт (хм?), во введении робо-комбайн, биткойны и Python. В статье что-то про какой-то API и ORM, про удобную обертку. Я заинтересовался и зашел, но даже в статье не смог уловить назначение.

          А всего-то хватило бы одного предложения во введении, например, вторым абзацем — «reapy — это обертка над REAPER, плагином для обработки аудио».

          Еще раз простите за занудство.
        0
        С удивлением увидел слово Reaper — решил залезть посмотреть. Да, оказалось тот самый. И у меня вопрос — вот у меня ни разу не возникло желания в рипере что-то самому допилить. :) А что обычно пытается допилить народ?
          0

          Ну, во-первых, соглашусь с тем, что это лучшая в мире DAW)
          А во-вторых, аппетит приходит во время еды: установите ReaPack, посмотрите, что там народ пишет: всегда есть нестандартные задачи.


          Иногда появляются какие-нибудь ну очень крутые пакеты, допустим Reaticulate. Я вообще не представляю, как я до его появления писал оркестр.


          Есть еще такая штука, как повседневный скриптинг: допустим, режешь ты сэмплы, у тебя 100500 item-ов, и надо вдруг всем сделать одинаковые fade-in и fade-out. Руками — да ни в жисть, скриптом — 20 минут от силы.


          У меня сейчас два долгостроя: один — попытка замены vienna ensemle, вот надеюсь до конца карантина хотя бы альфу выкатить. А второй — нарезатор сэмплов: я, когда с кубейса пересел, как раз на нарезку сэмплов — не мог поверить, что скорость работы возорасла не в разы, на порядки. Потому что уже из коробки в рипере много автоматизации процессов. Зато на этом этапе автоматизация каждого из таких глобальных процессов может давать огромный прирост в скорости работы.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое