SetBfree Hammond Organ (5)

Een Hammond Organ voor iedereen!

Tekst en technische afbeeldingen: Marjan Waldorp
Artikel uit Turning Wheel 2024-3

Geluid is een relatief nieuw verschijnsel in de computerwereld. Bij computers als de PDP-11 (1970) speelde geluid geen enkele rol. De IBM-PC had een speaker, maar veel meer dan "beep" kon die niet zeggen. De behoefte aan beter geluid en geluidseffecten onstond met name vanuit de gaming industrie. Een van de eerste geluidskaarten voor de PC, de "AdLib" (1987), kon uitsluitend geluid synthetiseren. De Adlib werd weldra verdrongen door de "Sound Blaster" (1989), die zowel geluid kon synthetiseren (MIDI), als PCM naar analoog geluid omzetten (8-bit mono DAC). De 15-polige "game port" t.b.v. aansluiting van een joystick droeg belangrijk bij aan het succes! Aanvankelijk stuurde de toepassingssoftware de geluidskaart direct aan. Er waren geen "drivers" (zie deel 3). Daardoor was het niet zonder meer mogelijk om de architectuur van de geluidskaart te wijzigen. Een nieuw ontwerp moest "Sound Blaster compatible" zijn, anders liepen de toepassingsprogramma's niet!

De geluidskaart werd snel een standaardvoorziening op de PC en de voortschrijdende integratie bracht vervolgens de geluidskaart als chip op het moederbord (Intel standaarden: AC'97, HD-audio 2004). Deze trend heeft zich ook bij SBC's voortgezet. De Raspberry Pi 3, 4 en 5 wekken het geluid op via pulsbreedte modulatie registers (PWM-blocks). Dat levert een acceptabele geluidskwaliteit op, maar voor HiFi wordt geadviseerd een externe audio DAC te gebruiken, zoals een HiFiBerry DAC+ of een USB externe geluidskaart. De ODROID-N2+ heeft een 384kHz/32bit HiFi audio DAC onboard. Het stereo audiosignaal is beschikbaar via een 4-pol. (TRRS) 3,5mm connector, vergelijkbaar met de RPi 4. We kunnen echter geen RPi 4 aansluitkabel gebruiken! De ODROID N2+ heeft massa op de "sleeve", niet op "ring 2"! Als alternatief kan een 3-pol. (TRS) stereo 3,5mm audiokabel gebruikt worden. De video uitgang wordt dan weliswaar kortgesloten met massa, echter wanneer de HDMI uitgang gebruikt wordt, doet de composietvideo uitgang geen dienst.

SBC Tip Ring 1 Ring 2 Sleeve
ODROID N2+ Left Right Video GND
RPi 4 Left Right GND Video


OSS en ALSA geluidssystemen

Het Open Sound System (OSS) was het eerste geluidssysteem in Linux (1993). OSS omvat een collectie device drivers voor de verschillende geluidskaarten en hulpprogramma's (utilities), zoals configuratieprogramma's en een soundmixer. De toepassingsprogramma's spreken de geluidskaart aan via device files (zie deel 3). Bijv.: Test het default device door ruis te sturen:

 $ cat /dev/random >/dev/dsp

In 1998 begon Jaroslav Kysela de ontwikkeling van een nieuw geluidssysteem "Advanced Linux Sound Architecture" (ALSA). Aanleiding was de gebrekkige ondersteuning van de Gravis UltraSound synthesizer geluidskaart in OSS. Na onderzoek van de OSS API (Application Programming Interface), kwam Jaroslav tot de conclusie dat er een nieuw geluidssysteem moest komen om moderne geluidskaarten met bijv. multi-channel audio goed te kunnen ondersteunen. Geen geringe klus! Eind 1999 werd het ALSA professional team opgericht. April 2000 had dit team drie programmeurs, alle drie in dienst van SuSE Linux. In Linux 2.5 werd ALSA opgenomen in de kernel source en in Linux 2.6 (eind 2003) werd OSS definitief vervangen door ALSA, niet in de laatste plaats omdat OSS versie 4 niet langer Open Source was.

ALSA bestaat uit drie componenten:

  • sound drivers (kernel)
  • alsa-lib (software bibliotheek)
  • utilities

De nieuwe component hier is "alsa-lib", een software bibliotheek bovenop de device files. Bij ALSA communiceren de applicaties in principe met "alsa-lib", niet rechtstreeks met de device files. De "alsa-lib" softwarelaag biedt de applicaties een scala van plugins. De "dmix" plugin kan bijv. de pcm data van diverse applicaties samenvoegen tot één pcm stroom naar de geluidskaart. De "plug" plugin kan resamplen, bijv. van 44100kHz naar 48000kHz.


Geluid testen

ALSA komt met een aantal utilities, waaronder "aplay" dat audio bestanden kan afspelen. Maar "aplay" kan meer! Met de optie "-l" kunnen we een lijst opvragen van alle hardware audio devices. We zien twee geluidskaarten: card 0 en card 1. Card 0 is de onboard geluidschip. Card 1 is een externe geluidskaart (USB adapter). De onboard geluidschip heeft 3 devices. Helaas blijkt hier uit de omschrijving niet duidelijk welk device wat doet, maar device 0 is de digitale HDMI interface, device 1 is de 32-bit DAC en device 2 is een digitale S/PDIF (IEC958) interface. Card 1 heeft alleen een analoge DAC uitgang:

 $ aplay -l 
**** List of PLAYBACK Hardware Devices ****
card 0: ODROIDN2 [ODROID-N2], device 0: fe.dai-link-0 (*) []
   Subdevices: 1/1
   Subdevice #0: subdevice #0
card 0: ODROIDN2 [ODROID-N2], device 1: fe.dai-link-1 (*) []
   Subdevices: 1/1
   Subdevice #0: subdevice #0
card 0: ODROIDN2 [ODROID-N2], device 2: fe.dai-link-2 (*) []
   Subdevices: 1/1
   Subdevice #0: subdevice #0
card 1: Device [USB Audio Device], device 0: USB Audio [USB Audio]
   Subdevices: 1/1
   Subdevice #0: subdevice #0

N.B. De ALSA device files zijn van de groep "audio". Om toegang te krijgen tot de device files moet de gebruiker dus lid zijn van de groep "audio". Zo niet, dan meldt "aplay -l" dat er geen geluidskaarten gevonden worden:

 $ aplay -l 
aplay: device_list:274: no soundcards found...

Met "aplay -L" (hoofdletter L) kunnen we alle pcm's opvragen, die in de "alsa-lib" configuratie gedefinieerd zijn. We zien zo niet alleen de hardware pcm's, maar ook de virtuele pcm's via bijv. de "plug" en de "dmix" plugins. Hieronder de pcm's van de USB adapter:

 hw:CARD=Device,DEV=0 
   USB Audio Device, USB Audio
   Direct hardware device without any conversions
plughw:CARD=Device,DEV=0
   USB Audio Device, USB Audio
   Hardware device with all software conversions
..
dmix:CARD=Device,DEV=0
   USB Audio Device, USB Audio
   Direct sample mixing device

Met "speaker-test" kunnen we een device testen, bijv. card 1, device 0, twee kanalen wav test. We horen dan "Front Left", "Front Right" uit de speakers:

 $ speaker-test -c2 -t wav -D hw:1,0 

speaker-test 1.2.8

Playback device is hw:1,0
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
..


Audio DAC initialisatie

We weten nu hoe we audiohardware kunnen testen, echter als we de ODROID audio DAC testen, krijgen we een foutmelding en geen geluid! Op het Armbian forum bleek dit een bekend probleem. De onboard geluidschip wordt door de Linux sound driver (axg-sound-card) niet goed geïnitialiseerd. Moderne geluidschips zijn complexe ontwerpen o.a. omdat ze kunnen resamplen (zie deel 2). Ze zijn opgebouwd uit diverse onderdelen, die onderling met digitale bussen zijn verbonden. Twee veel gebruikte busprotocollen zijn I2C (/i-kwadraat-c/) en I2S, beide ontwikkeld door Philips (1982 resp. 1986). I2C is een seriële inter-IC control bus. I2C wordt onder meer gebruikt in PC's voor het uitlezen van temperatuur sensors en de Real Time Clock. I2S is een seriële stereo PCM bus.

Bovenstaand blokschema toont het hier relevante deel van de ODROIDN2 onboard geluidschip. Rechts in het schema worden de drie PCM's van "Device 0/1/2" gestuurd naar drie FIFO (First In, First Out) buffers "FRDDR A/B/C". Via de multiplexers "TDMOUT A/B/C" en "SPDIFOUT A/B" worden de digitale geluidsstromen naar de output hardware geleid. De koppelingen tussen de diverse componenten zijn uitgevoerd als een software gestuurd patch panel. Vanuit elk Device kan het digitale geluid in principe naar elke uitgang geleid worden. Default stuurt de Linux axg-sound-card driver de PCM data van "Device 0" via "TDMOUT_B" naar "HDMITX". De PCM data van "Device 1" wordt via "TDMOUT_A" naar de audio DAC gestuurd. Er lijkt echter een technisch probleem te zijn met "TDMOUT_A", waardoor de analoge uitgang niet functioneert. De "fix" is om de PCM data van "Device 1" via "TDMOUT_C" naar de DAC te sturen. Doorgaans moet je voor dit soort wijzigingen de broncode van de driver aanpassen, maar de Linux axg-sound-card driver stelt alle controls van het patch panel op gebruikersniveau ter beschikking. Best bijzonder! Met de "amixer" (ALSA mixer) utility kunnen we zelf de routering van de geluidsstromen wijzigen. Onderstaand script (ODAC-patch.scr) maakt de analoge audio werkend:

 #!/bin/bash 

# Fix ODROID-N2 3.5mm jack audio

# Device 1 (DAC)
# FRDDR_B output: TDMOUT_C
amixer -c 0 sset 'FRDDR_B SINK 1 SEL' 'OUT 2'
amixer -c 0 sset 'FRDDR_B SRC 1 EN' 'on'

# TDMOUT_C input: FRDDR_B
amixer -c 0 sset 'TDMOUT_C SRC SEL' 'IN 1'

# DAC input: TDMOUT_C
amixer -c 0 sset 'TOACODEC SRC' 'I2S C'
amixer -c 0 sset 'TOACODEC OUT EN' 'on'

# Set DAC master volume to 100%
amixer -c 0 sset 'ACODEC' '100%'

# Device 2 (SPDIF)
amixer -c 0 sset 'FRDDR_C SINK 1 SEL' 'OUT 3'
amixer -c 0 sset 'FRDDR_C SRC 1 EN' 'on'

# Store config in /var/lib/alsa/asound.state
alsactl store

We maken het script executable en voeren het met root rechten uit:

 $ chmod +x ODAC-patch.scr 

$ sudo ./ODAC-patch.scr

Simple mixer control 'FRDDR_B SINK 1 SEL',0
   Capabilities: enum
   Items: 'OUT 0' 'OUT 1' 'OUT 2' 'OUT 3' 'OUT 4' 'OUT 5' 'OUT 6' 'OUT 7'
   Item0: 'OUT 2'
..

Het patch script slaat als laatste de ALSA configuratie op in "/var/lib/alsa/asound.state". Als het systeem opnieuw opstart leest "alsactl restore" dit configuratiebestand en herstelt de status van vòòr het afsluiten. We hoeven dit patch script dus niet telkens opnieuw uit te voeren.


vi editor

Linux scripts, broncode bestanden van programma's en configuratiebestanden zijn ASCII gecodeerd. Tekstverwerkers als "Open Office" zijn totaal ongeschikt om dit soort bestanden te bewerken! Hiervoor hebben we een "platte tekst" editor nodig. De meest gebruikte editor in de Unix/linux wereld is "vi" (/vi:'ai/), de afkorting van "visual". Toen programmeur Bill Joy in 1976 "vi" schreef, waren beeldschermen net in opkomst en functietoetsen niet gangbaar. Bill Joy gebruikte daarom de "gewone" toetsen van het keyboard als functietoetsen. In "vi" worden bijna alle hoofd- en kleine letters, leestekens en haakjes, enz. als functietoetsen gebruikt. Vi heeft zodoende heel veel commando's, maar wie de belangrijkste 10 á 20 beheerst, kan zich goed redden. We starten "vi" met de bestandsnaam als argument:

 $ vi bestandsnaam

Uiteraard zijn de "gewone" toetsen ook nodig t.b.v. tekstinvoer. Vi is een "bi-modale" editor. Als we "vi" opstarten komen we in "command mode" en werken alle toetsen als functietoetsen. Typen we een "a" (append) of een "i" (insert), dan komen we in "input mode". We kunnen nu nieuwe tekst invoeren. Met de escape-toets (op vrijwel alle toetsenborden prominent links bovenaan) komen we terug in "command mode". Op het eerste gezicht lijkt deze werkwijze wat omslachtig, maar dit went snel. En wie "vi" in de vingers heeft, werkt efficiënt en snel, sneller dan met een muis! Vandaar dat na bijna 50 jaar het vi-concept nog steeds springlevend is! Vi is wel met zijn tijd meegegaan. Vi IMproved (vim) heeft alles: syntax highlighting, macro's, plugins, scripts, enz. Als "vim" niet standaard geïnstalleerd is, installeren we het pakket met "apt-get":

 $ sudo apt-get install vim

Vim heeft een ingebouwde help :help. 1 Voor de beginner heeft "vim" een oefenmodule: $ vimtutor.

Hieronder een minimale commandoset voor "vi/vim":

Commando   Beschrijving
h j k l   ← ↓ ↑ → (pijltjes werken ook)
^ $   Ga naar begin/einde van de regel
1G G   Ga naar regel 1 / naar einde bestand
a i   append/insert nieuwe tekst (Sluit af met <esc>)
o O   Open nieuwe regel onder/boven (Sluit af met <esc>)
x   Delete character
dd   Delete line
u .   undo/redo
:wq   write and quit
:q!   quit zonder opslaan

Commando's kunnen gemultipliceerd worden. Bijv. 5x wist 5 tekens. Met name belangrijk voor het bewerken van configuratiebestanden is de optie :set list (terug met :set nolist), die tabs (^I) en regeleindes ($) laat zien:

 laatste^Iregel $ 
$

In bovenstaand voorbeeld staat achter "laatste" een <tab> en de regel eindigt met een spatie! De "laatste regel" wordt gevolgd door een lege regel en is dus niet de laatste regel! Met name bij configuratiebestanden kunnen dit soort ogenschijnlijk onbelangrijke details het verschil maken tussen een falende en een werkende configuratie!


  1. Vim online help: https://vimhelp.org/
    Tuxu4 Support Wiki compacte vi reference: http://support.tux4u.be/dokuwiki/doku.php?id=linux:vi:vi-reference