IMA5 2018/2019 P43 : Différence entre versions

De Wiki de Projets IMA
(Description)
Ligne 255 : Ligne 255 :
  
 
C'est l'idée brillante des concepteurs du MIDI. En effet, cela permet au différents fabricants de faire communiquer leurs synthétiseurs entre eux, sans prendre en compte leur standard de tension. En plus de cela, cela permet d'éviter les pertes importantes de tensions dans les longs câbles, car ils utilisent des boucles de courant.
 
C'est l'idée brillante des concepteurs du MIDI. En effet, cela permet au différents fabricants de faire communiquer leurs synthétiseurs entre eux, sans prendre en compte leur standard de tension. En plus de cela, cela permet d'éviter les pertes importantes de tensions dans les longs câbles, car ils utilisent des boucles de courant.
 +
 +
 +
 +
==Semaine 5==
 +
 +
 +
Une fois le circuit mis en place j'ai pu tester grâce à un analyseur logique que les données étaient effectivement reçues. Pour cela j'ai connecté le port midi à mon ordinateur via un boîtier spécialisé et j'ai envoyé des données via un logiciel nommé MidiOx. N'ayant pas apporté de clé USB lors du test je n'ai pas de capture d'écran mais cela ressemblait à ceci (exemple des messages Note_On et Note_Off) :
 +
 +
[[Fichier:Analyse_logique.png|600px|center]]
 +
 +
<center>''fig 7. Messages Note_On et Note_Off.''</center>
 +
 +
 +
Ces messages vont donc être transmis à l'Arduino afin d'être traités. Ils sont transmis via le port Rx avec un baudrate peu conventionnel et propre au midi valant 31250. A partir de la, les données doivent être analysées. Pour cela je voulais d'abord ré-implémenter la machine à état finis que j'avais crée lors de mon stage de 4ème année. Cependant, cette machine à état finis fait parti d'un système bien plus large, et donc lourde pour cette application, et est codée pour les noms de registres et les paramètres d'un autre système (Système ARM).
 +
 +
''Remarque :'' Il faudra ajouter un switch entre la réception et le port Rx. En effet sans cela l'opto-coupleur interférerais avec le port Rx même quand il n'y a pas de messages et empêcherais l'upload de nouveaux programmes sur l'arduino.
 +
 +
Afin de nous simplifier le travail la base de librairies arduino propose une librairie Midi développée par [https://github.com/FortySevenEffects/arduino_midi_library Forty Seven Effects]. En regardant la documentation de cette librairie on se rend compte qu'elle permet l'usage de callbacks. Un callback est une fonction que l'on écrit et qui va appeler la librairie uniquement lorsqu'un message arrivera. Cela évite de faire tourner le programme en continu et d'utiliser tout le CPU. Pour les utiliser c'est simple, lors de l'initialisation ('''void setup()''') on active le callback voulu. Ainsi, '''MIDI.setHandleNoteOn(NoteOnHandler)''' appellera la fonction NotOnHandler lorsque qu'une note sera jouée.
 +
[[Fichier:MPC4725.jpg|thumb| DAC Adafruit MPC4725]]
 +
 +
Nous pourrons donc traiter indépendamment les différents messages (si on veut faire évoluer le programme). Nous décrirons un peu plus bas le traitement des notes avec des exemples de code. Avant cela nous devons régler le problème de la sortie. L'arduino seul n'est pas capable de sortir directement des voltages stables. A la place il utilise des pulsations de périodes variées (PWM). Il nous faut donc un convertisseur digital vers analogique (DAC). Il y a plusieurs manières de réaliser un DAC, comme une échelle R-2R par exemple, ou un filtre RC. Cependant, pour contrôler un VCO nous avons besoin d'un DAC assez précis dans la mesure ou un écart entre deux semi-tons est environ égal à 0.083V. J'ai donc décidé d'utiliser un DAC dédie, le MPC4725 d'Adafruit qui a une librairie dédiée pour les modules arduino. Nous allons maintenant voir les différentes parties du code :
 +
 +
<u>Variables</u>
 +
 +
Différentes variables seront utilisées pour ce code :
 +
 +
* MIDI_CHANNEL : Canal d'écoute des messages midi.
 +
* Voltage : Voltage en mV correspondant à la note jouée.
 +
* dacValue : Valeur transmise au DAC.
 +
* VLinCoeff : Variable permettant un tuning lors de la mise en pratique.
 +
* Vshift : Permet d'augmenter ou diminuer d'octave.
 +
* LastNote : Stockage de la note jouée pour vérification dans la fonction Note_Off
 +
 +
 +
<u>Setup()</u>
 +
 +
* MIDI_CREATE_DEFAULT_INSTANCE :  Crée et lie l'interface MIDI au port Série du matériel.
 +
* TCCR1B = TCCR1B & B11111000 | B00000001 : Augmente la fréquence de la PWM du timer 1 (Pin D9 et D10) en réglant son diviseur à 1. On obtient alors une fréquence de 31372.55 Hz, ce qui permet de réduire les ondulations de tension en sortie.
 +
* MIDI.setHandleNoteOn(Note_On_Handle) et MIDI.setHandleNoteOff(Note_Off_Handle) : Initialisation des callbacks.
 +
* MIDI.begin(MIDI_CHANNEL) et dac.begin(0x60) : Initialisation de la connexion MIDI et DAC.
 +
 +
La fonction '''MIDI.read(MIDI_CHANNEL)''' sera placée dans la boucle pour lire les messages en continu.
 +
 +
 +
<u>La fonction Note_On_Handle(byte channel, byte note, byte velocity)</u>
 +
 +
* Tout d'abord la fonction sauvegarde la note dans la variable LastNote
 +
* On calcule ensuite le Voltage à l'aide de la formule '''Voltage = 1000*((note*VoctLinCoeff)+ VoctShift)'''
 +
* Le Voltage à été multiplié par 1000 car les valeurs décimales sont tronquées par la fonction constrain(). Or, nous appelons cette fonction pour le calcul de la valeur du DAC :
 +
<div class="center" style="width: auto; margin-left: auto; margin-right: auto;">'''dacValue = constrain(map(Voltage, 0, 5000, 0, 4095), 0, 4095)'''</div>
 +
La fonction Constrain ré-étalonne un nombre d'une fourchette de valeur vers une autre fourchette. Cette fonction ne contraint pas les valeurs à rester dans les limites indiquées, d'où l'utilité de la fonction constrain.
 +
* Finalement on applique au dac la valeur souhaitée avec la fonction '''dac.setVoltage(dacValue, false)'''
 +
 +
Pour la fonction Note_Off_Handle teste si la note reçue est la note jouée auparavant. Si c'est le cas, elle met à 0 la valeur envoyée au DAC.

Version du 8 novembre 2018 à 23:32

Présentation générale

  • Titre : Conception d'un synthétiseur


Description

Afin de compléter ma formation d'ingénieur en option IMA-SC j'ai décidé de me lancer dans la réalisation d'un synthétiseur. En effet, ce PFE s'inscrit dans une volonté de poursuite de mon projet professionnel. Voulant travailler dans l'industrie de la musique, il me permettra d'avoir un premier contact avec les notions techniques qu'elle implique.

Fort heureusement, mon sujet à été accepté en me laissant une grande liberté. Le synthétiseur pourra alors évoluer assez librement lors de l'année. Il me faut cependant réfléchir à toutes les étapes, afin de passer des premières idées sur papier au produit final. Cela n'est pas tout le temps évident, nous le verrons.

Le projet mêle électronique analogique et numérique, leur proportion pourra évoluer selon les idées ou les difficultés rencontrées en cours de route. Mon premier choix de microcontrôleur se porte sur la famille Atmega qui, par sa simplification de codage, permet de réaliser de la DSP assez efficacement.

Un travail très important de recherche devra être réalisé en amont afin d'assurer une base de connaissances suffisante et nécessaire au bon déroulement du projet.

Objectif principal

Concevoir et réaliser un instrument de musique électronique (Synthétiseur) mélodieux et comportant un ensemble de fonctionnalités accessible à l'utilisateur.

Préparation du projet

Cahier des charges

Choix techniques : matériel et logiciel

Le matériel utilisé pour ce projet n'est pas strictement fixé et est amené à évoluer durant toute la durée de celui-ci. Je tâcherai cependant d'actualiser au fur et à mesure de l'avancement de mes recherches le descriptif suivant :

Partie matériel

La description du matériel nécessaire se fait en séparant le projet en blocs fonctionnels :

DSP:

  • 1 microcontrôleur Atmega


Partie logiciel

  • Arduino IDE
  • Altium Designer


Liste des tâches à effectuer

Ce projet peut se découper en une multitudes de taches à effectuer :

1. Définition des fonctionnalités de l'instrument
2. Recherches bibliographiques
3. Réalisation du VCO
4. Codage de la DSP numérique (ADSR)
5. Réalisation d'un filtre
6. Réalisation du VCA
7. Réalisation de différents effets intégrés
8. Gestion du MIDI
9. Ajout de fonctionnalités (en fonction du temps restant)
10. Réalisation du boîtier et mise en place du circuit


Réalisation du Projet

Semaine 1

Lorsque j'ai commencé à réfléchir à quoi mon synthétiseur allait ressembler, je dois avouer que j'étais légèrement perdu dans la multitude de possibilités. Les idées venaient par centaines les unes au dessus des autres, toutes plus motivantes les unes que les autres, mais souvent bien incompatibles..

Il me fallait trouver une méthodologie de gestion de projet et découper mon objectifs en sous-catégories. D'une autre part il me fallait des gardes fous afin de ne pas m'emballer et partir sur des idées interminables. J'ai décidé de contacter mon tuteur de stage à Montréal qui travaille dans l'industrie des synthés modulaires. Après plusieurs heures de discussion, voici les principales questions que je me suis posées et auxquelles je me suis appliqué à répondre :


Desktop Synth VS Keyboard

Le légendaire Juno 106 (en haut) et sa version desktop (en dessous)

Voici la première question : A quoi va ressembler le synthétiseur ? Il a plusieurs types de synthétiseur et parmi eux les Keyboards et les Desktop synths. Alors que le premier incorpore les touches à son boîtier, l'autre et une version plus petite et compact. C'est vers cela que je vais me tourner.

Quels sont les avantages ?

  • Dans le commerce, les synthétiseurs Desktop sont généralement moins cher. Ici, la conception étant entièrement réalisée par mes soins, cela me permet d'oublier la gestion des touches et d'éviter leur achat.
  • La taille : Mon but, au delà du projet scolaire, est de garder le synthétiseur et de pouvoir l'utiliser pour mes projet musicaux personnels. Un synthétiseur ainsi réalisé permet de gagner de la place lorsque qu'il est installé dans une configuration d'instruments.
  • Facilement séquençable : Un séquenceur est un outil capable d'enregistrer et exécuter une séquence de commandes permettant de piloter des instruments de musique électronique. Il ne produit aucun son par lui-même, mais sert à automatiser l’exécution d'une séquence musicale.

Qu'est ce que cela implique ?

Le synthétiseur comporte un ou plusieurs VCO qui vont générer les notes. Cependant, sans clavier il faut ajouter au synthétiseur Desktop un moyen de contrôle des notes. Ceci se fera grâce à l'ajout d'un port MIDI IN. Cela implique un code de gestion des messages midi et de conversion de ces derniers en tension pour la commande du/des VCO.


Analogique ou Digital ? / Monophonique ou Polyphonique ?

Lors de l'apparition des premiers synthétiseurs, ces derniers se ressemblaient beaucoup. Tout les sons étaient générés analogiquement, c'est à dire qu'il reposaient tous sur un signal électrique analogique. Les circuits étaient complexes et en résultait principalement des synthétiseurs monophoniques (ne pouvant jouer qu'une note à la fois).

Avec l'arrivée du digital la polyphonie s'est grandement développée. Les synthétiseurs digitaux ont permis une approche simplifiée de la polyphonie (Réduction de la complexité et du coût). En effet, un synthétiseur analogique doit, pour être polyphonique, ajouter chaque voix individuellement à la chaîne du signal et dans l'ordre pour créer le son de l'accord joué.

Dans la mesure où je voulais réaliser un synthétiseur analogique (par envie d'étendre mes connaissance en électronique analogique et par amour du son analogique), mon choix s'est naturellement porté vers la monophonie.

Je précise que l'aspect analogique du synthétiseur que j’entreprends de réaliser concerne la génération du son (VCO) et d'autres blocs tels que le VCA ou le filtre par exemple. Une partie digitale sera en effet présente pour la gestion de différents éléments (ADSR, MIDI IN).


Quelles seront les fonctionnalités ?

Une fois le type de synthétiseur défini il m'a fallu réfléchir aux fonctionnalités qu'il apportera. En effet jusqu'ici, si l'on suppose avoir un VCO et un VCA, on a simplement le son d'un oscillateur que l'on contrôle de manière externe via un port MIDI.

Que peux-ton faire pour modifier ce signal et offrir à l'utilisateur un minimum d’interaction ? Les idées et possibilités sont infinies. C'est pour cela que la réponse à cette question risque de changer tout au long de l'année. Pour le moment j'aimerai pouvoir :

  • Coder une enveloppe ADSR sur le microcontrôleur
  • Concevoir un filtre analogique
  • Ajouter des effets analogiques (Delay, Reverb, Chorus)
  • Réaliser un LFO assignable à plusieurs paramètres (Fréquence de coupure du filtre, paramètres d'effets etc..)
  • (Dépendra du temps) Rendre le synthétiseur semi-modulaire


J'expliquerai plus en détail chacune de ces parties dans des paragraphes dédiés.

Semaine 2

Une fois les bases du projet posées, il m'a fallu découper le synthétiseur en blocs fonctionnels. Cela me permet de travailler sur chacun d'eux séparément, tout en réfléchissant à comment les rassembler en terme de niveaux de signal et de contrôle. Le microcontrôleur sera alors le cerveau sous-jacent qui contrôlera l'ensemble :

Synth global view.jpg
fig 1. Vue d'ensemble des blocs fonctionnels du synthétiseur.


Un VCO, c'est quoi ?

L'oscillateur est un circuit qui produit un signal périodique. En réglant la fréquence dans le domaine de l'audible (20 Hz - 20 kHz), on peut générer un signal utilisable pour le synthétiseur. Ce signal peut prendre plusieurs formes (rectangulaire, triangulaire, sinusoïdale, dent de scie), impactant alors le timbre du son.

  • Exemple d'un oscillateur simple


Oscillator schematic.jpg
fig 2. Oscillateur simple.


Ce qu'on appelle un oscillateur simple est un circuit qui génère un signal périodique à une fréquence fixe. Dans ce circuit que j'ai utilisé pour mon projet de 4ème année, un transistor placé dans sa zone d'avalanche produit un signal en dent de scie dont la fréquence est variable grâce au potentiomètre.

Pour un synthétiseur cela n'est pas très pratique. Il est nécessaire d'obtenir des fréquences précises correspondantes aux notes jouées; Par exemple, le LA3 se trouvant au centre d'un piano, correspond à une fréquence fondamentale de 440 Hz. Pour jouer un LA3 il faudrait un oscillateur produisant cette fréquence. On ne va ainsi pas créer un oscillateur pour chaque note, il suffit de rendre cet oscillateur ajustable.

  • Le VCO (Voltage Controlled Oscillator)

Un VCO est un oscillateur dont la fréquence du signal dépend d'une tension continue. Cela permet principalement de jouer l'intégralité des notes du clavier avec un seul oscillateur (dans un mode monophonique). La tension contrôlant l'oscillateur dépendra alors de la note jouée, et sera produite par le microcontrôleur.

Avoir une tension qui défini la fréquence présente d'autres avantages comme par exemple :

  • Possibilité d'ajouter un effet vibrato : On ajoute à la tension de contrôle une composante alternative de faible amplitude.
  • Glissando/Portamento : Si l'on peut gérer la vitesse de changement de tension d'une note à l'autre on peut ajouter un effet de Portamento (imaginez un slide sur une corde de guitare par exemple).

Et ce n'est que quelques idées qui m'ont traversées l'esprit, les possibilités sont nombreuses.

Korg MS-10



Choix du VCO : Le Korg MS-10

Après avoir passé beaucoup de temps à lire des documentations techniques et des articles sur les différentes marques/modèles de synthétiseurs j'ai décidé d'essayer de reproduire le VCO du Korg MS-10.

Le Korg MS-10 est un synthétiseur analogique monophonique semi-modulaire sorti à la fin des années 70. Ce synthétiseur est un classique utilisé par de nombreux artistes. J'ai toujours été admiratif du son de ce synthétiseur et voulu le posséder. Le circuit est complexe en apparence, mais ma motivation d'avoir le son original Korg dépasse la peur de l'incompréhension.

En fouillant les archives de Korg et des manuels techniques j'ai trouvé plusieurs schémas qu'il m'a fallu déchiffrer afin d'en comprendre le fonctionnement.


Semaine 3

MS10 circuit.jpg
fig 3. Circuit du Korg MS-10.


Afin d'étudier et de comprendre le circuit du VCO à l'origine du mythique son du Korg MS-10, j'ai cherché le manuel de service disponible au public. Ces manuels contiennent généralement les schémas complets des circuits qui composent le synthétiseur. Je l'ai trouvé assez facilement sur le site SynthManuals.

Il n'y a pas beaucoup de choses à reporter sur cette 3ème semaine. En effet, elle à été intégralement consacrée à l'étude et la compréhension du circuit dans le but d'isoler le VCO et de comprendre son fonctionnement.

Cependant, j'ai commencé en parallèle les recherches sur la partie DSP (Digital Signal Processive). Plus particulièrement, j'ai commencé à me renseigner sur le CV (Control Voltage) afin de passer du midi au voltage de la note jouée.


Semaine 4

Miss10

Lors de la semaine 3, je suis tombé par hasard sur le projet Miss10 en allant sur le forum MuffWiggler auquel je suis abonné. Ce projet, initié par un fan de musique, a pour but de rendre hommage au Korg Ms-10. Cela tombait plutôt bien. Voici le schéma publié par la petite entreprise E.A.S (Ce circuit étant conçu pour une intégration dans un système de synthétiseur modulaire certaines fonctionnalités dont on n'aura pas forcément besoin sont présentes) :

Miss 10.jpg
fig 4. Circuit du VCO.


Je me penché en profondeur sur ce circuit. Bien que certaines techniques d'oscillation et de réglages de pitch m'étaient familières, j'ai eu du mal à comprendre le fonctionnement détaillé. J'ai alors décidé d'écrire à mon tuteur de stage à Montréal spécialisé dans les synthétiseurs.

En attendant sa réponse j'ai commencé à faire des recherches sur le moyen d'assurer le CV pour le contrôle du VCO.


Le CV, c'est quoi ?

Le CV (Control Voltage) est une méthode analogue permettant de contrôler les synthétiseurs. Il trouve son origine dans les premiers synthétiseurs modulaires qui, à l'aide de câbles manipulés par l'utilisateur, faisaient circuler un voltage à travers plusieurs composants (VCO, filtre, effets..). Sur la plupart des modules on retrouvait alors une prise "CV" permettant de moduler un paramètre, comme la fréquence de coupure du filtre par exemple.


Dans notre cas, il va permettre de jouer la note voulue. En effet, comme nous l'avons expliqué plus haut, le VCO à besoin d'une tension afin d'être commandé. Nous communiquerons avec le synthétiseur via MIDI. Le micro-contrôleur se chargera alors d'effectuer la conversion MIDI->CV à l'aide d'un DAC. Il y a deux implémentations majeures du CV :


Les 2 standards
  • Le Volt/Octave : Comme son nom l'indique, 1V équivaut à une octave. Ce standard à été popularisé par Bob Moog dans les années 60 et est utilisé dans de nombreux appareils.
  • Le Hz/Volt : Dans cette configuration, augmenter d'une octave revient à doubler la tension. Ce mode est majoritairement utilisé par les compagnies Korg et Yamaha'. Comme nous basons notre VCO sur le Korg MS-10 nous devrions en théorie utiliser ce standard. Mais cela ne nous arrange pas car l'Arduino ne peut délivrer au maximum que 5V. Or pour l'octave la plus haute il faudrait dans cette configuration atteindre 16V (Schéma à droite). Heureusement la version du VCO de Miss10 permet le contrôle V/Octave.


Le langage MIDI

Le langage MIDI (abréviation de Musical Instrument Digital Interface) est un langage inventé dans les années 80. C'est un protocole de communication dédié à la musique permettant l'interaction entre les instruments électroniques, et les différents contrôleurs, séquenceurs.

Les messages MIDI sont généralement composés de 2 octets (mais peuvent aller jusqu'à 4). On les distingue en deux catégories majeures définies par leur premier bit.

Midi messages.jpg
fig 5. Les messages midi.


  • Si le premier bit est de poids fort, il s'agit d'un status byte. Eux-mêmes se décomposent en nibble (demi-octets). Le premier nibble indique la commande. Dans notre cas, nous nous concentrerons les octets Note On et Note Off qui, comme leur nom l'indique, indiquent lorsqu'une note est jouée ou arrêtée. Le second indique le canal.
  • Si le premier bit est de poids faible, il s'agira alors d'un data byte qui apportera des informations complémentaires à l'octet de statut. Les octets Note On et Note Off sont accompagnés de deux octets de données. Le premier indique la note jouée, le deuxième la vélocité (force avec laquelle la touche à été pressée).


Donc, lorque l'utilisateur joue un LA440 (A4 en anglais) cela produira le message: 0x90(NoteOn) 0x69(A4) 0x64(Velocity) Le langage midi comporte un grand nombre d'octet de status permettant toute sorte de choses (contrôle de séquence, changement de preset etc..) mais nous n'aurons besoin que de ces deux pour le moment.


Circuit de réception : MIDI_INPUT

Toutes les informations sur le MIDI peuvent être facilement trouvées sur le site de la MIDI manufacturers association. En cherchant sur le site, j'ai pu établir sur logiciel ce schéma de réception MIDI:

MIDI IN.jpg
fig 6. Circuit MIDI_IN.


Ce circuit, assez simple, utilise un optocoupleur. Un optocoupleur permet la transmission de donnée sans connexion électrique. Le signal en entrée fait clignoter une DEL et la lumière produite est captée par un phototransistor qui la convertit à nouveau en signal électrique.

Les pins 4 et 5 sont reliée respectivement à l'anode et la cathode de la LED. Lorsque aucune information est transmise, les pins 4 et 5 sont au même voltage et la DEL n'est pas allumée. Donc l'UART reçoit une tension en Pull-up et il en résulte un signal logique à 1. Et inversement lorsqu'une donnée est transmise.

C'est l'idée brillante des concepteurs du MIDI. En effet, cela permet au différents fabricants de faire communiquer leurs synthétiseurs entre eux, sans prendre en compte leur standard de tension. En plus de cela, cela permet d'éviter les pertes importantes de tensions dans les longs câbles, car ils utilisent des boucles de courant.


Semaine 5

Une fois le circuit mis en place j'ai pu tester grâce à un analyseur logique que les données étaient effectivement reçues. Pour cela j'ai connecté le port midi à mon ordinateur via un boîtier spécialisé et j'ai envoyé des données via un logiciel nommé MidiOx. N'ayant pas apporté de clé USB lors du test je n'ai pas de capture d'écran mais cela ressemblait à ceci (exemple des messages Note_On et Note_Off) :

Analyse logique.png
fig 7. Messages Note_On et Note_Off.


Ces messages vont donc être transmis à l'Arduino afin d'être traités. Ils sont transmis via le port Rx avec un baudrate peu conventionnel et propre au midi valant 31250. A partir de la, les données doivent être analysées. Pour cela je voulais d'abord ré-implémenter la machine à état finis que j'avais crée lors de mon stage de 4ème année. Cependant, cette machine à état finis fait parti d'un système bien plus large, et donc lourde pour cette application, et est codée pour les noms de registres et les paramètres d'un autre système (Système ARM).

Remarque : Il faudra ajouter un switch entre la réception et le port Rx. En effet sans cela l'opto-coupleur interférerais avec le port Rx même quand il n'y a pas de messages et empêcherais l'upload de nouveaux programmes sur l'arduino.

Afin de nous simplifier le travail la base de librairies arduino propose une librairie Midi développée par Forty Seven Effects. En regardant la documentation de cette librairie on se rend compte qu'elle permet l'usage de callbacks. Un callback est une fonction que l'on écrit et qui va appeler la librairie uniquement lorsqu'un message arrivera. Cela évite de faire tourner le programme en continu et d'utiliser tout le CPU. Pour les utiliser c'est simple, lors de l'initialisation (void setup()) on active le callback voulu. Ainsi, MIDI.setHandleNoteOn(NoteOnHandler) appellera la fonction NotOnHandler lorsque qu'une note sera jouée.

DAC Adafruit MPC4725

Nous pourrons donc traiter indépendamment les différents messages (si on veut faire évoluer le programme). Nous décrirons un peu plus bas le traitement des notes avec des exemples de code. Avant cela nous devons régler le problème de la sortie. L'arduino seul n'est pas capable de sortir directement des voltages stables. A la place il utilise des pulsations de périodes variées (PWM). Il nous faut donc un convertisseur digital vers analogique (DAC). Il y a plusieurs manières de réaliser un DAC, comme une échelle R-2R par exemple, ou un filtre RC. Cependant, pour contrôler un VCO nous avons besoin d'un DAC assez précis dans la mesure ou un écart entre deux semi-tons est environ égal à 0.083V. J'ai donc décidé d'utiliser un DAC dédie, le MPC4725 d'Adafruit qui a une librairie dédiée pour les modules arduino. Nous allons maintenant voir les différentes parties du code :

Variables

Différentes variables seront utilisées pour ce code :

  • MIDI_CHANNEL : Canal d'écoute des messages midi.
  • Voltage : Voltage en mV correspondant à la note jouée.
  • dacValue : Valeur transmise au DAC.
  • VLinCoeff : Variable permettant un tuning lors de la mise en pratique.
  • Vshift : Permet d'augmenter ou diminuer d'octave.
  • LastNote : Stockage de la note jouée pour vérification dans la fonction Note_Off


Setup()

  • MIDI_CREATE_DEFAULT_INSTANCE : Crée et lie l'interface MIDI au port Série du matériel.
  • TCCR1B = TCCR1B & B11111000 | B00000001 : Augmente la fréquence de la PWM du timer 1 (Pin D9 et D10) en réglant son diviseur à 1. On obtient alors une fréquence de 31372.55 Hz, ce qui permet de réduire les ondulations de tension en sortie.
  • MIDI.setHandleNoteOn(Note_On_Handle) et MIDI.setHandleNoteOff(Note_Off_Handle) : Initialisation des callbacks.
  • MIDI.begin(MIDI_CHANNEL) et dac.begin(0x60) : Initialisation de la connexion MIDI et DAC.

La fonction MIDI.read(MIDI_CHANNEL) sera placée dans la boucle pour lire les messages en continu.


La fonction Note_On_Handle(byte channel, byte note, byte velocity)

  • Tout d'abord la fonction sauvegarde la note dans la variable LastNote
  • On calcule ensuite le Voltage à l'aide de la formule Voltage = 1000*((note*VoctLinCoeff)+ VoctShift)
  • Le Voltage à été multiplié par 1000 car les valeurs décimales sont tronquées par la fonction constrain(). Or, nous appelons cette fonction pour le calcul de la valeur du DAC :
dacValue = constrain(map(Voltage, 0, 5000, 0, 4095), 0, 4095)

La fonction Constrain ré-étalonne un nombre d'une fourchette de valeur vers une autre fourchette. Cette fonction ne contraint pas les valeurs à rester dans les limites indiquées, d'où l'utilité de la fonction constrain.

  • Finalement on applique au dac la valeur souhaitée avec la fonction dac.setVoltage(dacValue, false)

Pour la fonction Note_Off_Handle teste si la note reçue est la note jouée auparavant. Si c'est le cas, elle met à 0 la valeur envoyée au DAC.