Dankzij software-frameworks en bibliotheken die in de loop van de tijd steeds krachtiger zijn geworden, is het mogelijk om, zelfs in combinatie met een goedkope en compacte microcontroller, complexe functies te implementeren. In dit project gebruiken we een Arduino Uno R4 met de nodige randapparatuur om een veelzijdige praktische audiosynthesizer en MIDI-sequencer te bouwen. In dit eerste deel van een serie over audiosynthese beschrijven we het blokschema en de belangrijkste functies van de Basic Synth software.

Platform voor Audiosynthese

Sommige lezers herinneren zich misschien nog de oude SN76477, de beroemde complex soundgenerator van Texas Instruments. Ontwikkeld in de jaren zeventig maakte deze chip de creatie mogelijk van een grote verscheidenheid aan geluiden waaronder geweervuur, stoomlocomotieven, ruimtegeluiden en nog veel meer, maar ook compacte muzikale synthesizers.

Het was met name deze laatste functie die bijzonder aantrekkelijk was. Ik wilde al een tijdje een kleine geluidssynthesizer bouwen toen ik per ongeluk op de geweldige Mozzi-bibliotheek, van Tim Barras stuitte, waarmee je synthesizers en drummachines kunt implementeren op basis van een Arduino Uno R4 Minima en een handvol andere componenten.

Miniphonic audio synthesis platform
Miniphonic, het Arduino-gebaseerde audiosyntheseplatform

Maar niet alleen dat, onderweg vond ik ook de OscPocketO-software, van Staffan Melin, een bruikbare sequencer die op zijn beurt ook weer gebaseerd is op de Mozzi-bibliotheek. Uiteindelijk besloot ik om de SN76477 te verlaten ten gunste van deze oplossing en het MiniPhonic Audio Synthesis Platform was geboren, een hardwarematig audiosyntheseplatform meyt als belangrijkste kenmerken:

  • LCD-display met 20x4 karakters
  • 4 programmeerbare potentiometers voor het in real-time wijzigen van parameters
  • In- en Uitgangen voor synchronisatie met andere synthesizers
  • MIDI in- en uitgang
  • Monitor versterker voor hoofdtelefoons
  • 4-pole LP filter for the on-chip DAC
  • Behuizing voor de Arduino Uno R4


Het audiosyntheseplatform is gebouwd op twee printplaten: het moederboard en het displayboard, verbonden door een 14-pins platte kabel. Figuur 1 toont het blokschema van de synthesizer, wat handig is voor het begrijpen van de werking en het volgen van de audiostream. Deze laatste, in eerste instantie digitaal, wordt uiteindelijk omgezet in een analoog signaal door een 12-bits, on-chip DAC-converter die wordt gevolgd door een laagdoorlaatfilte LPF.

Block diagram: audio synthesis platform
Figuur 1: Blokschema van de Miniphonic synthesizer.

Aan de uitgang van het Low Pass Filter vinden we een ontkoppelweerstand, waardoor audio van andere synthesizers via de Insert connector kan worden toegevoerd. Deze connector maakt het mogelijk om een extern geluidseffect toe te voegen, zoals bijvoorbeeld nagalm. Effectprocessors hebben vaak een stereo-uitgang, en daarom zijn zowel de volumepotmeter als de monitorversterker in stereo uitgevoerd. Op de hoofdprint is het echter mogelijk om de insert te omzeilen en de hele audioketen in mono te configureren. Om dit te doen, hoeft u alleen maar SJ3- en SJ4-pads op de printplaat te verbinden met een druppel soldeertin (verdere beschrijving volgt in de volgende aflevering).

De lijnuitgangen OUT L en OUT R zijn ook aangesloten op de monitorversterker. De twee belangrijkste toepassingen van het platform zijn:

  • Basic Synth: een eenvoudige monofone synthesizer waarbij de MIDI-ingang gebruikt wordt om een standaard keyboard aan te sluiten om in real-time te kunnen spelen.
  • Sequence: ontworpen als standalone sequencer met de mogelijkheid om andere synthesizers aan te sturen via de SYNC- of MIDI OUT-aansluiting.


Deze applicaties kunnen worden gedownload van de Elektor Labs-pagina voor dit project. Laten we om te beginnen de Basic Synth in detail bekijken.

Basic Synth

Het blokschema van de Basic Synth applicatie, zoals te zien is in Figuur 2, heeft de klassieke structuur van een synthesizer en is gebaseerd op een softwarestructuur genaamd Synthesizer Chain (zie ook het tekstkader), die in de code te vinden is vanaf regel 920.

Basic Synth application - Audio Synthesis Platform
Figuur 2: Blokschema van de Basic Synth.

In meer detail, vermenigvuldigt de functie gMOscillator.next() * Lv1 >> 4 de samples die worden gegenereerd door oscillator DCO1 gMOscillator.next() met de waarde Lv1, en schaalt deze vervolgens met de >> 4 operator. Deze bewerking simuleert de werking van een volumepotentiometer waarbij het signaal wordt bepaald door gMOscillator.next() en Lv1 de stand van de potentiometer voorstelt. Dezelfde bewerking wordt uitgevoerd voor de tweede oscillator, DCO2.

Synth text chain - audio synthesis article
De Synthesizerketen

Het volgende blok in het schema is de mixer (MIX), die wordt gevormd door een eenvoudige optelling die de samples van de twee oscillators optelt. Het DCA (Digital Controlled Amplifier) blok vermenigvuldigt de som van de twee oscillators met variabele gMGain, die dynamisch wordt bijgewerkt door​​​​​​​ gMEnvelope.next(). Samen vormt dat een ADSR (Attack, Decay. Sustain, Release) omhullende-generator.

Merk op dat de​​​​​​​ .next memberfuncties steeds de (volgende) numerieke waarden van de audio- of besturingsstreams vertegenwoordigen. In het blokschema valt misschien de ongebruikelijke positie van de DCF op die de DCA volgt in plaats van ervóór te staan; dit komt door het numerieke formaat van de audiostream dat beter past bij de DCF die oorspronkelijk is ontworpen om op de Arduino Uno R3 te werken. (Idealiter zouden deze bibliotheken herschreven worden met een formaat dat optimaal is voor de Arduino Uno R4 om optimaal te profiteren van de functies van de Arm Cortex4 RA4M1-processor, die een speciale DSP-instructieset heeft.)

In het blokschema zien we verder dat de MIDI-ingang niet alleen aan DCO1 en DCO2 is gekoppeld — om noot-codes te verzenden en de oscillatorfrequentie te bepalen op basis van het MIDI-noot-nummer — maar ook op de ADSR omhullendegenerator. Die laatste gebruikt d​​​​​​​e On en Note Off codes om het begin en einde van een omhullende te bepalen bij het starten of eindigen van een noot. Noot-codes kunnen ook door de DCF worden gebruikt om diens cutoff frequentie te wijzigen door manual KBD tracking in te schakelen. Op deze manier fungeert de DCF als een volgfilter. MG in het blokschema staat voor Modulation Generator.

Inschrijven
Schrijf u in voor tag alert e-mails over Arduino!

User Interface

Laten we nu eens kijken hoe de gebruikersinterface eruitziet voor deze toepassing van het platform. Het display is verdeeld in twee delen: de bovenste twee regels tonen de actuele labels die horen bij de vier potentiometers die het huidige panel gebruikt.

Er zijn vier bedieningspanelen — panels genaamd — beschikbaar (PANEL_MAIN, PANEL_ADSR, PANEL_MIXER en PANEL_FILTER), allemaal toegankelijk via het menu Tools, dat later nog in detail zal worden beschreven. De menu's zijn te kiezen via de MNU+- en MNU- knoppen, terwijl de LEFT- en RGHT- knoppen een submenu selecteren. Met VAL+ en VAL- worden steeds de waarden van parameters gewijzigd.

Laten we eens kijken naar de items van het hoofdmenu:

WAVEFORM: dit menu maakt het mogelijk om met behulp van VAL+ en VAL- te kiezen uit vijf golfvormen voor de DCO1 oscillator: Sinus, Driehoek, Zaagtand, Blok en een atypische vorm genaamd Phasor.

FILTER mode: met​​​​​​​ VAL+ and VAL- kunnen we hier de werkingsmodus van het filter wijzigen. We kunnen kiezen tussen Manual KBD Tracking waarin de​​​​​​​ gMFilterCutoff frequentie van het DCF wordt verschoven door het MIDI-nootnummer, Random MG1 waarbij de frequentie willekeurig wordt verschoven met een snelheid die wordt bepaald door MG1, Mod MG1 waarin een driehoekige modulatie wordt toegepast met een snelheid die wordt bepaald door MG1 en tot slot Fast, gelijk aan de vorige, maar met een vaste snelheid.

WAVEFORM2: dezelfde functie als WAVEFORM, maar nu voor de tweede oscillator DCO2.​​​​​​​

DETUNE 2: fijnafstelling van de DCO2-oscillator (VAL+ / VAL-). Een getal tussen 1 en 2 laat de frequentie van DCO2 iets afwijken wat een chorus-effect creëert in combinatie met DCO1.

TRANSPOSE 2: Transpositie van DCO2, opnieuw in te stellen me​​​​​​​t VAL+ and VAL-.

TOOLS: Vanuit dit menu kun je kiezen tussen de submenu's Save, d.w.z. opslaan van de volledige Synth-instelling, Load, d.w.z. laden van de instellingen en Panel waarin de Panels gekozen kunnen worden. De submenu's worden steeds gekozen met LEFT and RGHT buttons.

In PANEL_MAIN vinden we:

 

  • FREQ ATTACK
  • RESO RELEAS

 

waarin​​​​​​​ FREQ en RESO respectievelijk de afsnijfrequentie en resonantie van het filter voorstellen en​​​​​​​ ATTACK en RELEAS horen bij de ADSR omhullendegenerator en de attack- en releasetijd definiëren. In PANEL_ADSR, zien we alle vier de parameters van de ADSR. In het bijzonder de SUST_LEV en DECAY parameters stellen ons in staat om percussiegeluiden te creëren:

 

  • ATTACK DECAY
  • SUST_LEV REL

 

Vanuit PANEL_MIXER kunnen we de niveaus van beide oscillators en de frequentie van modulatiegenerator MG1 instellen via FRM1:

 

LEVL_1 FRM1

LEVL_2 ----

 

Het is ook mogelijk om het aantal panelen te vergroten door de​​​​​​​ DrawPanel() functie in de code te gebruiken

De Basic Synth Firmware

In setup (regel 806 en verder) vinden we alle basisinstellingen van het instrument en de nodige initialisaties. Eerst wordt het display ingesteld met​​​​​​​ gUILCD.begin(20, 4). Daarna vinden we de credits, het versienummer van de software en de MIDI-initialisatie, voorafgegaan door koppelingen met de MIDI-bibliotheek voor​​​​​​​ HandleNoteOn en HandleNoteOff en de initialisatie van de MIDI bibliotheek in​​​​​​​ MIDI_CHANNEL_OMNI mode waarin de MIDI kanalen 1 tot 16 worden ontvangen:

 

// 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);

 

De HandleNoteOn functie wordt geactiveerd door een keyboard dat verbonden is met de MIDI IN aansluiting, en start een noot na ontvangst van een​​​​​​​ NoteOn bericht; de noot blijft actief tot een​​​​​​​ NoteOff wordt ontvangen of gMSustainTime afloopt, via de​​​​​​​ HandleNoteOff functie.

Inschrijven
Schrijf u in voor tag alert e-mails over Synthesizer!

Vanaf regel 834 volgen de instellingen van de Mozzi bibliotheek, zodat de synthesizer kan beginnen met spelen. De gebruikersinterface (User Interface Draw) wordt gestart rond regel 868 en direct daarna wordt de Mozzi bibliotheek gestart:

 

UIDraw();

startMozzi(CONTROL_RATE)

 

In de updateControl() functie wordt inkomende midi afgehandeld doo​​​​​​​ MIDI.read(), de omhullende bijgewerkt met​​​​​​​ gMEnvelope.update(), en worden eventuele toetsdrukken afgehandeld door UIHandle().

Vervolgens wordt STEP RANDOM GENERATOR of MG1 uitgevoerd, verantwoordelijk voor het genereren van een willekeurige serie data, respectievelijk driehoek signaal, resulterend in waarden voor​​​​​​​ RndAcc en MG1acc, respectively.

Beide waarden worden later gebruikt om het filter te moduleren. De frequentie wordt bepaald door de modulatiegenerator MG1, waarvan de waarde wordt geregeld door de potentiometer FRM1, die in het derde paneel van het menu zit. Het is belangrijk te weten dat deze frequentie evenredig is met​​​​​​​ CONTROL_RATE, die al geïntroduceerd is in de StartMozzi functie.

Er is ook een tweede modulatiegenerator, MG2, die kan worden gekoppeld met de eerste voor verdere modulatiemogelijkheden. Ten slotte wordt de audiostream bijgewerkt via de updateAudio() functie. Dit is de belangrijkste functie omdat hij de verwerking van de audiostream voor zijn rekening neemt, d.w.z. de Synthesizerketen die we eerder zagen. De functie completeert de hoofdlus af die ook audioHook(), de aanroep naar de Mozzi-bibliotheek, bevat.


Audiosynthese in het Kort

Geluid wordt in de eerste plaats gekenmerkt door de frequentie — het aantal perioden per seconde — en deze wordt gemeten in Hertz (Hz). 100 Hz betekent bijvoorbeeld dat er 100 perioden per seconde zijn, zie Figuur A; In het geval van een snaar betekent dit dat deze 100 keer per seconde zal trillen.

Synth figA - Audio Synthesis Platform
Figuur A

Als de frequentie 440 Hz is spelen we een natuurlijke A, als de frequentie daalt naar 220 Hz, dan spelen we nog steeds een A, maar dan een octaaf lager. 880 Hz komt ook overeen met een A, maar dan een octaaf hoger. Vervolgens wordt de klank van het geluid gekenmerkt door timbre, dat wil zeggen de hoeveelheid en sterkte van aanwezige harmonischen waardoor we bijvoorbeeld het geluid van een jazzgitaar — die relatief weinig harmonischen heeft — kunnen onderscheiden van een sterk vervormd geluid dat er heel veel heeft.

Als een geluid geen harmonischen heeft is het een pure sinusgolf en spreken we van een zuivere toon, te zien in figuur A; als het geluid daarentegen harmonischen heeft, is de golfvorm complexer. Harmonischen zijn niets anders dan tonen die over de oorspronkelijke toon — fundamenteel genoemd, en bepalend voor de frequentie van het geluid — heen worden gelegd (erbij opgeteld). Deze harmonische tonen kunnen de dubbele, drievoudige enzovoort frequentie hebben en worden respectievelijk tweede harmonische, derde harmonische enzovoort genoemd. Een blokgolf wordt bijvoorbeeld gevormd door de fundamentele eerste harmonische met daarop gesuperponeerd de 3e, 5e, 7e (enzovoorts) harmonische, met een steeds afnemende amplitude

Synth FigB - Audio Synthesis Platform
Figuur B

Een blokgolf heeft een nogal hard timbre. Als we in plaats van de oneven, de even harmonischen superponeren wordt de golfvorm asymmetrisch zoals bij een zaagtand (ramp), die een veel minder onaangenaam timbre heeft. Synthesizer-oscillators kunnen meestal de basisgolfvormen zoals​​​​​​​ SINUSOIDAL, RAMP, SQUARE en TRIANGULAR genereren (Figuur B); er zijn echter ook oscillators die in staat zijn om veel complexere golfvormen te produceren, of zelfs golfvormen die zijn gesampled van echte instrumenten; deze worden WaveTable Oscillators genoemd en dat type wordt gebruikt in onze synthesizer.

Synth figC - Audio Synthesis Platform
Figuur C

Het is ook mogelijk om twee oscillators samen te voegen, waarvan de tweede wordt getransponeerd met een vijfde interval (7 halve tonen) of een octaaf (12 halve tonen) waardoor bijzonder rijke klanken kunnen worden verkregen. Een ander belangrijk onderdeel is de DCF die te zien is in Figuur C, dat is een digitaal gestuurd (Digital Controlled) filter dat de harmonische inhoud van de toon dynamisch kan variëren.

Synth figD - Audio Synthesis Platform
Figuur D

Meestal betreft het hier een laagdoorlaatfilter met resonantie, d.w.z. een filter dat alleen frequenties onder de afsnijfrequentie die naar wens is in te stellen doorlaat (Figuur D), en daarnaast nog kan worden aangepast door, bijvoorbeeld, een AR (Attack Release) omhullendegenerator of een MG (Modulation Generator) zoals het geval is bij onze synth.

De RESONANCE parameter daarentegen creëert in het filter een resonantiepiek (Figuur E) die in amplitude kan worden aangepast met een van de potentiometers en die ook weer in frequentie kan worden verschoven afhankelijk van de CUTOFF FREQUENCY.

Synth figE
Figuur E

Een andere belangrijke parameter van het geluid is de amplitude, dat wil zeggen hoe sterk de oscillatie is (de amplitude wordt bijvoorbeeld gevarieerd door het volume te verhogen of te verlagen) en vooral hoe deze amplitude in de loop van de tijd varieert; een fluit produceert bijvoorbeeld een geluid dat niet onmiddellijk zijn maximum bereikt, maar pas na verloop van tijd en volgens een toenemende helling; deze tijd heet de ATTACK tijd.

Synth figF
Figure F

Bij snaarinstrumenten daarentegen blijft de toon nadat de snaar is getokkeld lang naklinken, maar met een steeds verder afnemende amplitude. De tijd waarin het geluid wegsterft wordt de RELEASE tijd genoemd. De​​​​​​​ ENVELOPE GENERATOR (omhullendegenerator) zorgt er samen met de Amplitude Modulator (in ons geval de DCA of Digital Controlled Amplifier – digitaal gestuurde versterker, Figuur F) voor dat de amplitude van het geluid wordt gevarieerd door de ATTACK en RELEASE parameters, Figuur G).

Synth figG
Figuur G

De ATTACK parameter, in rood zichtbaar in Figuur H, beïnvloedt de amplitude van de audio stream van nul naar maximum in een tijd die korter of langer kan zijn afhankelijk van de stand van de bijbehorende potentiometer.

Synth figH
Figuur H

Voor een beter klinkend geluid is het handig om een meer geavanceerde omhullendegenerator te gebruiken, genaamd ADSR, zoals degene die is geïmplementeerd in onze synth, met nog twee extra parameters ten opzichte van de AR generator, namelijk de DECADE of DECAY tijd en d​​​​​​​e SUSTAIN of SUSTAIN LEVEL, Figuur I.

Synth figI
Figuur I

Deze omhullendegenerator stelt ons in staat om het geluid van een getokkelde snaar, zoals bij een klavecimbel of gitaar, zeer goed na te bootsen. We kunnen dit doen door het ADSR-paneel te selecteren en ATTACK op minimaal in te stellen, SUST_LEV op een derde en DECAY op ongeveer de helft; we krijgen dan een zeer goed percussiegeluid, vergelijkbaar met een getokkelde snaar, vooral in combinatie met een zaagtandgolf.


Binnenkort Beschikbaar

In het tweede deel van deze artikelreeks over audiosynthese zullen we de Sequence-functie en bijbehorende firmware beschrijven, de schema's van de hoofd- en displayprint verder behandelen — inclusief beide onderdelenlijsten — en geven we tips en adviezen voor de praktische uitvoering van het project. Blijf op de hoogte!

Inschrijven
Schrijf u in voor tag alert e-mails over Audio!


Noot van de redactie: dit audiosyntheseplatform project verscheen oorspronkelijk in​​​​​​​ Elettronica IN

elektor