Monthly Archives: F Y

Utiliser VMPK et Cardinal avec PIpeWire, Jack et les baies de brassage Helvum et Qpwgraph

Sommaire
VMPK, clavier de piano MIDI virtuel
Cardinal, fork de VCV Rack, synthétiseur modulaire Eurorack
PipeWire et les baies de brassage
Petit ensemble simple sous Cardinal

Arch Linux, ainsi que de nombreuses autres distributions Linux, ont définitivement basculé la pile audio sous PipeWire. Celui-ci à l’avantage de centraliser de façon simple Jack (temps réel pour l’audio de qualité studio, nécessite des réglages en fonction des besoins) et PulseAudio (plus simple, pour l’utilisation en informatique de bureau ou de jeu). PipeWire, permet aussi de synchroniser plusieurs sources et destinations video de différentes tailles et format, en même temps que le son. Les baies de brassage Helvum et Qpwgraph permettent d’établir simplement à la souris les connexions. QJackCtl ne semble plus fonctionner pour cette tâche.

VMPK, clavier de piano MIDI virtuel

VMPK (Virtual MIDI Piano Keyboard, signifiant clavier de piano MIDI virtuel) est un contrôleur MIDI logiciel, permettant d’utiliser le clavier de l’ordinateur, la souris ou autre dispositif de pointage (tablette, écran tactile) sur un clavier de piano logiciel, et d’envoyer des signals MIDI soit via l’interface MIDI du système, soit aux synthétiseurs logiciels General MIDI FluidSynth (paquet fluidsynth) ou SoniVoxEAS. Les distributions Linux contiennent des fontes sonores libres compatibles General MIDI, (sous Arch, paquet soundfont-fluid, complet, mais de qualité moyenne et freepats-general-midi, moins étendue en nombre d’instruments, mais de bien meilleure qualité). Si vous avez besoin de sélectionner leur emplacement, ces fontes sont placées dans le dossier /usr/share/soundfonts/ après installation. Le site de Freepats regroupe également des fontes spécialisées par instruments d’encore meilleures qualité, mais dont le poids des fichiers sont beaucoup plus grands.

réglage de la fonte midi ou de la sortie MIDI

Pour choisir le mode synthétiseur logiciel ou MIDI system, en suivant l’image ci-dessus :
* 1. Menu Éditer -> Paramètres MIDI
* 2. choisir dans le champs Pilote MIDI OUT, choisir soit Alsa pour le signal MIDI système, soit FluidSynth pour le synthétiseur MIDI logiciel permettant de produire directement les sons.
* 3. Dans le cas de FluidSynth, si c’est votre premier réglage, il faut cliquer sur le bouton [...]; à droite du bouton-menu ou vous avez sélectionné FluidSynth dans le champs Paramètres MIDI OUT.
La fenêtre Paramètres du pilote FluidSynth s’ouvre alors, il est possible dans le champs Pilote Audio de choisir Alsa, Jack, PulseAudio, SDL et d’autres.
# Dans le champs Soundfont, vous pouvez choisir la fonte sonore en ouvrant un sélecteur de fichier avec [...] ou de taper le chemin directement. Comme dis précédemment, les fontes sont placées par défaut dans le dossier /usr/share/soundfonts/.

Cardinal, fork de VCV Rack, synthétiseur modulaire Eurorack

Voici un aperçu des nombres plugins du synthétiseur modulaire Cardinal, il s’agit d’un fork, par le projet DISTRHO (dont le but est de regrouper les systèmes de plugins audio) de VCV Rack, intégrant de base tous les modules sous license libre en un seul paquet, et comme vous pouvez voir sur cette vidéo de la version d’avril 2022, ils sont nombreux :

VCV Rack est une version logicielle de synthétiseur modulaire au format standardisé ouvert de modules de synthétiseurs analogiques, Eurorack créé par l’allemand Dieter Döpfer1. Il est d’ailleurs possible d’interfacer, notamment via MIDI, des modules matériel de ce format. Les échanges s’y font principalement par un signal électrique analogique en utilisant des câbles avec connecteurs jack, mais les modules peuvent faire des traitements numériques ou utiliser des connexions numériques de type MIDI ou différents formats audio comme la connexion optique S/PDIF. Certains modules logiciels de VCV Rack sont d’ailleurs fait par des créateurs de modules matériels, à l’image des auteurs des excellents modules Mutable Instruments qui en ont porté certains sous le nom de Audible Instruments ou encore de Befaco. Ceux-ci comportement notamment de la synthèse granulaire et de la simulation numérique de sons. La version Cardinal supporte également différents formats de plugins audio LV2, VST, etc..

Je maintien les paquets Arch AUR de VCVRack-git en version 1.x qui ont l’avantage de pouvoir être utilisé avec ALSA directement (plus simple que Jack) et de comporter directement un module de saisie au clavier. Ce que ne propose pas encore Cardinal, mais cela devrait arriver ce mois-ci avec l’ajout des modules Fundamentals.

À ce propos, David Louapre, l’auteur de la chaîne Youtube de vulgarisation scientifique « Science étonnante » à fait une vidéo explicative des principes des synthétiseurs analogiques et modulaires intitulée « La Science des synthétiseurs ».

PipeWire et les baies de brassage

La baie de brassage Helvum permet de gérer de façon graphique et interactive, les connexions des différents éléments audio ou vidéo au sein de PipeWire, il est bien évidement également possible de les gérer par des programmes ou scripts directement dans PipeWire.

Helvum affiche les différents éléments sous forme de boîte et les liaisons via des courbes ou fils. D’après ce que j’en ai compris, les courbes en pointillées montrent les connexions automatiques de la partie PulseAudio, et les courbes pleine, montrent les connexions manuelles pour Jack.

Pour ajouter une connexion, il suffit de cliquer sur une boîte, puis de déplacer le petit icône de fichier affiché vers l’autre point de liaison. Voici comment faire dans le cas de VMPK avec Cardinal et de Cardinal avec la sortie audio :

Qpwgraph, à l’avantage de détecter d’avantages de choses. Il a notamment détecté VokoscreenNG que j’ai utilisé ici pour la capture vidéo du bureau. Mais ça n’est pas un problème, celui-ci ayant permis de sélectionner l’entrée audio sans doute via pulseaudio à utiliser. Il comporte également des annuler/refaire, et l’ouverture et sauvegarde de la configuration en fichier, ce qui peut rapidement devenir indispensable.

Voici donc les manipulations équivalentes sous Qpwgraph :

À noter que dans cet vidéo j’avai une sortie MIDI de VMPK, mais dans un autre cas, comme sur cette capture d’écran, je ne l’avais pas. VMPK étant connecté au bridge (passerelle) MIDI du port 0, il suffit alors de connecter la sortie de la passerelle MIDI du port 0 pour avoir le même résultat.

Utilisation du bridge MIDI du port 0 pour récupérer la sortie de VMPK

Petit ensemble simple sous Cardinal

Voici un exemple simple d’ensemble fonctionnant avec VMPK et cette configuration. Cela permet de comprendre le fonctionnement de base de Cardinal/VCV Rack.

Les sorties de contrôle MIDI sont récupérées vers les entrées de contrôle du rack « Modal Synthesizer » d’Audible Instrument dont j’aime bien la sonorité, proche de carillons :
* La sortie V/Oct (volt/octave) vers l’entrée V/Oct. Elle donne la hauteur de la note en fonction de la tension électrique (ici virtuelle).
* La sortie Gate (porte) vers l’entrée Gate. Elle transmet le moment où une touche est pressée (signal 0 relâchée ou 1 pressée). Il est intéressant de noter dans ce montage que lorsque la touche suivante est pressée avant que la touche précédente ne soit relâché on a un glissendo, plutôt qu’une nouvelle percussion de la note avec attaque initiale.
* La sortie velocity (vélocité) permet de donner de l’expression au son en variant l’attaque, sur un clavier texte AZERTY d’ordinateur, il n’y a pas ce genre de paramètres, mais il est possible de le lier à l’entrée strength (force), du module, et de lui transmettre ainsi l’expression du touché.

Pour la sortie du module d’Audible Instrument, c’est simple, la sortie gauche (L comme left) vers le port de sortie audio 1 et la sortie droite (R comme right) sur le port audio 2, comme nous avions définit dans la baie de brassage. Il ne reste plus qu’à presser les touches du clavier virtuel pour entendre les notes et tourner les molettes pour modifier les effets.

Comme on peut le voir sur cette vidéo, la saisie directe du clavier comme le permettent les modules Fundamentals ou un veritable instrument midi sont tout de même plus pratique pour ne pas avoir à passer sans arrêt de l’un à l’autre. Mais cela permet déjà de faire des enregistrement ou contrôle simple. Différents outil comme Qjackctl permettent d’enregistrer une séquence MIDI puis de la retransmettre. Il est aussi possible de passer un morceau midi en fichier .MID dans la passerelle MIDI et de lui ajouter des effets avec Cardinal et/ou des nombreux modules au format LV2 ou VST.

Principe de synthétiseur analogique modulaire

Les synthétiseurs analogiques modulaires suivent le principe similaire à UNIX, du KISS (keep It Simple and Stupid), garder les choses simples et stupides. Les modules sont très simples, et la force du système réside dans la possibilité d’échanger entre ces différents éléments. Les échanges se font principalement via des câbles électrique via un courant qui peut varier en tension (en Volt) de façon analogique (continue), plutôt que numérique (discrète). Il est tout de même possible de transmettre un signal numérique (1 ou 0) et c’est ce que fait la fonction gate (porte).

Les différents modules de base sont généralement (je donne les termes anglais et leurs abréviations utilisée, ainsi que la traduction du terme en français entre parenthèses :
* VCO Voltage Controled Oscillator (oscillateur commandé en tension), Il s’agit d’un générateur de signal, généralement sinusoïdal, comme le faisait le premier synthétiseur, le Thérémine, du nom de son inventeur, le Russe Lev Sergueïevitch Termen. Certains plus avancés permettent de fournir des singaux carrés, en dent de scie, différentes couleurs de bruits (blanc, rose, etc).
* VCF Voltage Controled Filter (filtre contrôlé en tension), permet de filtrer l’entrée en fonction de fréquences définies.
* VCA Voltage Controled Amplifier (Amplificateur commandé en tension). Permet d’amplifier le signal.
* ADSR Attack, Delay, Sustain, Release (Attaque, délai, soutient, relâchement. Il s’agit des paramètres standard d’enveloppe sonore, dont les principes ont été crées par Vladimir Ussachevsky. Pour faire une analogie avec les instruments acoustiques, L’attaque correspond à la montée au moment ou l’on actionne le sonophore de l’instrument. La corde frappée d’un piano ou pincée d’une guitare ou d’un clavecin. L’archer qui commence à frotter la corde, La percussion sur la peau d’un tambour, l’impulsion d’un trompettiste. Le délais est la durée de l’attaque, c’est à dire le délai de l’attaque initiale. le Sustain/soutien, et la longueur pendant la vibration produisant le son continue sur son palier. et le relâchement, l’arrêt du son.
* LFO Low Frequency Oscillator (Oscillateur basse fréquence), il est utilisé principalement pour les modulation de l’instrument, comme un trémolo ou une trille par exemple.
* Arpeggiator (arpégiateur). Il est destiné à produire une succession de note. Un accord correspond à plusieurs notes produites simultanément, et un arpège est son équivalent avec cet ensemble de notes décalées dans le temps. Par exemple les notes do mi sol do jouées successivement correspondant à un accord de do majeur. Cela permet de produire simplement des éléments de base de mélodies.

Pour aller plus loin

La page PipeWire du wiki d’Arch.

RISC-V based ESP32c3 with ESP-IDF part 3, OLED screen, and potentiometer

Table of Content

* Introduction
* ADC Limitations on some ESP32 SoCs
* Potentiometer
* OLED I²C Screen
* Building the project and flashing

Introduction

This piece of software was done for new year 2022, but procrastination helped me to delay the release of the tutorial, it continue the traditionnal (but with detailed explanations) LED blinking introduction tutorial. The goal of this tutorial is to learn to use potentiometer and little I²C screens (4 pins are I²C only, SPI versions use more pins) in EPE-IDF, with ESP32 microcontroller SoC based. I use here a really cheap (<5€) but powerful AI thinker ESP-C3-32S, that use an efficient low power RISC-V microcontroller.

Full schema with part 2 and 3

You can find the complete sources files and prebuild RISC-V firmware for ESP32-C3 on my files repository.

This example contain two main parts in the single file adc/esp32c3/adc/main/adc_dma_example_main.c, called in app_main(void), at the end of the file :
* One simple example single_read(NULL);, that make only one read of the state of the ADC, it uses ADC 1, channels 2,3,4) and ADC 2 (channel 0) and display datas on terminal.
* One more complex example continuous_read(NULL);, that reads 256 times the state of the channels and display them in the console, and then make continuous reading and change the onboard RGB Led blue colour light intensity.

The official documentation of the ADC.

ADC Limitations on some ESP32 SoCs

Limitations differs depending on ESP SoC, they have both 2 ADC, and one can’t be used when using WiFi:
* ESP32, based on Xtensa LX6 has 10 channels on ADC1 and 8 channels on ADC2, and ADC2 is used when Wifi is on.
* ESP32-S2 (no WiFi/BT) and ESP32-S3 (Wifi/BT), based on Xtensa LX7 (this last one has a RISC-V coprocessor for a more efficient ULP deep sleep mode), has 10 channels on both ADC, and ADC2 can’t be used when WiFi is on.
* ESP32-C3, based on RISC-V, ADC1 can’t be used with WiFi on, both ADC1 and ADC2 can’t be read simultaneously, you must read them alternately. ADC1 have 6 channels (6 pins) and ADC2 only one.

NodeMCU-series ESP-C3-32S-kit pinoutESP-C3-32S kit Pinout schema from JC François, with ADC pins in pink.

Full schema with part 2 and 3
Whole Breadboard montage with previous part tutorial and this one.

Potentiometer and OLED screen connexions
Connexions of potentiometer and OLED screen.

Potentiometer

* The first top-left pin (ADC1_CH0 / ADC_CHECK in pink) is connected to the middle pin of the potentiometer (et right on the picture) using the white wire.
* The  3.3V , here 5th pin starting from the bottom left, but other 3.3V can be choosen, is connected to the left pin of the potentiometer (at right on the picture).
* The  GND , here 6th pin starting from the bottom left, but any ground pin can be used is connected using black wire to the right pin of the potentiometer.

V Red and GND black-blue breadboard lanes
Red lane and blue/black lane of the bread board.

Both  Vcc  and Ground are transiting by dedicated lane of the breadboard, on the top of the picture painted with red (meaning Vcc) and blue (meaning for black/Ground) lines. It is very important to keep black and red wire to these roles to avoid to burn components, any other colour can be used for data links. There is another lane at bottom. This is not clear on the picture, but the screen is connected on but on the first row of the inner part.

We need to include the adc.h headers, and we also add esp_log.h header here for debug purpose.

#include "esp_log.h"
#include "driver/adc.h"

Here are the presets used for potentiometer ADC (Analog-Digital Converter) in the source code.

/* ADC vars */

esp_err_t ret;
int adc1_reading[1] = {0xcc};
int adc2_reading[1] = {0xcc};
const char TAG_CH[][9] = {"ADC1_CH0", "ADC2_CH0"};

void init_adc()
{
  adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
  adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0);
}

OLED I²C Screen

An author made an interesting list of available colour display managed by ESP32 on Instructables.

I used the driver esp-idf-ssd1306 by nopnop2002 available on github (local archive)

There are 4 connector pins on the I²C only version:
*  GND , I use black wire and connect it to GND lane.
*  VCC , I use red wire and connect it to Vcc lane.
*  VCL  (sometimes VCK, VCLK as V clock), is for the clock signal, I choose green colour wire here, I connect it to  GPIO9 , at 4th pin starting from top right.
*  VDA  (VDA as V data), I choose white colour wire here, I connect it to  GPIO10 , at 6th pin starting from top right.

The SDA/SCL GPIO can be set by two way:

By editing the sdkconfig file at the root of the project and changing the following values to the values you want:

CONFIG_SCL_GPIO=9
CONFIG_SDA_GPIO=10

Or in the menu using:

make menuconfig

Then go to submenu SSD1306 Configuration ---> Then defining the number in (9) SCL GPIO number and (10) SDA GPIO number field.

By default, this application print the current settings in the monitor console via these functions:

#if CONFIG_I2C_INTERFACE
        ESP_LOGI(tag, "INTERFACE is i2c");
        ESP_LOGI(tag, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
        ESP_LOGI(tag, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
        ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
        i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE

The example of the driver is used for the screen. It pre-include the necessary headers files. ssd1306.h is the driver itself, font8x8_basic.h is a 8×8 pixels ASCII font set, and driver/i2c.h is the i²C protocol header, used to communicate with the screen microcontroller.

#include "ssd1306.h"
#include "font8x8_basic.h"
#include "driver/i2c.h"

I removed the demo, and set all the specific code in the #if CONFIG_SSD1306_128x64 section, as this is the model of my screen.

#if CONFIG_SSD1306_128x64
        top = 2;
        center = 3;
        bottom = 8; // 8 lines
        int n=200;
        int pos=0; // initial position = 0

Le main loop (while(n) {}):
I read ADC1 channel 0 (first pin) of the potentiometer and print the current value into the console

  adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_0);
  printf("chan[%d] 0x%x = %d\n", 0, adc1_reading[0],adc1_reading[0]);

Then I compute the current p position after a constant I predetermined, after test I seen that the specific potentiometer I use, as values in range [20 ; 2920]. And I have 8 text lines on screen, so I rounded to 3000/8 = 375. Output value / 8 compute the current line on screen.

  pos=adc1_reading[0]/375; // 20~2920  => need to calibrate 3000/8=375
  printf("pos=%d\n",pos);

Clearing the 8 text lines of the buffer, but the current line

  for (int i=0;i<8;i++) {
    if ( i != pos) {
      ssd1306_clear_line(&dev, i,false);
    }
  }

Printing 2022!! at the current line. the two space, allow to center a bit the text.

  ssd1306_display_text(&dev, pos, "  2022!!", 11, false);

And finally, wait a delay of 50 milliseconds before refreshing to avoid uselessly saturating processor and overloading.

  vTaskDelay(50 / portTICK_PERIOD_MS);

That's all ! We just have to build the project and put in on the board now.

Building the project and flashing

Build the example for AI thinker ESP-C3-32S

Initialising esp-idf:


ESPIDF=/PATH/OF/YOUR/INSTALLATION/OF/esp-idf
. $ESPIDF/export.sh

Then go the the project root:

cd myproject/
 idf.py set-target esp32c3

If you have the following error:

Adding "set-target"'s dependency "fullclean" to list of commands with default set of options.
Executing action: fullclean
Directory '/data/arc/esp/esp-idf/test/adc/esp32c3/adc/build' doesn't seem to be a CMake build directory. Refusing to automatically delete files in this directory. Delete the directory manually to 'clean' it:

You simply need to clean build subdirectory if it exists

rm -R build
mkdir build

and in any case to create the CMake:

cd build
cmake ..
cd ..

Then configure the project for your SoC target, in ESP32-C3 case:

idf.py set-target esp32c3

If you need to change some settings of your porject, like GPIO ports for screen driver, you can edit the sdkconfig file or use make menuconfig now.

you will not have to redo all this procedure at each rebuild now, you can play with source code and build or rebuild/flash with the following last command:

idf.py build flash monitor
You can quit the monitor by making the CTRL + ] keys combination.