Linux a zvuk

Radek Pospisil

Obsah

29.brezna 1995

V dnesni dobe multimedii se snad v kazdem znamejsim operacnimu systemu objevily zvukove aplikace jak pro zabavu ( hry ) tak pro praci ( sequencery ). Pokusim se popsat jak se s timto vyporadali autori Linuxu.


Linux & CDROM

Kdyz si dnes kupujeme CDROM dostaneme k nemu i nejake drivery, ktere jsou urceny pro MSDOS, OS/2 nebo nejaky jiny OS ale urcite zatim vyrobci nedistribuji drivery pro Linux ( a to asi z toho duvodu, ze by museli dat siroke programatorske verejnosti zdrojove texty driveru ). To znamena, ze si musime poridit taky CDROM, ktery je v soucasnosti podporovan - pokud jej budeme chtit pouzivat v Linuxu.

Podporovane typy CDROM

SCSI - zde nemam, co bych dodal ( nemam s tim zadne zkusenosti, ale ze znamosti samotneho rozhrani by nemel byt zadny problem ). Pri 'make config' si vyberme 'SCSI support' a pak 'SCSI CDROM support' - alespon doufam :-)

ATAPI/IDE rozhrani - to jsou ty, ktere se pripojuji na IDE rozhrani jako druhy HD - asi od verze jadra 1.1.80 (?), kde se prepracovaly ovladace disku. Dnes Linux podporuje pripojeni az 4 IDE zarizeni ( napr 1xHD 3xCDROM ) - pokud mame odpovidajici IDE kartu ( nejsou drahe, ale jsou VL-busove ). I kdyz maji CDROM jednotne rozhrani nemusi se ovladac v jadre s timto diskem dohodnout ( mam vlastni zkusenost s typem Aztech 268-03I, ale mala oprava ovladace tomu pomohla ). V posledni dobe jsou dost popularni, protoze umoznuji dost vysoke datove prenosy ( no podivejme se, kolik toho prenasi HD ). Pri 'make config' vybereme 'new IDE driver...' a pak 'Include support for IDE/ATAPI CDROM'.

CDROM s vlastnim rozhranim - starsi typy CDROMu jako Mitsumi, SONY, Panasonic, CreativeLab, Aztech 268-01,... . Tyto typy maji svuj radic a kazdy typ ma svuj vlastni. pri 'make config' si vyberte z 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)' sekce to, co mate. Nektere typy lze pripojit i pres zvukovou kartu. Zatim je podporovano pripojeni pres SB pro MultiCD a SB16 MultiCD, ... . Asi bude nejlepsi, kdyz si prectete soubor linux/drivers/block/README.sbpcd, ve kterem se dozvite jak a ktere CDROM pripojit pres zvukove karty.

Tolik alespon jak nakonfigurovat jadro. Muze se stat, ze CDROM bude schopen pracovat jen s datovymi CD disky ( napr. na ruznych ftp servrech dostupny ovladac na NEC260 ).

Co s CDROM v Linuxu

Odpoved je jednoducha - to co pod ostatnimi OS. Muzeme pomoci ruznych prehravacu prehravat audio CDROM jak pod konzoli tak pod X Windows, muzeme je moutnout jako cast filesystemu, pokud do nej vlozime datovy CD disk anebo ho tam muzeme jen tam mit.

Vetsina aplikaci ocekava, ze CDROM je na zarizeni /dev/cdrom, ale velka vetsina appl. dovoluje zadat zarizeni, na kterem je pripojena.

Pokud budeme ho chtit mountnout musime mit v jadre fs ISO9660 nebo ho tam pridat tesne pred mount prikazem vlozit jako modul ( - jak na moduly viz zdrojaky jadra, soubor README.modules ). Pak prikazem 'mount -t iso9660 /dev/cdrom_zarizeni /mount_point' jej pridame do adresarove struktury.

Jak prehravat audio CD disky

workbone s normalni distribuci SLACKWARE se dodava prehravac, ktery se jmenuje 'workbone'. Je velice jednoduchy jak na ovladani tak na funkce ktere poskytuje. Ovlada se pomoci numericke klavesnice ( nezapomenme si ji zapnout kl. NumLock ). Pri spusteni se objevi vice nez jasny popis klaves. Umoznuje - Start, Stop, Pause, Previous/Next track, Eject, Rewind fore/backward. Nejlepsi je si ho vyzkouset.

workman take standartne dodavan s distribuci SLACKWARE. Tento je urcen pro X Windows a je napsan v XView. Je oproti workbone rozsiren o moznost si vytvaret playlisty, rozdelovat tracky a s nimi pak pracovat jako s normalnimy tracky. Program si udrzuje databanku uz vytvorenych playlistu. V playlistu lze zakazat prehravani tracku, urcovat poradi, pojmenovavat tracky. Dale lze zvolit pro disk mod prehravani (playlist, shuffle, normal ) a spoustu dalsi veci - nejlepsi je si ho vyzkouset. Tento prehravac povazuji za jeden z mala nejlepsi co jsem kdy videl.

xplaycd - tento je z baliku programu multimedia. Je urcen pro X Windows a je srovnatelny s workbone.

Prehravacu existuje urcite vice, ale nechce se mi je popisovat - hledejte na ruznych ftp servrech nebo si nejaky napiste sami - jak na to je popsano v nasledujici kapitole.

Ovladani CD ROM z pohledu programatora

Ovladat prehravani audio CDROMu je zcela jednoduche - nejdrive si otevreme file_descriptor na specialni soubor, na kterem je pripojen CD ROM a pak uz jen aplikujeme ioctl prikazy. Budu se zabyvat jen audio CD disky, i kdyz lze pouzit tyto ioctl prikazy i na datove disky, ale stejne se nic nestane. Ovladani se nelisi at uz mame ATAPI, SCSI nebo kdovijakou CDROM ( alespon doufam :-) ).

Co v programu musi byt

  int cdrom = open( "/dev/cdrom", O_RDONLY ); // otevreni fd na cdrom
a ioctl prikazy - jinak viz soubor linux/cdrom.h

nacteni TOC ( table of content ) - obsahu CD disku

ioctl( cdrom, CDROMREADTOCHDR, & struct cdrom_tochdr );
- precte cislo prvni a posledni polozky v TOC - zjisteni velikosti TOC

ioctl( cdrom, CDROMREADTOCENTRY, &struct cdrom_tocentry );
- precte jednu polozku z TOC, ve strukture musi byt nastavena polozka 'cdte_track' na cislo pozadovane polozku a 'cdte_format' na hodnotu 'CDROM_LBA' nebo 'CDROM_MSF' - rika v jakem formatu chceme vratit pocatecni adresu tracku. Format LBA nam naplni 'cdte_addr.lba' absolutnim sektorem a MSF cdte_addr.msf - tento format znamena minuta, sekunda, frame ( 1/75 sec ). Po navratu je teda nastavena polozka 'cdte_addr' adresou zacatku, 'cdte_cdte_datamode' rika, zda je track datovy ci audio a to pres masku CDROM_DATA_TRACK ( 1 data, 0 audio ). O polozkach cdte_adr, cdte_ctrl nic blizsiho nevim.

Pokud chceme zjistit konec CD disku pouzijeme jako cislo polozky CDROM_LEADOUT.

zjisteni aktualniho stavu CDROM

ioctl( cdrom, CDROMSUBCHNL, &struct cdrom_subchnl );
- precte Q channel - informace o aktualnim stavu CD ROM. Musime inicializovat polozku 'cdsc_format' na 'CDROM_LBA' nebo 'CDROM_MSF' a po navratu jsou nastaveny ostatni polozky. Timto volanim precteme - aktualni track, polohu v tracku, absolutni polohu na disku a nejake dalsi informace, jejich vyznam zcela neznam a status - 'cdsc_audiostatus', ktery nabyva hodnot CDROM_AUDIO_?????? - viz cdrom.h.

prehravani a nektere dalsi prikazy

ioctl( cdrom, CDROMPLAYMSF, &struct cdrom_msf );
- prehraje oblast z disku zadanou casy ve strukture cdrom_msf. Ty muzou libovolne prekryvat rozdeleni disku danou polozkami z TOC.
ioctl( cdrom, CDROMPLAYTRKIND, &struct cdrom_ti );
- take prehraji oblast z disku, ale ta je zadana cislem polozky z TOC.
ioctl( cdrom, CDROMPAUSE, NULL );
- pause prehravani
ioctl( cdrom, CDROMRESUME, NULL );
- pokracovani prehravani po pause
ioctl( cdrom, CDROMSTOP, NULL );
- okamzite ukonceni prehravani
ioctl( cdrom, CDROMSTART, NULL );
- zapne motor CDROM
ioctl( cdrom, CDROMEJECT, NULL );
- vysune disk

To je asi vsechno jako uvod k CD ROMum. Pro uziti viz napr. muj priklad cdplay.cc.


Linux & zvukove karty

Zvukovych karet je dnes mnoho typu. Lisi se predevsim technologii prehravani a tim i vytvareni vysledneho zvuku.

Prvnim typem jsou karty kompatibilni se SoundBlastrem. Karty jsou standartne vybaveny FM cipem alespon verze OPL-2. Zvuk vznika PCM - pulsni modulaci - zvuk je sniman/prehravan v tzv. samplech (8 nebo 16 bit ) a ty jsou pote ruznou rychlosti ( 5000-44100 Hz, mono/stereo ) prehravany. FM cip slouzi k vytvareni zvuku pomoci frekvencni modulace - mame dva (OPL-2) nebo ctyri( OPL-3) operatory nejcasteji se sinovym prubehem, ktere bud scitame nebo jeden druhym moduluje.

Na podobnem principu pracuji karty Gravis. Rozdil spociva v tom, ze maji vlastni pamet, ve ktere jsou ulozeny samply nastroju a ty dokazi prehravat s ruznymi efekty ve 32 kanalech. Jsou take schopny nahravani/prehravani jako SB. Jsou vhodne jako prehravajici midi zarizeni.

Poslednim typem jsou MIDI karty - slouzi k pripojeni MIDI zarizeni bud pro vstup nebo vystup. To znamena, ze pocitac muze jednak zaznamenavat prehravanou skladbu a zaroven ji prehravat. Bohuzel vice o MIDI nevim - nemam s nim moc velke zkusenosti. V podstate SB i Gravis maji MIDI konektory.

Podporovane typy zvukovych karet

SB v1.0 a kompatibilni ( 8 bit mono, max 22050 Hz, DMA prenos, bez mixeru )

SB v2.0 vylepsena SB v1.0

SB pro - ( 8 bit stereo/mono, 44100Hz(mono), 22050Hz(stereo) )

SB 16 - 8/16 bit stereo/mono, 44100Hz, 2x DMA 8,16

SB 16ASP - jako SB16 + HW komprese ALaw/MuLaw/IMA ADPCM, zatim jsem napsal jen prvni alpha verzi

SB AWE32 - jako SB 16 ASP

ProAudio Spectrum 16 - karta podobna SB 16 + OPL-3

Gravis Ultrasound, Gravis MAX

ruzne MIDI karty vetsinou kompatibilni s MPU 401

- ovladace karet se musi pridavat do jadra - viz 'make config'

Programy pro vyuziti zvukovych karet

Prehravace slouzi k prehravani ruznych typu sound souboru od raw az po mod, s3m, ... , midi.

prehravace formatu mod, s3m,...

tracker prehravac amiga mod souboru ( pres /dev/dsp - viz pozdeji )

s3mod prehravac protracker s3m souboru a mod souboru ( pres /dev/dsp )

prehravace midi

mp, xmp mp je konzolova, xmp X Windows verze. Prehrava midi soubory pres /dev/sequencer. Muze pouzivat bud Gravis, FM (OPL-2/3) nebo external synthesizer. Pro FM syntezu potrebuje banky standartnich MIDI nastroju (std.sb, std.o3) a bubnu (drums.sb,drums.o3). Pro Gravise vyzaduje patche nastroju a bubnu (std.gus,drums.gus) dodavane s kartou. Ovladani je velice snadne. Pod X Windows je lepsi nastaveni parametru.

timidity prehravac, ktery pracuje na principu Gravise - z nasemplovanych nastroju vyrabi vysledny signal a ten bud uklada do soubodu ve formaty WAV nebo prehrava pres /dev/dsp.

ostatni

Svgafft - zobrazuje frekvencni spektrum signalu, potrebuje svgalib nebo existuje verze i do X ( zatim jsem ji nevidel ).

sod - prehravac, pracujici jako timidity, ale prehrava vlastni typ souboru

rawseq - docela dobra hracka - jako sod

maplay - prehravac mpeg sound formatu

ad - prehravac formatu adagio - prevadi i do mid formatu

sox - program na prevod

rsynth - program prevadejici psany text na rec

speak - jako rsynth, ale trochu horsi

ogi - rozpoznavani reci - jeste jsem to nestacil rozchodit (:-")

sox - program na prevadeni zvukovych formatu mezi sebou a provadeni ruznych effektu na nich

Mixery novejsi karty ( SB pro, SB16, Gravis, ... ) maji tzv mixer - dovoluje nastavovat hlasitosti vstupnich/vystupnich linek, urcovat zdroj nahravani.

konzolove mixery

cam, aumixer - ovladni pomoci kurzorovych klaves + zapinani nahravacich kanalu

X Windows mixery

xmix, xmixer - vyzkousejte si je

Jak se programove ovlada zvukova karta

Existuje nekolik standartnich zarizeni:

/dev/sndstat - provedte cat /dev/sndstat a uvidite info o aktualne nainstalovanych kartach

/dev/dsp - zarizeni ke PCM prehravani/nahravani

/dev/audio - jako /dev/dsp ale misto PCM samplu prichazeji Mu Law samply

/dev/mixer - zarizeni k ovladani mixeru

/dev/midi - slouzi jako nejjednodusi MIDI zarizeni dovoluje primo komunikovat s primojenym midi zarizenim

/dev/sequencer - MIDI zarizeji mnohem inteligentnejsi nez /dev/midi, dovoluje rozdelit prehravani vice zarizeni vlozenych do systemu

Pokud je v systemu vice zarizeni pak jsou na dalsich minor cislech, ktera se uvadeji za vlastnim jmenem ( napr. /dev/midi01 ).

Na zacatku se pomoci prikazu open otevre nami pozadovane zarizeni a pak se pomoci ioctl volani nastavuji parametry zarizeni a prikazy write/read provadi presun dat do/z karty. Vsechny info cerpany z linux/soundcard.h a zdrojaku jadra.

/dev/dsp

Nejjednodusim uzitim je toto: 'cat /dev/dsp > sample.raw' a dokud neprerusime tak se ukladaji samply do souboru sample.raw. Vzdy, kdyz se zarizeni otevira, tak se inicializuje na mono,8 bit, 8000 Hz. Pak soubor prehrajeme takto: 'cat sample.raw >/dev/dsp'.

A ted na urovni C

int dsp = open("/dev/dsp", O_RDWR );
ioctl( dsp, SNDCTL_DSP_RESET, NULL )
- resetuje kartu

ioctl( dsp, SNDCTL_DSP_SYNC, NULL )
- pocka do ukonceni prave probihajici operace

ioctl( dsp, SNDCTL_DSP_SPEED, int *speed )
nastavi rychlost na speed a do speed pak ulozi skutecne nastavenou hodnotu

ioctl( dsp, SNDCTL_DSP_STEREO, int *stereo )
- stereo = 0/1, vrati ve stereo skutecne nastavenou hodnotu

ioctl( dsp, SNDCTL_DSP_GETFMTS, int *afmts )
- vrati bitmapu podporovanych audio formatu:

AFMT_MU_LAW - Mu Law - logaritmicka komprese 16->8, uzivaji Sun spark

AFMT_A_LAW - A Law podobna Mu Law

AFMT_IMA_ADPCM - z 16 bit dela 4 bity

AFMT_U8 - unsigned 8 bit sample

AFMT_S16_LE - little endien signed 16 bit sample

AFMT_S16_BE - big endien signed 16 bit sample

AFMT_S8 - signed 8 bit sample

AFMT_U16_LE - little endien unsigned 16 bit sample

AFMT_U16_BE - big endien unsigned 16 bit sample

ioctl( dsp, SNDCTL_DSP_SETFMT, int *afmt )
- nastavi ( precte ) aktualni audio format a vrati skutecne nastaveny ( pokud afmt = AFMT_QUERY tak se vrati aktualni format )

dale pro /dev/dsp ioctl prikazu existuji synonyma jiz uvedenych prikazu - viz linux/soundcard.h

/dev/audio

- vse jako pro /dev/dsp, ale je inicializovano na audio format Mu Law. Pokud ho karta nepodporuje ( SNDCTL_DSP_GETFMTS ) tak je sw emulovano.

/dev/mixer

Existuje nekolik zarizeni, na ktere se odkazujeme pomoci jejich bitovych masek:

SOUND_MASK_VOLUME - hlasitost na vystupu

SOUND_MASK_BASS - basy na vystupu

SOUND_MASK_TREBLE - vysky na vystupu

SOUND_MASK_SYNTH - hlasitos synth

SOUND_MASK_PCM - hlasitost PCM

SOUND_MASK_SPEAKER - hl. pc speakru

SOUND_MASK_LINE - hl. line in

SOUND_MASK_MIC - hl. mic

SOUND_MASK_CD - hl. CD vstupu

SOUND_MASK_IMIX - recording monitor

SOUND_MASK_ALTPCM - druhe PCM zarizeni

SOUND_MASK_RECLEV - zaznamova hlasitost

ioctl( mixer, MIXER_READ(dev), int *volume )
- dev je SOUND_MASK_?????, do volume se pak ulozi hlasitost pozadovaneho zarizeni a to takto - do 1. byte se ulozi levy kanal ( 0-100 ) a do 2. byte se ulozi pravy kanal ( 0 - 100 ).

ioctl( mixer, SOUND_MIXER_READ_RECSRC, int *recsrc )
- do recsrc ulozi bitovou masku aktualniho nastaveni zaznamovych zarizeni.

ioctl( mixer, SOUND_MIXER_READ_DEVMASK, int *devices )
- do devices ulozi bitovou masku vsech mixerem podporovanych zarizeni.

ioctl( mixer, SOUND_MIXER_READ_RECMASK, int *maxrec )
- do maxrec da bit. masku vsech zarizeni, ze kterych je mozno nahravat.

ioctl( mixer, SOUND_MIXER_READ_STEREODEVS, int *strdev )
- do strdev da vsechna zarizeni schopna sterea.

ioctl( mixer, SOUND_MIXER_READ_CAPS, int *cap )
- do cap da schopnost mixeru - bitovou maskou, zatim jen SOUND_CAP_EXCL_INPUT - pokud je nastavena tak lze nahravat jen z jednoho zarizeni najednou.

ioctl( mixer, MIXER_WRITE(dev), int *volume )
- jako MIXER_READ, jen nastavuje hlasitosti.

/dev/midi, /dev/sequencer

- programovat tyto zarizeni bez hlubsi znalosti MIDI protokolu a nejakeho MIDI zarizeni je docela nezazivne a bohuzel se o nem nemohu moct vice rozepsat. Vsechny ioctl prikazy jsou popsany v linux/soundcard.h a mnoho z nich uz primo nazvem rika, co delaji.

/dev/sequencer umoznuje inicializovat jak FM synth tak Gravis pomoci ruznych patchu.

Priklady:

pro /dev/dsp viz dsp.cc

pro /dev/mixer viz mixer.cc

Vsechny poznatky jsou cerpany ze zdrojaku jadra, vlastnich zkusenosti a nahodnych poznamek na ruznych mistech.

Zminovane programy lze stahnout z kazdeho ftp serveru, ktery mirroruje sunsite, napr ftp.muni.cz/pub/UNIX/linux/apps/sound.

Nemohu zarucit, ze vsechny udaje zde uvedene jsou v poradku. Pokud najdete chybu(y) nebo budete mit nejake dotazy, pripominky, tak mi poslete e-mail na adresu rpos1368@comenius.ms.mff.cuni.cz

.