Использование синтезатора в качестве компьютерной клавиатуры

    Недавно мне в голову пришла мысль: а нельзя ли, подключив синтезатор к компьютеру, набирать на нем текст? Я попробовал реализовать это, и у меня получилось. Моя программа считывает нажатия клавиш синтезатора и эмулирует нажатия клавиш обычной клавиатуры. В этой статье я расскажу, как это реализовать. Писать будем под Linux на C++ с использованием Qt.




    Чтение данных из синтезатора


    Итак, в наличии имеется ноутбук с Linux и синтезатор Yamaha DGX-200. Подключаем синтезатор через USB-разъем к ноутбуку и видим, что устройство распозналось:



    Из устройства идет постоянный поток вопросиков, среди которых появляются другие символы при нажатии клавиш синтезатора. Кстати, интересный факт: если записать этот вывод в файл, а потом прочитать из файла и записать обратно в /dev/midi2, то синтезатор через свои колонки воспроизведет те ноты, которые были нажаты при записи, но без пауз.

    Следующая задача — разбор этого потока. После продолжительных поисков в гугле я решил воспользоваться библиотекой portmidi. Документация к ней довольно скудная, рабочих примеров я вообще не нашел. Что ж, теперь будет одним примером больше. Получаем список устройств:
    int count = Pm_CountDevices();
    for(int i = 0; i < count; i++) {
      const PmDeviceInfo* info = Pm_GetDeviceInfo(i);
      qDebug() << i << ": " << info->name 
               <<  " input: " << info->input
               << " output: " << info->output;
    }
    

    У меня получился такой результат:
    0: Midi Through Port-0 input: 0 output: 1
    1: Midi Through Port-0 input: 1 output: 0
    2: YAMAHA Portable G MIDI 1 input: 0 output: 1
    3: YAMAHA Portable G MIDI 1 input: 1 output: 0
    

    Для дальнейшей работы с устройством нам потребуется знать только id, который указан в начале строки. Нам подходит устройство 3 — входной (input=1) поток от нашего синтезатора. Открываем нужный поток:
    PortMidiStream* stream = 0;
    PmError e = Pm_OpenInput(&stream, good_id, 0, 100, 0, 0);
    if (e != pmNoError) {
      qWarning() << "Can't open input, error: " << e << endl;
      return 2;
    }
    

    После этого периодически читаем данные. Я использовал Qt-слот с периодическим вызовом по таймеру, но подойдет и обычный while(true) и sleep.
    PmEvent event; // структура, в которую будут записаны пришедшие данные
    int c = Pm_Read(stream, &event, 1); // читаем одно сообщение из устройства
    if (c > 0 && Pm_MessageStatus(event.message) == 144) {
      unsigned int note = Pm_MessageData1(event.message),
                   volume = Pm_MessageData2(event.message);
      // дальнейшая обработка note и volume 
    }
    

    Чтобы пояснить, что это за магические числа, я расскажу, как устроены MIDI-команды.

    MIDI-команды


    Каждое сообщение (оно же MIDI-команда) состоит из трех целых чисел, которые в portmidi называются status, data1, data2. Таблицу с возможными статусами можно посмотреть здесь. Нас интересует только статус 144 — изменение состояния ноты на первом канале. В data1 при этом передается номер ноты, а в data2 — ее громкость. Например, когда вы нажимаете клавишу «до» первой октавы на синтезаторе, приходит команда 144 60 95, а когда отпускаете — 144 60 0.

    Громкость варьируется от 0 до 127 и зависит от силы удара по клавише. Теоретически можно выводить заглавные буквы вместо строчных, когда пользователь сильно бьет по клавиатуре. Ну, а номер ноты — это просто порядковый номер, соответствие нот номерам можно посмотреть на этой картинке:

    Обозначение нот и аккордов


    Я решил обозначать ноту как «3C» или «3C#», где 3 — номер октавы (причем октава начинается с «ля», так проще), C — обозначение ноты («до»), а при необходимости добавляется диез. Вот как это реализовано:
    class Note {
    public:
      Note(int midi_number);
      QString to_string() const;
      int tone, octave;
    };
    
    Note::Note(int midi_number) {
      int n = midi_number - 21;
      octave = n / 12;
      tone = (n - octave * 12);
    }
    
    QString Note::to_string() const {
      return QObject::tr("%1%2").arg(octave).arg(
        tone == 0?  "A":
        tone == 1?  "A#":
        tone == 2?  "B":
        tone == 3?  "C":
        tone == 4?  "C#":
        tone == 5?  "D":
        tone == 6?  "D#":
        tone == 7?  "E":
        tone == 8?  "F":
        tone == 9?  "F#":
        tone == 10? "G":
        tone == 11? "G#": "??"
      );
    }
    

    Если пользователь нажимает аккорд (несколько нот одновременно), то приходит несколько сообщений почти сразу. Мы можем программно отслеживать эту ситуацию и отличать одиночные нажатия от аккордов. В моей программе можно ставить в соответствие различным буквам различные аккорды. Чтобы получить обозначение аккорда, соединим плюсом обозначения входящих в него клавиш: «3C#+3E+3G#». Когда пользователь нажимает ноту или аккорд, программа ищет в раскладке строку, совпадающую с этим обозначением, и эмулирует нажатие соответствующей клавиши. Когда клавиша на синтезаторе отпускается, эмулируется отпускание клавиши. Модификаторы (Shift, Ctrl и т.д.) здесь не отличаются от других клавиш. Все сочетания работают, как положено.

    Эмуляция нажатий клавиш


    Ура, мы умеем определять, когда ноты нажимают и отпускают. Теперь научимся эмулировать нажатие клавиш клавиатуры. Будем использовать решение, которое я нашел на Stack Overflow.
    #include <X11/Xlib.h>
    #include <X11/keysym.h>
    #include <X11/extensions/XTest.h>
    
    Display* display = XOpenDisplay(0);
    
    void emulate_key(QString key, bool pressed) {
      KeySym sym = XStringToKeysym(key.toAscii());
      if (sym == NoSymbol) {
        qWarning() << "Failed to emulate key: " << key;
        return;
      }
      XTestFakeKeyEvent(display, XKeysymToKeycode(display, sym), pressed, 0);
      XFlush(display);
    }
    

    Я добавил использование функции XStringToKeysym, чтобы эмулировать клавишу по ее имени, которое мы будем брать из конфигурационного файла. Список допустимых клавиш можно найти в заголовочном файле /usr/include/X11/keysymdef.h.

    Раскладку будем хранить в файле layout.ini следующего вида:
    ; letters
    X = 3C#+3G#
    Y = 3D#+3G#
    Z = 3E+3G#
    
    ; navigation
    Space     = 2E
    Return    = 1A+2A
    BackSpace = 4C#
    Delete    = 4D#
    Left      = 4A
    Right     = 4C
    

    Раскладка


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

    Попробуем уместить на 12 клавишах (от A до G#) 26 латинских букв. Выбор букв для семи белых клавиш очевиден — это буквы от A до G, являющиеся общепринятыми обозначениями соответствующих нот. Затем я выписал оставшиеся буквы в порядке убывающей частоты употребления и попробовал составить слово из букв, находящихся ближе к началу списка. У меня получилось слово HINTS, и я отдал этим буквам пять черных клавиш. Остальным клавишам я в алфавитном порядке назначил большие и малые терции внутри той же октавы. Осталась еще куча вариантов для размещения других букв (например, русских).

    Остальным клавишам тоже нашлось место на клавиатуре. У меня получилась такая раскладка:



    Использовался редактор нотной записи MuseScore.

    На видео, приложенном к посту, продемонстрирован набор программы Hello world и ее компиляция с использованием синтезатора вместо клавиатуры.

    Код программы выложен на Github.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 92

      +3
      Почти доделал похожий проект — транслирование MIDI сообщений в команды для компьютера. Команды реализуются в виде плагинов, так что можно будет хоть подсветкой экрана ноутбука управлять, хоть уровнем красного цвета в GIMPе.

      Для работы с midi использую и рекомендую rtMIDI — работает на всех 3 операционных системах.
      Для эмуляции нажатия клавиш несмотря на кучу примеров для каждой операционной системы, я не нашёл одной универсальной. В итоге, набросал свою. Если интересно, вот.

      У вас есть планы развития проекта?
        +1
        Конкретных планов пока нет. Подумываю о том, чтобы сделать программу кроссплатформенной, но сам я другие ОС использую редко, поэтому не очень заинтересован. Еще хочу улучшить раскладку и научиться быстро печатать, но на это нужно время.
          0
          можно было бы на .Net написать попробовать. Была бы клавиатура…
            0
            В моей программе всё кроссплатформенное, кроме эмуляции нажатий клавиш. Сделать ее кроссплатформенной, наверное, несложно.
            0
            Извиняюсь, знания в языках у меня нулевые.
            Но я тоже играю, только на Akai mpk88. Работаю под windows через reaper и давно хочу повесить на свободные кноб и фейдер — баланс и регулятор громкости в винде, соответственно. Удобно, все под рукой, регулировка точная и плавная.
            Понимаю, что Вы в винде не работаете, но все же: может быть есть более доступные пути в моем положении?
          +7
          В качестве доказательства концепции, дальнейшую разработку вы должны вести с помощью данной клавиатуры!)
            +3
            Это проблематично, потому что если в процессе разработки я поломаю программу, то я не смогу больше ничего сделать без обычной клавиатуры.
            +4
            «Потому что можем!»

            Если тут появится буханка-троллейбус.жпж

            Так скоро можно будет какое-нибудь литературное произведение сыграть.
              0
              «Выбор букв для семи белых клавиш очевиден — это буквы от A до G, являющиеся общепринятыми обозначениями соответствующих нот.»
              Я бы понял, если бы вы это в Америке писали. А в России (да и вообще в Европе) B — это не си, а си-бемоль. По крайней мере, в академической традиции. А H, соответственно — си. Монограмма Баха — си-бемоль-ля-до-си, B-A-C-H (она же — крест).

              Далее, «традиционно», S — ми-бемоль. (потому что Es). Не верите? Музыкальная монограмма Шостаковича — ре-ми-бемоль-до-си, D-(e)S-C-H.
                0
                Благодарю за пояснение, я недавно только начал увлекаться фортепиано, слышал лишь про то, что B и H могут быть вместо друг друга в различных вариантах обозначений!
                +4
                Сыграй Моцырта, может получится внятный код?=)
                  0
                  Только сначала нужно определить, какую раскладку он использовал.
                    +4
                    Надо забиндить символы по пентатонике, тогда написание программы звучало бы более гармонично =) Ну а Моцарта уже просто транспонировать и просто транспонировать и вперёд.
                      +1
                      Хорошая идея с пентатоникой, обязательно попробую.
                        +1
                        Пентатоник много, разных.
                        И, IMHO, пентатоника это Blues & Rock.
                        А если кому-нибудь захочется, например Jazz, там же одни квинты, септы и т.п.
                        Или, ну вдруг, кто-нибудь является любителем популярной музыки.
                        Или имеет классическое музыкальное образование?
                        Может быть тогда нужно какую-то карту пресетов\раскладок.
                        Текстовый файл забиндить?
                          +1
                          У меня в программе раскладка хранится в текстовом файле, его легко менять.
                        0
                        Как-раз пришел в комменты — пентатонику предложить. Первая мысль которая пришла при просмотре видео :)

                        Автору топика — запишите плз приемер с пентатоникой, очень интересно посмотреть что получится.
                      0
                      Или наоборот: отстучать исходники Linux и посмотреть, какая мелодия получится.
                    +3
                    Отличный способ скрытно перетаскивать текстовую информацию ))) перегоняем в мелодию, мелодию в MP3, потом обратный процесс )))
                      +3
                      Привет, программы на магнитной плёнке.
                        0
                        Предложенный способ уникально отличается тем, что нет необходимости производить подключение для передачи информации. Елси текст воспроизвести как звук, это звук можнго записать на диктофон )) О!!! Этож привет из прошлого от телефонных модемов!!!
                          0
                          Разве что простейшими сигналами наподобие морзянки, иначе помехи будут искажать информацию.
                        0
                        А для декодирования можно нанять человека с абсолютным слухом.
                        –5
                        скажите мне, зачем?
                          +13
                          Зачем вообще всё? Это философский вопрос.
                            +3
                            почему нет?
                              –9
                              спасибо за минусы. видимо, скоро выйдет статья «Включаем пылесос через блютуз».
                                +6
                                А офигенная тема! Если дома робот-пылесос, то даже кнопку нажимать не надо. Телефон на столе взял, отправил конмаду и убирается! Спасибо за идею!)))
                                  +3
                                  Шикарная идея.

                                  Интересно, а на двух пылесосах можно сыграть какую-нибудь простенькую мелодию? звучит как вызов
                                    +1
                                    Ну если контролировать по какому-нть беспроводному интерфейсу скорость вращения двигателя, то думаю вполне возможно. А еще лучше — сделать Web-интерфейс и дать возможность юзерам с хабра поиграть музику!
                                • UFO just landed and posted this here
                                  +5
                                  Я надеюсь, данная статья написана на синтезаторе?
                                    +11
                                    Микроволновка умерла, пишу с синтезатора?
                                      0
                                      Нет. Нужно много упражняться, чтобы печатать с нормальной скоростью. Впрочем, как и с незнакомой раскладкой на обычной клавиатуре.
                                        0
                                        о да, болгарская клавиатура наше все! :D
                                        0
                                        «Сыграй-ка мне хабрапост!»
                                        +4
                                        может, если ускорить видео, то будет прикольнее? :)
                                          +1
                                          Теперь я знаю как мне одновременно играть и программировать

                                          P.S я еще и пианист, ага
                                            +3
                                            Супер, regards.

                                            А можно сделать вот так?
                                            en.wikipedia.org/wiki/Chorded_keyboard

                                            И, можно, ли, например, подключить цветомузыку на крайнюю левую октаву, чтобы фонариками светить на концертах?
                                              0
                                              Да, можно назначить все сочетания на 12 (или меньше) клавиш одной октавы. Тогда получится что-то вроде аккордовой клавиатуры для одной руки.

                                              А фонарики управляются с компьютера? Если так, то можно забиндить клавиши левой октавы на определенные хоткеи, а эти хоткеи забиндить на управление фонариками. Или добавить в программу возможность сразу запускать определенную команду при нажатии клавиши.
                                                +1
                                                Фонарики управляются с пульта.
                                                Есть такие пульты управления фонариками, очень похожи на звуковые пульты управления.
                                                Т.к. я не в теме, то в первый раз увидев их даже спутал.
                                                И, как, вот, например, есть ЗвукоОператор, так есть и СветоОператор.
                                                Пульт, это по сути какая-то аналоговая штуковина.
                                                Но, из того, что я видел, мне стало ясно что интерфейс (протокол обмена) у фонариков стандартный был.
                                                  0
                                                  Я со светомузыкой не встречался, поэтому не знаю.
                                                    0
                                                    Да я и сам случайным образом свидетелем был всего лишь.
                                                    Наблюдал за друзьями музыкантами, сколько у них аппаратуры всякой приходится таскать с собой на концерты.
                                                    Вот, подумалось, что это же ведь «непаханное поле», если можно к стандартному синтезатору, например, через arduino подключать фонарики.
                                                    Хотя, наверное, это всего лишь нелепые догадки.
                                                      0
                                                      хм. вообще-то пульт управления светом — центр управления сервомоторами прожекторов, а они уже светят куда надо и как надо/
                                                      и стоят недешево.
                                                      вот, например светопульт
                                                      мне товарищ инженер рассказывал недавно относительно
                                                    0
                                                    Через DMX они управляются. Вроде как несложно через ардуину сигналы слать. Да и например вот такое шоу проблемно без компа, так что как-то можно.
                                                  +1
                                                  Есть устройство, которое по входным MIDI-сообщениям переключает реле. С его помощью можно фонариками светить на концертах.
                                                    0
                                                    Nice, спасибо!
                                                  0
                                                  Месье знает толк…
                                                    0
                                                    подскажите хороший секвенсор для Linux
                                                    пробовал rosegarden не заработало, jackd+fluidsynth еще
                                                      +1
                                                      Qtracktor.
                                                      Ещё Reaper в Wine нормально работает. Когда-нибудь будет и родная версия.
                                                        0
                                                        у меня не получилось завести Qtractor, сигналы с клавиатуры идут, но звука нет… но это был archlinux
                                                        единственное что заработало это renoise

                                                        а вы RT-патч на ядро ставите?
                                                          0
                                                          Чтобы звук был, нужно, чтобы в системе был MIDI-output, а его обычно нет.
                                                        –1
                                                        В виртуалбоксе отлично пускается аблтон.
                                                        –3
                                                        Мсье…
                                                          0
                                                          Мне кажется, что сопоставление нот и клавиш не оптимальное (по алфавиту).
                                                          Все равно что ABCDEF… на обычной клавиатуре — для обучения хорошо, но не для быстрой печати.
                                                          Нужно проводить эксперименты и вычислять лучший вариант — клавиши, которые используются чаще всего нужно играть указательными, средними и большими пальцами и они должны быть сгруппированы.
                                                            0
                                                            Да, вы правы.
                                                              +1
                                                              Тут еще параллельная задача есть — сделать что бы при наборе в большинстве звук гармоничный и интересный был.
                                                              0
                                                              Можно использовать звонкость/глухость согласных (например длительностью нажатия или по силе удара) и вынести на «черные» гласные. Также так и просятся аккорды на частые слоги;)

                                                              Кстати в русской стенографии, как в официальной Гесс, так и самобытной Александровой, используется нотная запись ;)То есть гласная обозначается месторасположением следующей согласной.
                                                                0
                                                                Тут должно быть видео с отрывком к/ф «Близкие контакты третьей степени»
                                                                  –7
                                                                  Иш ты, 30 каментов, а еще никто не вставил картинку с троллейбусом из буханки:)
                                                                    +2
                                                                    это решает проблему хоткеев для вима и емакса!
                                                                      0
                                                                      Как старый добрый анекдот про компьютерщика и пианино?
                                                                      «Странная у тебя раскладка на клаве — без обозначений! Но шифты ногами нажимать — зачётно!»
                                                                        –1
                                                                        Мы так с CSharpRU играли в osu! в 4 руки. Он написал небольшую программку, которая эмулировала нажатие двух кнопок.
                                                                          +1
                                                                          Я тут поофтоплю: скажите, а какую программу вы используете в линуксах чтобы с миди-клавиатурой писать музыку?
                                                                            +2
                                                                            Я бы ее использовал для авторизации. «Для входа в систему наиграйте свой пароль». Если у многих запомнить пароль в 10 символов уже проблема, то наиграть его гораздо легче ИМХО. Тогда длинна пароля ограничена музыкальной памятью… да и запоминать легче, на этом сайте у меня «лунная соната», на этом «кузнечик», а тут «похоронный марш.
                                                                              0
                                                                              Хорошая идея!
                                                                              Но так как у большинства пользователей нет синтезатора, но есть клавиатура, то можно использовать ее. И вторая проблема: не стоит ставить в качестве пароля «лунную сонату» и другие известные произведения, так как их легко можно будет забрутфорсить :)
                                                                                0
                                                                                Ну я к примеру привел их :-) Но сделать такой плагин для все ОС — не особо сложно я думаю.
                                                                                +1
                                                                                Напоминает классический способ генерации запоминаемого и сложного ко взлому пароля — использование первых букв слов какой-то песни. Вроде IttwIwbLamwstsAhtuohlItlos
                                                                                0
                                                                                > периодически читаем данные
                                                                                Эээ… Как-то костылясто. А нет никакого там метода, что спал бы до поступления символа?
                                                                                  0
                                                                                  Говоря русским языком, асинхронного метода)
                                                                                    0
                                                                                    Да-да, именно он)
                                                                                    0
                                                                                    Не нашел такого метода в portmidi.
                                                                                    0
                                                                                    Текст статьи не набирался с помощью синтезатора? Тогда это ещё сырой проект :).
                                                                                      0
                                                                                      Пришла в голову мысль:
                                                                                      А что если обобщить данную идею с синтезатором на другие инструменты (флейта, гитара)? При этом будет использоваться микрофон и нужно будет вычислять частоты.
                                                                                        0
                                                                                        А как-же SHIFT педалью?!!! Без этого — не айс!
                                                                                          0
                                                                                          Пробовал, не очень удобно. Клавишей лучше.
                                                                                          0
                                                                                          image
                                                                                          +1
                                                                                          Тренируйтесь и когда-нибудь вы сможете сразиться с Марком Миллером и померяться с ним скоростью программирования на музыкальных инструментах. Причем у вас преимущество — кнопок на порядок больше.
                                                                                            0
                                                                                            было бы прикольно, как мне кажется, взять какой-нибудь текст программы и транслировать его в обратную сторону, чтобы получить мелодию.
                                                                                              0
                                                                                              А потом наигрывать ее и вспоминать код :)
                                                                                              +1
                                                                                              Кстати, для Mac OS X есть такая прекрасная штука, как Keyboard Maestro (для макрокоманд, клавиатурных сокращений и т.д.), она может использовать MIDI для запуска скриптов и т.д. Учитывая, что midi-контроллер может иметь совершенно разный вид (пример ниже), это может быть интересно…

                                                                                              image

                                                                                                0
                                                                                                А для PC есть BOME's MIDI translator.
                                                                                                  0
                                                                                                  Платный.
                                                                                                  Поэтому, кстати, и делаю свой — чтобы была бесплатная альтернатива :)
                                                                                                  Разработчик ещё и Send SX сделал платной — это никуда не годится!
                                                                                                    0
                                                                                                    Для персонального использования Bome’s Midi Translator Classic бесплатен.

                                                                                                    Bome’s Midi Translator Classic is the smaller sister of Midi Translator Pro. It has the same powerful MIDI processing engine, but can only convert MIDI messages to other MIDI messages, or to keystrokes. Also, the rules and conditional MIDI translation are not available with the Classic Edition.

                                                                                                    Midi Translator translates midi messages «on the fly». Sys-Ex messages are treated equally as «short» midi messages.
                                                                                                    Several translation sets may be created for a quick change. The MIDI-TO-KEY feature allows to control arbitrary software by way of keyboard commands. For example, control Adobe Premiere with a USB/MIDI control surface.

                                                                                                    The Classic Edition is only available for Windows and it will not evolve anymore. It is free for personal use (Postcardware).
                                                                                                  +1
                                                                                                  Я уже давно использую Launchpad как быстрый запуск, используя самописную программку. К слову, я чего только для него не делал…
                                                                                                  0
                                                                                                  Зачем?
                                                                                                    0
                                                                                                    вы ещё спросите зачем вот это :-D Низачем. Just For Fun. Ну и ради изыскательского интереса.
                                                                                                    0
                                                                                                    Самая интересная штука — как трансформируется мышление если пользоваться подобной клавиатурой.
                                                                                                    Если сейчас при наборе текста работает моторная память, то там подключится еще и аудиально-музыкальная.

                                                                                                    Человек начнет мыслить мелодией :)
                                                                                                      +1
                                                                                                      И как теперь правильно программировать на С#: в до диез мажоре или в до диез миноре? Какими аккордами вводить ключевые слова, какие имена давать переменным, чтобы эффективная и правильная программа хорошо звучала, а баги сразу резали слух?
                                                                                                        0
                                                                                                        Мне cout нравится как звучит.
                                                                                                        А расово линуксовый нотный редактор — LilyPond :-)

                                                                                                        Only users with full accounts can post comments. Log in, please.