Miniphonic : Une plateforme de synthèse audio basée sur Arduino (1)
sur
Grâce aux cadres logiciels et aux bibliothèques qui sont devenus très performants au fil du temps, même avec un système compact et peu coûteux, il est possible de réaliser des tâches complexes. Dans ce projet, nous utilisons une carte Arduino Uno R4 et d'autres éléments matériels, pour réaliser un synthétiseur sonore et un séquenceur MIDI assez polyvalents et performants. Dans la première partie de cette série sur la synthèse audio, nous décrivons le schéma fonctionnel et les principales fonctions du logiciel Basic Synth.
Une plateforme de synthèse audio
Certains d'entre vous se souviennent peut-être du vieux SN76477, le célèbre générateur de sons complexe de Texas Instruments. Apparu dans les années 1970, il permettait de créer une variété de sons comme par exemple des coups de feu, des locomotives à vapeur, des sons spatiaux, et bien plus encore, y compris de petits synthétiseurs musicaux.
C'est cette dernière caractéristique qui était particulièrement intéressante. Je voulais construire un petit synthétiseur sonore depuis un certain temps, lorsque je suis tombé par hasard sur l'incroyable librairie Mozzi de Tim Barras, qui vous permet d'implémenter des synthétiseurs et des boîtes à rythmes, simplement en utilisant une carte Arduino Uno R4 Minima et quelques autres composants.

De plus, en cours de route, j'ai également trouvé le logiciel OscPocketO de Staffan, un séquenceur performant basé à son tour sur la bibliothèque Mozzi. Il a donc été décidé d'abandonner le vieux SN76477 en faveur de cette dernière solution, et MiniPhonic Audio Synthesis Platform est né, une plateforme matérielle de synthèse sonore dont les principales caractéristiques sont les suivantes :
- Un écran LCD, 20x4
- 4 potentiomètres programmables pour changer les paramètres en temps réel
- Entrée/Sortie pour la synchronisation avec un autre synthétiseur
- MIDI IN/OUT
- Amplificateur de monitoring pour casque
- Filtre LP à 4 pôles pour le CNA intégré
- Un logement pour l'Arduino Uno R4
La plate-forme de synthèse audio est structurée sur deux circuits imprimés, avec une carte principale et une carte d'affichage reliées par un câble plat à 14 broches. La Figure 1 montre le schéma fonctionnel du synthétiseur, utile pour en comprendre le fonctionnement et suivre le flux audio. Celui-ci, initialement sous forme numérique, est converti en un signal analogique via un convertisseur CNA 12 bits intégré à la puce et connecté au filtre passe-bas LPF.

A la sortie de ce filtre se trouve une résistance de découplage qui permet d'alimenter le signal audio d'autres synthétiseurs via le connecteur Insert. Ce connecteur permet d'insérer un processeur d'effets externe, comme une réverbération. Les processeurs d'effets externes ont souvent une sortie stéréo, c'est pourquoi le potentiomètre de volume et l'amplificateur de monitoring sont tous deux stéréo. Pourtant, sur la carte principale, il est possible de contourner les broches d'insertion pour configurer l'ensemble de la chaîne audio en mode mono. Pour cela, il suffit de court-circuiter les plots SJ3 et SJ4 du circuit imprimé (illustré dans la prochaine partie de cet article) avec un point de soudure.
Les sorties ligne OUT L et OUT R sont également connectées à l'amplificateur de monitoring. La plateforme offre deux applications principales:
- Basic Synth : un synthétiseur monophonique basique qui utilise l'entrée MIDI pour connecter un clavier standard et jouer en temps réel.
- Sequence : conçu comme un séquenceur autonome, avec la possibilité de piloter d'autres synthétiseurs via le connecteur SYNC ou MIDI OUT.
Ces applications peuvent être téléchargées sur la page Elektor Labs de ce projet. Examinons en détail la première d'entre elles.
Basic Synth
Le schéma de principe de l'application Basic Synth, présenté à la Figure 2, reprend la structure classique d'un synthétiseur et est basé sur une structure logicielle appelée Synthesizer Chain (voir l'encadré ci-contre), que l'on trouve à partir de la ligne 920 du code environ.

En détail, l’opération gMOscillator.next() * Lv1 >> 4 multiplie les échantillons générés par l'oscillateur DCO1 gMOscillator.next() par la valeur Lv1, mis à l'échelle de manière appropriée via l'opérateur >> 4. Cette opération simule le fonctionnement d'un potentiomètre de volume, où le signal est représenté par gMOscillator.next() et Lv1 la position angulaire du potentiomètre. La même opération est effectuée pour le second oscillateur DCO2.

Le mélangeur (MIX) est un autre bloc dans le schéma, réalisé simplement par l'opérateur + (sum), qui additionne les échantillons des deux oscillateurs. Le bloc DCA (Digital Controlled Amplifier) est réalisé en multipliant la somme des deux oscillateurs par la variable gMGain, qui est mis à jour de manière dynamique par gMEnvelope.next(). Ce composant représente un générateur d'enveloppe ADSR.
Il est important de noter les membres .next qui représentent des échantillons des flux audio ou de contrôle. Dans le schéma de principe, nous pouvons noter la position inhabituelle du DCF, qui suit le DCA au lieu de le précéder. Ceci est dû au format numérique du flux audio qui correspond mieux au DCF qui a été conçu à l'origine pour fonctionner sur l'Arduino Uno R3. (Idéalement, les bibliothèques devraient être réécrites dans un format adapté à l'Arduino Uno R4, afin de tirer pleinement parti des caractéristiques du processeur Arm Cortex4 RA4M1, qui dispose en plus d'un jeu d'instructions DSP supplémentaire).
Sur le schéma de principe, nous observons que l'entrée MIDI est connectée non seulement à DCO1 et DCO2 — pour transmettre des codes de notes et déterminer la fréquence de l'oscillateur en fonction du numéro de note MIDI — mais aussi au générateur d'enveloppe ADSR. Ce dernier utilise le code Note On et Note Off pour démarrer un cycle d'enveloppe lors de l'activation ou du relâchement d'une note. Les codes de note peuvent également être utilisés par le DCF pour modifier sa fréquence de coupure, en activant le mode Manual KBD Tracking. De cette façon, le FCD agit comme un véritable filtre de suivi. MG dans le schéma de principe signifie générateur de modulation.
L'interface utilisateur
Voyons maintenant comment l'interface utilisateur a été configurée pour cette application de plate-forme de synthèse audio. L'écran est divisé en deux parties, avec les deux premières lignes qui affichent les libellés associés aux quatre potentiomètres, indiquant le PANEL en cours.
Quatre PANEL sont disponibles (PANEL_MAIN, PANEL_ADSR, PANEL_MIXER et PANEL_FILTER) accessibles par le menu Tools, qui sera décrit plus loin. Les menus sont accessibles par les boutons MNU+ et MNU- appropriés, tandis que les boutons LEFT et RGHT permettent de sélectionner un sous-menu. VAL+ et VAL- par contre, permettent de modifier les paramètres.
Voyos les rubriques du menu principal :
WAVEFORM : Ce menu permet, à l'aide de VAL+ et VAL-, de choisir parmi cinq formes d'onde pour l'oscillateur DCO1 : Sine (Sinus), Triangular (Triangulaire), Sawtooth (Dent de scie), Square (Carrée) et une forme d'onde atypique appelée Phasor.
FILTER mode : Les touches VAL+ et VAL- permettent de modifier le mode de fonctionnement du filtre. Nous pouvons choisir entre Manual KBD Tracking dans lequel la fréquence du DCF gMFilterCutoff est décalée par le numéro de note MIDI, Random MG1 où la fréquence est décalée de façon aléatoire et avec une vitesse fixée par MG1, Mod MG1 où une modulation de forme triangulaire est appliquée avec une vitesse toujours fixée par MG1, et enfin Fast, comme le précédent, mais avec une vitesse fixe.
WAVEFORM2 : A la même fonctionnalité que WAVEFORM, mais agit sur le second oscillateur DCO2.
DETUNE 2 : Le réglage fin de l'oscillateur DCO2 (VAL+ et VAL-). Un nombre entre 1 et 2 dévie légèrement la fréquence de DCO2 afin de créer un effet de chorus avec DCO1.
TRANSPOSE 2 : Transposition de DCO2, toujours à l'aide de VAL+ et VAL-.
TOOLS : Dans ce menu, vous pouvez choisir entre les sous-menus Save, c'est-à-dire sauvegarder le réglage complet du Synthétiseur, Load, c'est-à-dire charger le réglage, et Panel dans lequel les Panels sont accessibles. Les sous-menus sont sélectionnés via les boutons LEFT et RGHT.
Dans PANEL_MAIN nous trouvons :
- FREQ ATTACK
- RESO RELEAS
où FREQ et RESO se rapportent à la fréquence de coupure et à la résonance du filtre, ATTACK et RELEAS appartiennent au générateur d'enveloppe ADSR, c'est-à-dire au temps d'attaque et au temps de relâchement. Dans le PANEL_ADSR, en revanche, nous trouvons les quatre paramètres de l'ADSR. Les paramètres SUST_LEV et DECAY en particulier, permettent de créer des sons percussifs :
- ATTACK DECAY
- SUST_LEV REL
Depuis le PANEL_MIXER, nous pouvons doser les niveaux des deux oscillateurs et la fréquence du générateur de modulation MG1 via FRM1 :
LEVL_1 FRM1
LEVL_2 ----
Bien sûr, il est possible d'augmenter le nombre de Panels en développant la fonction DrawPanel() dans le code.
Le logiciel Basic Synth
Dans setup (vers la ligne 806), nous trouvons tous les réglages de l'instrument ainsi que les initialisations. En premier lieu, nous configurons l'affichage avec gUILCD.begin(20, 4). Nous trouvons ensuite les crédits et le numéro de version du logiciel ainsi que l'initialisation MIDI, précédée par les connexions à la bibliothèque MIDI des commandes HandleNoteOn et HandleNoteOff et le démarrage de la bibliothèque MIDI en mode MIDI_CHANNEL_OMNI, dans lequel tous les canaux MIDI 1 à 16 sont reçus :
// Connect the HandleNoteOn function to the library,
// so it is called upon reception of a NoteOn.
MIDI.setHandleNoteOn(HandleNoteOn);
// Put only the name of the function
MIDI.setHandleNoteOff(HandleNoteOff);
// Put only the name of the function
// Initiate MIDI communications,
// listen to all channels
MIDI.begin(MIDI_CHANNEL_OMNI);
La fonction HandleNoteOn est utilisée par le clavier connecté au port MIDI IN, et joue une note à la réception du message NoteOn. Cette note persiste jusqu'à la réception du message NoteOff, ou jusqu'à l'expiration du gMSustainTime, via la fonction HandleNoteOff.
Tous les arrangements de la bibliothèque Mozzi suivent à partir de la ligne 834 environ, afin que le synthétiseur puisse commencer à jouer immédiatement. L'interface utilisateur (User Interface Draw) est lancée vers la ligne 868 environ, et immédiatement après, la bibliothèque Mozzi est lancée :
UIDraw();
startMozzi(CONTROL_RATE)
Dans la fonction updateControl(), sont effectués l'interrogation du port MIDI avec MIDI.read(), la mise à jour de l'enveloppe avec gMEnvelope.update() et la gestion des boutons avec la fonction UIHandle().
STEP RANDOM GENERATOR ou MG1 est ensuite exécuté, ce qui est responsable de la génération d'une séquence aléatoire de données et d'une onde triangulaire, résultant en RndAcc et MG1acc, respectivement.
Ces deux valeurs seront utilisées ultérieurement pour moduler le filtre. La fréquence est déterminée par le générateur de modulation MG1, dont la valeur est contrôlée par le potentiomètre FRM1, situé dans le troisième panel du menu. Il est important de noter que cette fréquence est proportionnelle au CONTROL_RATE, déjà introduit dans la fonction StartMozzi.
Il y a également une implémentation d'un second générateur de modulation MG2, qui peut être concaténé avec le premier pour d'autres possibilités de modulation. Enfin, le flux audio est mis à jour via la fonction updateAudio(). C'est la fonction la plus importante car elle encapsule le traitement du flux audio, c'est-à-dire la chaîne du synthétiseur que nous avons vue au début. Elle termine la boucle qui contient l'appel principal à la bibliothèque Mozzi audioHook().
La synthèse sonore, en quelques mots
Le son est principalement caractérisé par la fréquence, qui est le nombre de périodes par seconde, et est mesuré en Hertz (Hz). Par exemple, 100 Hz signifie 100 périodes par seconde (voyez la Figure A), ou 100 oscillations par seconde. Dans le cas d'une corde, cela signifie qu'elle vibrera 100 fois par seconde.

Si notre fréquence prend la valeur de 440 Hz, nous jouons un « la » naturel, et si la fréquence descend à 220 Hz, nous jouons toujours un « la » , mais une octave plus bas. 880 Hz, en revanche, correspond à un « la » d'une octave plus haut. En plus de cela, le son est caractérisé par le timbre, c'est-à-dire le contenu harmonique, qui permet de distinguer par exemple le son d'une guitare de jazz (qui a peu d'harmoniques) d'un son distordu, qui en a beaucoup.
Si le son n'a pas d'harmoniques, il est défini comme une onde sinusoïdale et peut être défini comme un son pur, comme celui de la Figure A. Par contre, s'il a des harmoniques, sa forme d'onde est beaucoup plus complexe. Les harmoniques ne sont rien d'autre que des sons superposés au son original, appelé fondamentale, qui définit la fréquence du son. Ces tonalités peuvent avoir une fréquence double, triple, etc. et sont respectivement appelées deuxième harmonique, troisième harmonique, et ainsi de suite. Par exemple, une onde carrée sera caractérisée par la première harmonique fondamentale, à laquelle se superposent la troisième harmonique, la cinquième harmonique, la septième harmonique et ainsi de suite, dans un ordre impair et avec une amplitude décroissante.

L'onde carrée a un timbre plutôt rude. Si d'un autre côté, nous incluons des harmoniques paires, la forme d'onde deviendra asymétrique, comme une rampe ou une dent de scie, dont le timbre est moins désagréable. Les oscillateurs des synthétiseurs sont généralement capables de générer les formes d'onde de base telles que SINUSOIDALE, RAMPE, CARRÉE et TRIANGULAIRE (Figure B). Mais il existe des oscillateurs capables de produire des formes d'onde beaucoup plus complexes, voire des formes d'onde échantillonnées à partir d'instruments réels, il s'agit des oscillateurs à tables d'ondes, qui sont utilisés dans notre synthétiseur ici.

Il est également possible d'utiliser deux oscillateurs, dont le deuxième est transposé avec un intervalle de quinte (7 demi-tons), ou d'octave (12 demi-tons) pour obtenir des sons particulièrement riches. Le DCF (Digital Controlled Filter) est un autre composant clé visible dans la Figure C, c'est-à-dire le filtre numérique contrôlé qui est capable de changer le contenu harmonique de notre son de manière dynamique.

Il s'agit généralement d'un filtre passe-bas avec résonance, c'est-à-dire un filtre qui ne laisse passer que les fréquences inférieures à la fréquence de coupure (Figure D). Cette Cutoff Frequency peut être réglée à volonté et être manipulée par exemple par un générateur d'enveloppe AR (Attack Release) ou un MG (générateur de modulation), comme c'est le cas de notre synthétiseur.
Le paramètre RESONANCE, par contre, crée dans le filtre un pic de résonance (Figure E) qui peut être dosé en amplitude par un potentiomètre approprié et qui peut évidemment être décalé en fréquence en fonction de la fréquence de coupure CUTOFF FREQUENCY.

L’amplitude est un autre paramètre important du son, c'est-à-dire l'amplitude de l'oscillation (on fait varier l'amplitude, par exemple, en augmentant ou en diminuant le volume), et surtout la façon dont l'amplitude varie dans le temps. Une flûte par exemple, produit un son qui n'atteint pas immédiatement son maximum à l'émission, mais après un certain temps et selon une rampe croissante. Ce temps est appelé ATTACK.

Dans le cas des instruments à cordes, par contre, le son continue longtemps après que la corde a été pincée, mais avec une amplitude décroissante. Le moment où le son diminue est appelé RELEASE (relâchement). Le ENVELOPE GENERATOR (générateur d’enveloppe), ainsi que le modulateur d'amplitude (dans notre cas le DCA ou Digital Controlled Amplifier, Figure F) se chargent de manipuler le son à travers les paramètres ATTACK et RELEASE, comme à la Figure G.

En fait, le paramètre ATTACK, visible en rouge dans la Figure H, fait passer l'amplitude du flux audio de zéro au maximum dans un temps qui peut être court ou long, selon la position du potentiomètre.

Pour obtenir un meilleur son, il convient d'utiliser un générateur d'enveloppe plus sophistiqué, appelé ADSR, comme celui implémenté dans notre synthé, qui dispose de deux paramètres supplémentaires par rapport au générateur AR, à savoir le DECADE ou temps de DECAY et le SUSTAIN ou SUSTAIN LEVEL, montré à la Figure I.

Ce générateur d'enveloppe nous permet de créer parfaitement le son pincé d'une corde, comme celui d'un clavecin ou d'une guitare. Nous pouvons vérifier cette fonction en sélectionnant le panel ADSR, en réglant ATTACK au minimum, SUST_LEV à 1/3 de la course et DECAY à environ la moitié. Nous obtiendrons un très bon son percussif, similaire à une corde pincée, surtout lorsqu'il est utilisé avec la forme d'onde en dent de scie.
Prochainement
Dans la deuxième partie de cette série d'articles sur la synthèse audio, nous décrirons l'application et le firmware de Sequence, nous présenterons les schémas de câblage de la carte principale et de la carte d'affichage (avec la liste de leurs composants), et il y aura quelques notes sur la mise en œuvre pratique du projet. Restez à l’écoute !
Note de l'éditeur : ce projet de plate-forme de synthèse audio a été publié à l'origine dans Elettronica IN.
Traduction : Laurent RAUBER
Discussion (1 commentaire(s))