
Il y a quelques mois j’ai commencé la réalisation d’un synthétiseur modulaire analogue, qui est encore en cours de réalisation. Quelques temps après, mon école a demandé de développer un projet à long terme de notre choix. J’ai décidé de créer le code pour une interface MIDI à CV pour complémenter le synthétiseur. Voici un vidéo qui explique l’essentiel des fonctions de l’extension.
À la base, c’est un fichier .h qui est ajouté au dossier du sketch principal et qui se jumelle à la librairie MIDI.h pour interpréter les données reçues et réagir selon les paramètres de l’utilisateur. Je prévois publier une version mise à jour sous la forme d’une libraire qui supportera plusieurs canaux et sera optimisée pour réduire l’utilisation des ressources de certaines opérations. Elle sera aussi optimisée pour l’utilisation d’une interface graphique ou pour son utilisation dans un convertisseur à paramètres fixes.
Schéma du circuit
Voici le schéma circuit que j’utilise actuellement pour connecter l’entrée MIDI au Arduino. Si vous prévoyez créer une interface, il est fortement recommandé d’utiliser un convertisseur digital à analogue d’au moins 12 bits. Je recommande personnellement la puce MCP4728, un DAC à quatre sorties 12 bit fonctionnant sur I2C qui vous coûtera la modique somme de 3$. Elle possède une librairie, que vous pouvez télécharger ici. La librairie a été écrite sur une vielle version de l’IDE d’Arduino, et certaines commandes de base ont changé depuis. La librairie doit être modifiée pour fonctionner. Voir ce post sur le forum Arduino pour plus de détails.
Utilisation de base
Afin de bien faire fonctionner le tout, il faut écrire quelques lignes de code. D’abord, au haut de votre sketch, inclure la librairie MIDI.h
(si vous ne l’avez pas, allez ici).
#include "MIDI.h"
MIDI_CREATE_DEFAULT_INSTANCE();
Avant d’inclure MIDItoCV.h
, on doit définir quelques valeurs nécessaires.
//#define HZV // enlevez le commentaire pour mode volt par hertz
//#define VOCT // enlevez le commentaire pour mode volt par octave
#define AMOUNTOUTPUTS 4 // nombre de sorties
#define CHANNEL 1 // canal MIDI utilisé
#define POLY 4 // le nombre maximal de voies/de polyphonie. plus de voix = moins de RAM libre.
Ok! on peut maintenant inclure MIDItoCV.h
! Voici le lien pour le téléchargement de mon code, publié sous license Creative Commons BY. Attention! MIDItoCV.h
n’est pas une librairie! Il doit être placé dans le dossier de votre sketch!
#include "MIDItoCV.h"
Dans votre setup, vous devez exécuter setupMIDItoCV()
, une fonction qui initialise des variables du code.
void setup()
{
setupMIDItoCV();
}
Enfin, vous pouvez ensuite placer MIDI.read()
dans votre loop pour lire les données MIDI entrantes
void loop()
{
MIDI.read();
}
Maintenant, les fonctions définissant le comportement de chaque sortie peuvent être utilisées.
Commençons par l’assignation d’un mode à une sortie. La fontion utilisée est setoutputaction(outputnumber, mode, parameter)
outputnumber
est le numéro de l’output, qui varie entre 1 etAMOUNTOUTPUTS
que vous avez défini plus tôtmode
peut être l’un des 8 modes;NONE
,NOTE
,VELOCITY
,GATE
,POLYAT
,CHANNELAT
,BEND
, ouCC
.parameter
est un paramètre additionnel utilisé uniquement pour les modes polyphoniques etCC
. Dans le cas des modes polyphoniques, (NOTE
,VELOCITY
,GATE
etPOLYAT
), le paramètre est le numéro de la voix. PourCC
, c’est simplement le numéro du contrôleur continu
Maintenant, voyons comment on peut utiliser les outputs. La fonction utilisée est un peu spéciale. Voici à quoi elle ressemble: setoutputfunction(outputnumber, outputfunction)
outputnumber
est le numéro de l’outputoutputfunction
est une fonction à laquelle la valeur de l’output est passé.
Si le dernier paramètre a porté à confusion, c’est essentiellement le nom d’une fonction qui prend comme variable une valeur et qui la transforme en voltage, par exemple avec analogWrite()
ou avec un DAC. En voici un exemple
int outputfunction1(int value) // voici la fonction qui reçoit les données de l'output et qui l'écrit avec analogWrite()
{
analogWrite(6, value); // notre sortie est la pin numéro 6
}
setoutputfunction(1, outputfunction1); // la fonction de sortie est la fonction d'écriture sur la pin numéro 3
Le programme a aussi besoin d’informations pour pouvoir bien calibrer la conversion en volts par octave ou herts par volts. Voici la fonction: setoutputrange(outputnumber, minvalue, maxvalue, minvoltage, maxvoltage)
outputnumber
est le numéro de l’outputminvalue
est la valeur minimum attendue par la fonction d’écriture de la sortiemaxvalue
est la valeur maximum attendue par la fonction d’écriture de la sortieminvoltage
est le voltage en millivolts que la fonction d’écriture produira lorsque sa valeur estminvalue
maxvoltage
est le voltage en millivolts que la fonction d’écriture produira lorsque sa valeur estmaxvalue
Un exemple!
int outputfunction1(int value) // Cette fonction reçoit les données de l'output 1 et l'écrit par PWM sur la pin 6
{
analogWrite(6, value); // la valeur est écrite sur la pin 6
}
setoutputfunction(1, outputfunction1); // on définit la fonction de sortie
setoutputrange(1, 0, 255, 0, 5000); // analogWrite prend des valeurs de 0 à 255 produit des voltages de 0V à 5V
Il est très probable que vous ayez plusieurs outputs ayant des mêmes caractéristiques de voltage et de valeur, et il serait plutôt frustrant d’avoir à le réécrire à chaque fois. C’est pourquoi la fonction setoutputrangeall(minvalue, maxvalue, minvoltage, maxvoltage)
existe. Les paramètres sont les mêmes qu’avec la dernière fonction sauf pour l’absence du paramètre outputnumber
car la fonction définit les valeurs pour tous les outputs.
Un guide sur l’utilisation avancée du code sera bientôt publié.
Écrit par Simon Demeule, 2015
Très intéressant ! , Merci ! ps: Avez vous publié votre « guide sur l’utilisation avancée du code » ?
J’aimeJ’aime
Hélas non! Et j’avoue que ça ne fait plus vraiment partie de mes plans; moi-même je ne connais plus ce code et je n’ai pas d’usage pour celui-ci. Je suis surpris d’en entendre parler aujourd’hui! L’avez-vous utilisé dans un projet? Je n’étais qu’à mon tout début en programmation lorsque j’ai écrit ce petit bout de code; à 16 ans! J’étudie maintenant en programmation et je suis conscient qu’un bon lot de coquilles peu efficaces s’y sont glissés.
J’aimeJ’aime