ALSA Audio API手册.docx
《ALSA Audio API手册.docx》由会员分享,可在线阅读,更多相关《ALSA Audio API手册.docx(9页珍藏版)》请在冰豆网上搜索。
ALSAAudioAPI手册
ALSAAudioAPI手册
ALSAAudioAPI手册
ThisdocumentattemptstoprovideanintroductiontotheALSAAudioAPI.ItisnotacompletereferencemanualfortheAPI,anditdoesnotcovermanyspecificissuesthatmorecomplexsoftwarewillneedtoaddress.However,itdoestrytoprovideenoughbackgroundandinformationforareasonablyskilledprogrammerbutwhoisnewtoALSAtowriteasimpleprogramthatusestheAPI.
AllcodeinthedocumentislicensedundertheGNUPublicLicense.IfyouplantowritesoftwareusingALSAundersomeotherlicense,thenIsuggestyoufindsomeotherdocumentation.
Contents
UnderstandingAudioInterface
WhataTypicalAudioApplicationDoes
AMinimalPlaybackProgram
AMinimalCaptureProgram
AMinimalinterrupt-drivenProgram
AMinimalDuplexProgram
HowToDoIt
OpeningTheDevice
SettingTheParameters
ReceivingAndDeliveringData
WhyYouMightWantToForgetAboutAllOfThis
UnderstandingAudioInterfaces
Letusfirstreviewthebasicdesignofanaudiointerface.Asanapplicationdeveloper,youdon'tneedtoworryaboutthislevelofoperation-itsalltakencareofbythedevicedriver(whichisoneofthecomponentsthatALSAprovides).Butyoudoneedtounderstandwhatisgoingataconceptuallevelifyouwanttowriteefficientandflexiblesoftware.
Anaudiointerfaceisadevicethatallowsacomputertoreceiveandtosendaudiodatafrom/totheoutsideworld.Insideofthecomputer,audiodataisrepresentedastreamofbits,justlikeanyotherkindofdata.However,theaudiointerfacemaysendandreceiveaudioaseitherananalogsignal(atime-varyingvoltage)orasadigitalsignal(somestreamofbits).Ineithercase,thesetofbitsthatthecomputerusestorepresentaparticularsoundwillneedtobetransformedbeforeitisdeliveredtotheoutsideworld,andlikewise,theexternalsignalreceivedbytheinterfacewillneedtobetransformedbeforeitisusefultothecomputer.Thesetwotransformationsaretheraisond'etreoftheaudiointerface.
Withintheaudiointerfaceisanareareferredtoasthe"hardwarebuffer".Asanaudiosignalarrivesfromtheoutsideworld,theinterfaceconvertsitintoastreamofbitsusablebythecomputerandstoresitintheparthardwarebufferusedtosenddatatothecomputer.Whenithascollectedenoughdatainthehardwarebuffer,theinterfaceinterruptsthecomputertotellitthatithasdatareadyforit.Asimilarprocesshappensinreversefordatabeingsentfromthecomputertotheoutsideworld.Theinterfaceinterruptsthecomputertotellitthatthereisspaceinthehardwarebuffer,andthecomputerproceedstostoredatathere.Theinterfacelaterconvertsthesebitsintowhateverformisneededtodeliverittotheoutsideworld,anddeliversit.Itisveryimportanttounderstandthattheinterfaceusesthisbufferasa"circularbuffer".Whenitgetstotheendofthebuffer,itcontinuesbywrappingaroundtothestart.
Forthisprocesstoworkcorrectly,thereareanumberofvariablesthatneedtobeconfigured.Theyinclude:
whatformatshouldtheinterfaceusewhenconvertingbetweenthebitstreamusedbythecomputerandthesignalusedintheoutsideworld?
atwhatrateshouldsamplesbemovedbetweentheinterfaceandthecomputer?
howmuchdata(and/orspace)shouldtherebebeforethedeviceinterruptsthecomputer?
howbigshouldthehardwarebufferbe?
Thefirsttwoquestionsarefundamentalingoverningthequalityoftheaudiodata.Thesecondtwoquestionsaffectthe"latency"oftheaudiosignal.Thistermreferstothedelaybetween
dataarrivingattheaudiointerfacefromtheoutsideworld,anditbeingavailabletothecomputer("inputlatency")
databeingdeliveredbythecomputer,anditbeingdeliveredtotheoutsideworld("outputlatency")
Bothoftheseareveryimportantformanykindsofaudiosoftware,thoughsomeprogramsdonotneedbeconcernedwithsuchmatters.
Whatatypicalaudioapplicationdoes
Atypicalaudioapplicationhasthisroughstructure:
open_the_device();set_the_parameters_of_the_device();while(!
done){/*oneorbothofthese*/receive_audio_data_from_the_device();deliver_audio_data_to_the_device();}closethedevice
AMinimalPlaybackProgram
Thisprogramopensanaudiointerfaceforplayback,configuresitforstereo,16bit,44.1kHz,interleavedconventionalread/writeaccess.Thenitsdeliversachunkofrandomdatatoit,andexits.ItrepresentsaboutthesimplestpossibleuseoftheALSAAudioAPI,andisn'tmeanttobearealprogram.#include<stdio.h>#include<stdlib.h>#include<alsa/asoundlib.h>main(intargc,char*argv[]){inti;interr;shortbuf[128];snd_pcm_t*playback_handle;snd_pcm_hw_params_t*hw_params;if((err=snd_pcm_open(&playback_handle,argv[1],SND_PCM_STREAM_PLAYBACK,0))<0){fprintf(stderr,"cannotopenaudiodevice%s(%s)\n",argv[1],snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_malloc(&hw_params))<0){fprintf(stderr,"cannotallocatehardwareparameterstructure(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_any(playback_handle,hw_params))<0){fprintf(stderr,"cannotinitializehardwareparameterstructure(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_access(playback_handle,hw_params,SND_PCM_ACCESS_RW_INTERLEAVED))<0){fprintf(stderr,"cannotsetaccesstype(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_format(playback_handle,hw_params,SND_PCM_FORMAT_S16_LE))<0){fprintf(stderr,"cannotsetsampleformat(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_rate_near(playback_handle,hw_params,44100,0))<0){fprintf(stderr,"cannotsetsamplerate(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_channels(playback_handle,hw_params,2))<0){fprintf(stderr,"cannotsetchannelcount(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params(playback_handle,hw_params))<0){fprintf(stderr,"cannotsetparameters(%s)\n",snd_strerror(err));exit
(1);}snd_pcm_hw_params_free(hw_params);if((err=snd_pcm_prepare(playback_handle))<0){fprintf(stderr,"cannotprepareaudiointerfaceforuse(%s)\n",snd_strerror(err));exit
(1);}for(i=0;i<10;++i){if((err=snd_pcm_writei(playback_handle,buf,128))!
=128){fprintf(stderr,"writetoaudiointerfacefailed(%s)\n",snd_strerror(err));exit
(1);}}snd_pcm_close(playback_handle);exit(0);}
AMinimalCaptureProgram
Thisprogramopensanaudiointerfaceforcapture,configuresitforstereo,16bit,44.1kHz,interleavedconventionalread/writeaccess.Thenitsreadsachunkofrandomdatafromit,andexits.Itisn'tmeanttobearealprogram.#include<stdio.h>#include<stdlib.h>#include<alsa/asoundlib.h>main(intargc,char*argv[]){inti;interr;shortbuf[128];snd_pcm_t*capture_handle;snd_pcm_hw_params_t*hw_params;if((err=snd_pcm_open(&capture_handle,argv[1],SND_PCM_STREAM_CAPTURE,0))<0){fprintf(stderr,"cannotopenaudiodevice%s(%s)\n",argv[1],snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_malloc(&hw_params))<0){fprintf(stderr,"cannotallocatehardwareparameterstructure(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_any(capture_handle,hw_params))<0){fprintf(stderr,"cannotinitializehardwareparameterstructure(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_access(capture_handle,hw_params,SND_PCM_ACCESS_RW_INTERLEAVED))<0){fprintf(stderr,"cannotsetaccesstype(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_format(capture_handle,hw_params,SND_PCM_FORMAT_S16_LE))<0){fprintf(stderr,"cannotsetsampleformat(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_rate_near(capture_handle,hw_params,44100,0))<0){fprintf(stderr,"cannotsetsamplerate(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params_set_channels(capture_handle,hw_params,2))<0){fprintf(stderr,"cannotsetchannelcount(%s)\n",snd_strerror(err));exit
(1);}if((err=snd_pcm_hw_params(capture_handle,hw_params))<0){fprintf(stderr,"cannotsetparameters(%s)\n",snd_strerror(err));exit
(1);}snd_pcm_hw_params_free(hw_params);if((err=snd_pcm_prepare(capture_handle))<0){fprintf(stderr,"cannotprepareaudiointerfaceforuse(%s)\n",snd_strerror(err));exit
(1);}for(i=0;i<10;++i){if((err=snd_pcm_readi(capture_handle,buf,128))!
=128){fprintf(stderr,"readfromaudiointerfacefailed(%s)\n",snd_strerror(err));exit
(1);}}snd_pcm_close(capture_handle);exit(0);}
AMinimalInterrupt-DrivenProgram
Thisprogramopensanaudiointerfaceforplayback,configuresitforstereo,16bit,44.1kHz,interleavedconventionalread/writeaccess.Itthenwaitstilltheinterfaceisreadyforplaybackdata,anddeliversrandomdatatoitatthattime.Thisdesignallowsyourprogramtobeeasilyportedtosystemsthatrelyonacallback-drivenmechanism,suchasJACK,LADSPA,CoreAudio,VSTandmanyothers.#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<poll.h>#include<alsa/asoundlib.h>snd_pcm_t*playback_handle;shortbuf[4096];intplayback_callback(snd_pcm_sframes_tnframes){interr;printf("playbackcallbackcalledwith%uframes\n",nframes);/*...fillbufwithdata...*/if((err=snd_pcm_writei(playback_handle,buf,nframes))<0){fprintf(stderr,"writefailed(%s)\n",snd_strerror(err));}returnerr;}main(intargc,char*argv[]){snd_pcm_hw_params_t*hw_params;snd_pcm_sw_params_t*sw_params;snd_pcm_sframes_tframes_to_deliver;intnfds;interr;structpollfd*pfds;if((err=snd_pcm_open(&playback_handle,argv[1],SND_PCM_STREAM_PLAYBACK,0))<