MiniPhonic: een Arduino-gestuurd Audiosynthese Platform (2)
op
Dankzij softwareframeworks en bibliotheken die in de loop der tijd behoorlijk power hebben gekregen, kun je zelfs met een compact en goedkoop systeem complexe functies realiseren. In het eerste deel van de MiniPhonic-artikelenreeks hebben we het blokschema en de belangrijkste functies van de Basic Synth-software beschreven. Hier sluiten we af met de beschrijving van de Sequence-applicatie en firmware, waarbij we kijken naar de hardware van het moederbord en het displaybord, inclusief montage-instructies en een lijst met onderdelen. Aan de slag!
Sequence(r)!
Deze app is ook gebaseerd op Tim Barras' Mozzi-bibliotheek en gebruikt een aangepaste versie van Staffan Melins OscPocketO-software, waarmee je sommige instellingen in realtime kunt aanpassen. Het blokschema van de Sequence-app zie je in Figuur 1. De belangrijkste functies zijn:
- 16-noten sequencer met 4 patronen, die je kunt uitbreiden als je wilt, ook met output op MIDI OUT.
- Sequenties worden weergegeven in alfanumerieke muzieknotatie (bijv. C, C#, D…).
- Twee wavetable (golfvorm) oscillatoren DCO1 en DCO2 met vijf golfvormen die kunnen worden vervangen.
- Tweede oscillator met Detune en Transpose.
- Envelope-generator met vier parameters, ATTACK, DECAY, SUSTAIN LEVEL en RELEASE, die in RT via potmeters kunnen worden geregeld.
- LP-filter met instelbare frequentie en resonantie.
- Filtermodulatiegenerator met instelbare Slow-, Fast- en Random-parameters.
- 4 oproepbare panelen, indien nodig uitbreidbaar.
- Mogelijkheid om een extern toetsenbord via MIDI IN te gebruiken om in realtime te spelen.
De belangrijkste module van deze app is de SEQUENCER. Hiermee kun je reeksen noten maken die cyclisch worden herhaald, opgeslagen op 4 patronen van elk 16 noten, die zich in EEPROM bevinden en dus quasi-permanent bewaard blijven.
Voor elke noot kun je de toonhoogte aanpassen, dus het MIDI-nootnummer en de status ervan: STATE_OFF dempt de noot, waardoor er een pauze ontstaat, STATE_ON speelt de noot op normaal volume, STATE_BOLD speelt de noot met een accent.
Je kunt ook het hele patroon omhoog of omlaag "transponeren" om het aan te passen aan de gewenste toonsoort, zonder dat je alle noten hoeft te veranderen. De sequencer heeft ook een SYNC-ingang/uitgang, waardoor je een of meer synthesizers parallel kunt aansluiten.
De sequencer regelt de twee oscillatoren DCO1 en DCO2, die ook gegevens van de MIDI-poort accepteren, zodat je in realtime kunt spelen, ongeacht de sequencer. Met de MNU+ en MNU- knoppen ga je naar de menu's.
In detail:
SEQUENCE: met de knoppen VAL+ en VAL- start of stop je de sequencer.
SYNC: activeert de synchronisatie, die van binnenuit of van buitenaf kan komen, via de juiste aansluiting. EXT24 wordt gebruikt om de sequencer te synchroniseren op 24 ppq (pulsen per kwartnoot; max. 140 bpm).
PATTERN: met VAL+ en VAL- kun je kiezen uit de vier beschikbare patronen.
ED pat: hiermee kun je het patroon bewerken; gebruik de knoppen LEFT en RGHT om over noten te gaan, druk op VAL+ en VAL- om de noot te wijzigen die in alfanumerieke notatie wordt weergegeven, d.w.z. op de derde regel van het display worden de noten weergegeven volgens de internationale standaard: C, C' (Cis), D, D' (Dis), E, F, F' (F-kruis), G, G' (G-kruis), A, A' (A-kruis), B. Het getal eronder geeft aan in welk octaaf de noot klinkt.
STATE: status van elke noot; ook hier kunnen we met de knoppen LEFT en RGHT naar de noten gaan en met VAL+ en VAL- de status van de noot veranderen
- = gedempt
O = noot normaal gespeeld
B = geaccentueerde noot
TEMPO: metronoom uitgedrukt in bpm.
GATE: nootlengte uitgedrukt in procenten; een waarde van 30 zorgt er bijvoorbeeld voor dat de noot 30% klinkt, gevolgd door een pauze van 70%.
SH pat: verplaatst het hele patroon omhoog of omlaag door VAL+ en VAL- met telkens een halve toon in te drukken.
WAVEFORM: hiermee kun je met VAL+ en VAL- kiezen uit vijf golfvormen voor DCO1: Sin = sinus, Tr = driehoek, Saw = zaagtand, Square en een atypische golfvorm genaamd Phasor.
FILTER-mode: met VAL+ en VAL- kun je de filtermodi veranderen: Fixed, waarbij de afsnijfrequentie van de DCF gMFilterCutoff wordt aangepast met een potentiometer, Random, waarbij de frequentie willekeurig wordt verschoven met een snelheid die wordt ingesteld met MG1, Man.Mod, waarbij een driehoek- modulatie wordt toegepast met een snelheid die altijd wordt ingesteld met MG1, en ten slotte Fast, zoals de vorige maar met een vaste snelheid. MG1 is te bereiken via de paneelmixer ingang FRM1.
WAVEFORM2: Hiermee kun je via VAL+ en VAL- kiezen uit vijf golfvormen voor DCO2: Sine, Triangular, Saw, Square en de atypische Phasor.
DETUNE2: Hiermee kun je via VAL+ en VAL- de frequentie van DCO2 een beetje verstemmen: een waarde van 2 zorgt voor een uitgesproken chorus-effect.
TRANSPOSE2: VAL+ en VAL- transponeren DCO2 ten opzichte van het MIDI-nootnummer.
KEY PLAY: speelt meteen de eerste 4 noten van het huidige patroon af door op de vier knoppen LEFT, VAL-, VAL+ en RGHT te drukken. Het bijbehorende MIDI-nootnummer staat boven elke knop. Handig om geluiden te oefenen of in realtime te spelen, vooral als er geen keyboard is aangesloten.
TOOLS: S slaat de huidige configuratie inclusief patronen op in het niet-vluchtige geheugen, L laadt eerder opgeslagen configuraties en patronen, R maakt een willekeurige reeks in het huidige patroon, B maakt een monodische baslijn (zelfde noot) maar met alle noten in O-status, zodat je deze gemakkelijk kunt wijzigen.
Ook hier kun je met de P-functie kiezen uit 3 panelen: main, adsr en mixer.
De Sequence-firmware
In de setup (rond regel 1520) staan alle instellingen voor de instrumenten en de dingen die je eerst moet doen. We configureren de pinnen en starten het display met het commando:
gUILCD.begin(20, 4)
Vervolgens worden er een paar aangepaste tekens gemaakt die niet in de standaard LCD-set zitten, maar wel handig zijn om de patroonreeksen weer te geven:
gUILCD.createChar(0, Dodiesis);
gUILCD.createChar(1, Rediesis);
gUILCD.createChar(2, Fadiesis);
gUILCD.createChar(3, Soldiesis);
gUILCD.createChar(4, Ladiesis);
Vervolgens vind je de credits en versienummers van de software en de MIDI-initialisatie, voorafgegaan door verbindingen met de MIDI-bibliotheek van: HandleNoteOn and NoteOff:
// 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);
Je ziet vast dat er meerdere NOTE ON-functies zijn. De belangrijkste is playNote(), rond regel 420, en die wordt gebruikt door de sequencer. De functie playNoteOn() is speciaal voor de KEY PLAY-modus, waarmee je de eerste vier noten van het huidige patroon kunt spelen met de toetsen LEFT, VAL-, VAL+ en RGHT.
Tenslotte wordt de functie HandleNoteOn() gebruikt om invoer van het toetsenbord dat is aangesloten op de MIDI IN-poort te verwerken.
Natuurlijk zijn er ook twee wederzijdse functies die de afgespeelde noot beëindigen, respectievelijk playNoteOff en HandleNoteOff. In 1570 vinden we de declaraties en de koppeling van deze functies met de MIDI-bibliotheek.
Vanaf ongeveer regel 1580 volgen alle instellingen van de Mozzi-bibliotheek, zodat de synthesizer meteen kan beginnen met spelen; op dezelfde manier volgen (rond regel 1610) de instellingen voor de sequencer.
De gebruikersinterface (User Interface Draw) wordt rond regel 1630 gestart met de functie UIDraw(), en meteen daarna wordt de Mozzi-bibliotheek startMozzi(CONTROL_RATE) gestart.
Tijd om naar de functie updateControl() te gaan op regel 1640, waar alle bedieningselementen zijn geïmplementeerd, en meteen daarna vinden we de MIDI-poortquery voor het geval er een toetsenbord is aangesloten.
if(MIDI.read()){
gMEnvelope.noteOn(); // play from MIDI input
PanelHandle(); // handle panel
}
Met de functie PanelHandle() kun je de instellingen van de vier potmeters aanpassen, net zoals bij de Basic Synth. Daarna komt de sequencer-engine (rond 1648), waar eerst de synchronisatie wordt geregeld en daarna wordt gekeken of de huidige zestiende noot voorbij is voordat de volgende noot begint.
if (gSyncNoteOn) {
playNote();
gSyncNoteOn = false;
Ook hier zie je de functie PanelHandle(), zodat we elke keer dat een noot wordt gespeeld de parameters kunnen aanpassen, waarna de volgende noot wordt verwerkt, totdat het maximale aantal noten is bereikt. Dan gaan we weer terug naar de eerste noot.
PanelHandle(); // --- Sequence/Mozzi
gSeqNoteIndex++;
if (gSeqNoteIndex >= MAX_NOTES) {
gSeqNoteIndex = 0;
}
}
De nootduur wordt dan gecontroleerd en de Off-noot en sync out worden opgeroepen voor eventuele externe apparaten, en de envelope (omhullende) wordt bijgewerkt met gMEnvelope.update().
Op dit punt wordt de gebruikersinterface opgeroepen om te kijken of er toetsen zijn ingedrukt met gMEnvelope.update().
Tenslotte volgt de audio-update updateAudio(). Dit is de belangrijkste functie, omdat deze de verwerking van de audiostream omvat, zoals we al hebben gezien bij de Basic Synth. In feite stelt deze switch:
switch(gSeqStatus[gSeqPatternIndex][NIdx])
het gMGain-niveau in, oftewel het volume van de gespeelde noot, dat vervolgens wordt gebruikt door SYNTHESIZER CHAIN 2 (te zien in het betreffende kader in dit artikel). De lus met de belangrijkste aanroep van de Mozzi audioHook()-bibliotheek sluit het programma af.
Praktische realisatie
Gebruik de componentopstellingen van de printen als referentie en start met de SMD-onderdelen aan de soldeerzijde, en wel de passieve elementen. Daarna ga je verder met de "draadjes"-componenten aan de andere kant.
Het is handig om de MiniPhonic in een behuizing te steken, zoals je in de introafbeelding van dit artikel en in figuur 2 kunt zien. Daarin zie je hoe het moederbord (zie het schema in figuur 3) en het displaybord (figuur 4) zijn geplaatst en met een stukje flatcable zijn verbonden.
IC3 is een TDA2822D-audioversterker van STMicroelectronics, waarvan de output naar zowel de 6,3 mm L- en R-mono-uitgangen als naar de 3,5 mm stereo-uitgang voor hoofdtelefoons aan de achterkant van de behuizing van de MiniPhonic gaat.
De potmeters en knoppen die je gebruikt, zijn makkelijk te vinden. De eerste potmeter linksboven op de foto van het hoofdbord (zie het tekstvak Componentlijst hoofdbord) hoef je niet te monteren.
Let goed op de SYNC-connector en vooral op de AUDIOBUS-aansluiting, die groen is gemarkeerd in het bedradingsschema van figuur 5. Als je meerdere synthesizers parallel aansluit, moeten alle audiokanalen ook parallel worden aangesloten. Maar let op: de totale output wordt 6 dB lager door de belasting van de andere aangesloten synthesizers.
Als je liever een mixer gebruikt (aanbevolen), kun je het beste de AUDIOBUS loskoppelen van de aansluiting, eventueel met een schakelaar, zodat elke synthesizer zijn eigen kanaal heeft. Dezelfde SYNC-aansluiting zorgt ook voor stroom via de DC IN-aansluiting, waardoor je maar één voeding (wandtransformator) nodig hebt voor alle synthesizers. Houd er rekening mee dat elke synthesizer ongeveer 200 mA verbruikt.
Figuur 6 laat de naam van het huidige paneel zien – in dit geval mixer – met daarachter drie parameters: LEVL_1, LEVL_2 en FRM1, en een lege ruimte. Deze parameters zijn toegewezen aan de potentiometers P1, P2 en P3, terwijl P4 in dit paneel niet wordt gebruikt. De parameters LEVL_1 en LEVL_2 regelen het niveau van de twee oscillatoren, terwijl FRM1 de frequentie van MG1 regelt. Dit paneel maakt deel uit van de Basic Synth.
Figuur 7 toont het Main paneel met het ED PAT-menu. De derde regel toont de volgorde van de noten, terwijl de vierde regel de bijbehorende octaven laat zien. De eerste noot is een C in octaaf 0, gevolgd door een C# (C-kruis) in hetzelfde octaaf, dan een D, ook in octaaf 0, enzovoort. De reeks eindigt met een D# in octaaf 1.
Het MiniPhonic-platform: slotoverwegingen
Het MiniPhonic-platform is niet alleen handig om kleine synthesizers te maken en de basis van geluidssynthese en het MIDI-protocol te leren, maar ook om verder mee te werken. De SYNC-connector is bijvoorbeeld zo ontworpen dat hij SDI-, SDO-, SCK- en SS-signalen extern kan overbrengen, waardoor een SPI-datastroom mogelijk is. Deze stroom kan worden gebruikt als drager voor meerkanaals audio en bijbehorende besturingssignalen, die kunnen worden gebruikt om externe componenten zoals analoge VCF's, VCA's en andere apparaten te implementeren.
Dankzij de kracht van de ARM-processor kan de Basic Synth worden uitgebreid tot een polyfoon apparaat, bijvoorbeeld met 3 stemmen, met behoud van de huidige structuur. Bovendien kunnen de hierboven beschreven toepassingen verder worden herwerkt en verbeterd, met als doel het volledige potentieel van de ARM-processor te benutten.
Hier moet het filter, dat eigenlijk voor de Arduino UNO R3 is gemaakt, even worden genoemd, want dat is het zwakke punt. Als RESONANCE helemaal open staat, wordt het filter onstabiel en gaat het oscilleren, wat voor flinke vervorming zorgt. Naar onze mening zou dit onderdeel als eerste opnieuw ontworpen moeten worden. Toch verdient de ontwerper van de huidige versie alle lof, want hij is erin geslaagd het systeem op een Arduino UNO R3 te laten draaien, een knappe prestatie!
Het complete softwarepakket voor het MiniPhonic-project kun je downloaden op de Elektor Labs-pagina.
Vragen over het Miniphonic Project?
Heb je vragen of opbouwend commentaar over het MiniPhonic project of dit artikel, neem dan contact op met het Elektor-redactieteam via editor@elektor.com.
Opmerking van de redactie: Het MiniPhonic-platform voor audiosynthese verscheen oorspronkelijk in Elettronica IN.
![]()

Discussie (0 opmerking(en))