IntroductiontoSoundProgrammingwithALSA.docx
《IntroductiontoSoundProgrammingwithALSA.docx》由会员分享,可在线阅读,更多相关《IntroductiontoSoundProgrammingwithALSA.docx(18页珍藏版)》请在冰豆网上搜索。
IntroductiontoSoundProgrammingwithALSA
IntroductiontoSoundProgrammingwithALSA
ALSAstandsfortheAdvancedLinuxSoundArchitecture.Itconsistsofasetofkerneldrivers,anapplicationprogramminginterface(API)libraryandutilityprogramsforsupportingsoundunderLinux.Inthisarticle,IpresentabriefoverviewoftheALSAProjectanditssoftwarecomponents.ThefocusisonprogrammingthePCMinterfacesofALSA,includingprogrammingexampleswithwhichyoucanexperiment.
YoumaywanttoexploreALSAsimplybecauseitisnew,butitisnottheonlysoundAPIavailable.ALSAisagoodchoiceifyouareperforminglow-levelaudiofunctionsformaximumcontrolandperformanceorwanttomakeuseofspecialfeaturesnotsupportedbyothersoundAPIs.Ifyoualreadyhavewrittenanaudioapplication,youmaywanttoaddnativesupportfortheALSAsounddrivers.Ifyourprimaryinterestisn'taudioandyousimplywanttoplaysoundfiles,usingoneofthehigher-levelsoundtoolkits,suchasSDL,OpenALorthoseprovidedindesktopenvironments,maybeabetterchoice.ByusingALSAyouarerestrictedtousingsystemsrunningaLinuxkernelwithALSAsupport.
HistoryofALSA
TheALSAProjectwasstartedbecausethesounddriversintheLinuxkernel(OSS/Freedrivers)werenotbeingmaintainedactivelyandwerelaggingbehindthecapabilitiesofnewsoundtechnology.JaroslavKysela,whopreviouslyhadwrittenasoundcarddriver,startedtheproject.Overtime,moredevelopersjoined,supportformanysoundcardswasaddedandthestructureoftheAPIwasrefined.
Duringdevelopmentofthe2.5seriesofLinuxkernel,ALSAwasmergedintotheofficialkernelsource.Withthereleaseofthe2.6kernel,ALSAwillbepartofthestableLinuxkernelandshouldbeinwideuse.
DigitalAudioBasics
Sound,consistingofwavesofvaryingairpressure,isconvertedtoitselectricalformbyatransducer,suchasamicrophone.Ananalog-to-digitalconverter(ADC)convertstheanalogvoltagesintodiscretevalues,calledsamples,atregularintervalsintime,knownasthesamplingrate.Bysendingthesamplestoadigital-to-analogconverterandanoutputtransducer,suchasaloudspeaker,theoriginalsoundcanbereproduced.
Thesizeofthesamples,expressedinbits,isonefactorthatdetermineshowaccuratelythesoundisrepresentedindigitalform.Theothermajorfactoraffectingsoundqualityisthesamplingrate.TheNyquistTheoremstatesthatthehighestfrequencythatcanberepresentedaccuratelyisatmostone-halfthesamplingrate.
ALSABasics
ALSAconsistsofaseriesofkerneldevicedriversformanydifferentsoundcards,anditalsoprovidesanAPIlibrary,libasound.ApplicationdevelopersareencouragedtoprogramusingthelibraryAPIandnotthekernelinterface.Thelibraryprovidesahigher-levelandmoredeveloper-friendlyprogramminginterfacealongwithalogicalnamingofdevicessothatdevelopersdonotneedtobeawareoflow-leveldetailssuchasdevicefiles.
Incontrast,OSS/Freedriversareprogrammedatthekernelsystemcalllevelandrequirethedevelopertospecifydevicefilenamesandperformmanyfunctionsusingioctlcalls.Forbackwardcompatibility,ALSAprovideskernelmodulesthatemulatetheOSS/Freesounddrivers,somostexistingsoundapplicationscontinuetorununchanged.Anemulationwrapperlibrary,libaoss,isavailabletoemulatetheOSS/FreeAPIwithoutkernelmodules.
ALSAhasacapabilitycalledpluginsthatallowsextensiontonewdevices,includingvirtualdevicesimplementedentirelyinsoftware.ALSAprovidesanumberofcommand-lineutilities,includingamixer,soundfileplayerandtoolsforcontrollingspecialfeaturesofspecificsoundcards.
ALSAArchitecture
TheALSAAPIcanbebrokendownintothemajorinterfacesitsupports:
Controlinterface:
ageneral-purposefacilityformanagingregistersofsoundcardsandqueryingtheavailabledevices.
PCMinterface:
theinterfaceformanagingdigitalaudiocaptureandplayback.Therestofthisarticlefocusesonthisinterface,asitistheonemostcommonlyusedfordigitalaudioapplications.
RawMIDIinterface:
supportsMIDI(MusicalInstrumentDigitalInterface),astandardforelectronicmusicalinstruments.ThisAPIprovidesaccesstoaMIDIbusonasoundcard.TherawinterfaceworksdirectlywiththeMIDIevents,andtheprogrammerisresponsibleformanagingtheprotocolandtiming.
Timerinterface:
providesaccesstotiminghardwareonsoundcardsusedforsynchronizingsoundevents.
Sequencerinterface:
ahigher-levelinterfaceforMIDIprogrammingandsoundsynthesisthantherawMIDIinterface.IthandlesmuchoftheMIDIprotocolandtiming.
Mixerinterface:
controlsthedevicesonsoundcardsthatroutesignalsandcontrolvolumelevels.Itisbuiltontopofthecontrolinterface.
DeviceNaming
ThelibraryAPIworkswithlogicaldevicenamesratherthandevicefiles.Thedevicenamescanberealhardwaredevicesorplugins.Hardwaredevicesusetheformathw:
i,j,whereiisthecardnumberandjisthedeviceonthatcard.Thefirstsounddeviceishw:
0,0.Thealiasdefaultreferstothefirstsounddeviceandisusedinalloftheexamplesinthisarticle.Pluginsuseotheruniquenames;plughw:
forexample,isapluginthatprovidesaccesstothehardwaredevicebutprovidesfeatures,suchassamplingrateconversion,insoftwareforhardwarethatdoesnotdirectlysupportit.Thedmixanddsharepluginsallowyoutodownmixseveralstreamsandsplitasinglestreamdynamicallyamongdifferentapplications.
SoundBuffersandDataTransfer
Asoundcardhasahardwarebufferthatstoresrecordedsamples.Whenthebufferissufficientlyfull,itgeneratesaninterrupt.Thekernelsounddriverthenusesdirectmemoryaccess(DMA)totransfersamplestoanapplicationbufferinmemory.Similarly,forplayback,anotherapplicationbufferistransferredfrommemorytothesoundcard'shardwarebufferusingDMA.
Thesehardwarebuffersareringbuffers,meaningthedatawrapsbacktothestartwhentheendofthebufferisreached.Apointerismaintainedtokeeptrackofthecurrentpositionsinboththehardwarebufferandtheapplicationbuffer.Outsideofthekernel,onlytheapplicationbufferisofinterest,sofromhereonwediscussonlytheapplicationbuffer.
ThesizeofthebuffercanbeprogrammedbyALSAlibrarycalls.Thebuffercanbequitelarge,andtransferringitinoneoperationcouldresultinunacceptabledelays,calledlatency.Tosolvethis,ALSAsplitsthebufferupintoaseriesofperiods(calledfragmentsinOSS/Free)andtransfersthedatainunitsofaperiod.
Aperiodstoresframes,eachofwhichcontainsthesamplescapturedatonepointintime.Forastereodevice,theframewouldcontainsamplesfortwochannels.Figure1illustratesthebreakdownofabufferintoperiods,framesandsampleswithsomehypotheticalvalues.Here,leftandrightchannelinformationisstoredalternatelywithinaframe;thisiscalledinterleavedmode.Anon-interleavedmode,whereallthesampledataforonechannelisstoredfollowedbythedataforthenextchannel,alsoissupported.
Figure1.TheApplicationBuffer
OverandUnderRun
Whenasounddeviceisactive,dataistransferredcontinuouslybetweenthehardwareandapplicationbuffers.Inthecaseofdatacapture(recording),iftheapplicationdoesnotreadthedatainthebufferrapidlyenough,thecircularbufferisoverwrittenwithnewdata.Theresultingdatalossisknownasoverrun.Duringplayback,iftheapplicationdoesnotpassdataintothebufferquicklyenough,itbecomesstarvedfordata,resultinginanerrorcalledunderrun.TheALSAdocumentationsometimesreferstobothoftheseconditionsusingthetermXRUN.ProperlydesignedapplicationscanminimizeXRUNandrecoverifitoccurs.
ATypicalSoundApplication
ProgramsthatusethePCMinterfacegenerallyfollowthispseudo-code:
openinterfaceforcaptureorplayback
sethardwareparameters
(accessmode,dataformat,channels,rate,etc.)
whilethereisdatatobeprocessed:
readPCMdata(capture)
orwritePCMdata(playback)
closeinterface
Welookatsomeworkingcodeinthefollowingsections.IrecommendyoucompileandruntheseonyourLinuxsystem,lookattheoutputandtrysomeofthesuggestedmodifications.Thefulllistingsfortheexampleprogramsthataccompanythisarticleareavailablefordownloadfrom
Listing1.DisplaySomePCMTypesandFormats
#include
intmain(){
intval;
printf("ALSAlibraryversion:
%s\n",
SND_LIB_VERSION_STR);
printf("\nPCMstreamtypes:
\n");
for(val=0;val<=SND_PCM_STREAM_LAST;val++)
printf("%s\n",
snd_pcm_stream_name((snd_pcm_stream_t)val));
printf("\nPCMaccesstypes:
\n");
for(val=0;val<=SND_PCM_ACCESS_LAST;val++)
printf("%s\n",
snd_pcm_access_name((snd_pcm_access_t)val));
printf("\nPCMformats:
\n");
for(val=0;val<=SND_PCM_FORMAT_LAST;val++)
if(snd_pcm_format_name((snd_pcm_format_t)val)
!
=NULL)
printf("%s(%s)\n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
printf("\nPCMsubformats:
\n");
for(val=0;val<=SND_PCM_SUBFORMAT_LAST;
val++)
printf("%s(%s)\n",
snd_pcm_subformat_name((
snd_pcm_subformat_t)val),
snd_pcm_subformat_description((
snd_pcm_subformat_t)val));
printf("\nPCMstates:
\n");
for(val=0;val<=SND_PCM_STATE_LAST;val++)
printf("%s\n",
snd_pcm_state_name((snd_pcm_state_t)val));
return0;
}
Listing1displayssomeofthePCMdatatypesandparametersusedbyALSA.ThefirstrequirementistoincludetheheaderfilethatbringsinthedefinitionsforalloftheALSAlibraryfunctions.Oneofthedefinit