Tải bản đầy đủ - 0 (trang)
Chapter 7.  Introducing Java Sound

Chapter 7.  Introducing Java Sound

Tải bản đầy đủ - 0trang

AppletPlaying

TheAppletplay()methodloadsasound(perhapsfromacross

thenetwork)andplaysitonce.play()causestheapplet's

drawingandeventhandlingtofreezewhiletheaudiodataare

retrievedanddoesnothingiftheaudiocan'tbefound(i.e.,no

exceptionisraised).Thesoundismarkedforgarbagecollection

afterbeingplayed,soitmayneedtobedownloadedagain

whenplay()iscalledagain.Example7-1isatypical1990s

example:



Example7-1.Simpleappletthatusestheplay()

method

importjava.applet.Applet;

importjava.awt.*;

publicclassOldMcDonaldextendsApplet

{

publicvoidinit()

{play(getCodeBase(),"McDonald.mid");}

publicvoidpaint(Graphicsg)

{g.drawString("OlderMcDonald",25,25);}

}//endofOldMcDonaldclass



TheMIDIfile(containingthetune"OldMcDonald")isloaded

andplayedastheappletisloaded.getCodeBase()indicatesthat

thefilecanbefoundinthesameplaceastheapplet's.class

file.AnalternativeisgetdocumentBase(),whichspecifiesalocation

relativetotheenclosingwebpage.



ThecodefortheOldMcDonaldappletcanbefoundinthe

SoundExamps/McDonalds/directory.



EarlyversionsofJavaonlysupported8-bitmonoWindows

Wavefiles,butthevariousformatswereextendedinJDK1.2to

includeSunAudio(AUfiles),MacAIFFfiles,MusicalInstrument

DigitalInterface(MIDI)files(type0andtype1),andRich

MediaFormat(RMF).Datacanbe8-bitor16-bit,monoor

stereo,withsampleratesbetween8,000and48,000Hz.



TheAudioClipClass

ManyoftheshortcomingsofApplet'splay()methodare

remediedbytheAudioClipclass.AudioClipseparatesloadingfrom

playingandallowsloopingandterminationviatheloop()and

stop()methods.Example7-2isanupdatedMcDonaldapplet

usingAudioClip.



Example7-2.AppletusingtheAudioClipclass

importjava.awt.*;

importjavax.swing.*;

importjava.applet.AudioClip;



publicclassMcDonaldextendsJApplet

{

privateAudioClipmcdClip;



publicvoidinit()

{mcdClip=getAudioClip(getCodeBase(),"mcdonald.mid");}

publicvoidpaint(Graphicsg)

{g.drawString("OldMcDonald",25,25);}

publicvoidstop()

{mcdClip.stop();}

publicvoidstart()

/*Aloopingplay(andacalltoplay())alwaysstartsat

thebeginningoftheclip.*/

{mcdClip.loop();}

}//endofMcDonaldclass



TheclipisloadedwithgetAudioClip()ininit(),causingthe

applettosuspenduntilthedownloadiscompleted.Thesoundis

playedrepeatedlyduetotheloop()callinstart(),continuing

untiltheappletisremovedfromthebrowser(triggeringacall

tostop()).Ifthepageisdisplayedagain,start()'scalltoloop()

willplaythemusicfromthebeginning.

AnapplicationemploysAudioClipsinjustaboutthesameway,

exceptthattheclipisloadedwithnewAudioClip()fromtheApplet

class,asshowninthePlaySoundapplication(seeExample7-3).



Example7-3.UsingnewAudioClip()froman

applet

importjava.applet.Applet;

importjava.applet.AudioClip;

publicclassPlaySound

{

publicPlaySound(Stringfnm)

{try{

AudioClipclip=Applet.newAudioClip(

getClass().getResource(fnm));

clip.play();//playthesoundonce

}

catch(Exceptione){

System.out.println("Problemwith"+fnm);

}

}



publicstaticvoidmain(String[]args)

{if(args.length!=1){

System.out.println("Usage:javaPlaySound");

System.exit(0);



}

newPlaySound(args[0]);

}

}//endofPlaySoundclass



DespiteAudioClip'ssimplicity,usefulapplicationsandappletscan

bewrittenwithit.Oneofitsgreatstrengthsisthelargenumber

offileformatsthatitsupports.Anotheristhatmultiple

AudioClipscanbeplayedatthesametime.

Adrawbackofthisapproachisthesuspensioncausedbycalls

togetAudioClip()andnewAudioClip().Sun'sJavaSoundtutorial

suggeststhreadsasasolution:thetutorial'sSoundAppletand

SoundApplicationexamplesfireoffaseparatethreadtoloadthe

audio,allowingthemainprogramtocontinue.Anotheranswer

istodownloadthesoundresourceswiththecode,wrapped

togetherinaJARfile,makingthesubsequentloadingalocal,

fastoperation.

AstubbornproblemwithAudioClipisthelackofinformation

aboutwhenapieceofaudiofinishes.Thisknowledgecanbe

usefulingamessincelinkingeventstotheendofanaudio

commentaryormusicclipiscommon.Ahackyworkaroundisto

callsleep()foraperiodbasedontheaudiofile'sbytesize

(whichcanbeobtainedviaaFileobject).

Athirdissueisthelackoflow-levelaccesstothesounddata

(ortheaudiodeviceitisplayingon)topermitruntimeeffects

likevolumechanging,panningbetweenspeakers,andechoing.

Relatedtothisistheinabilitytogeneratenewsoundsduring

execution(i.e.,soundandmusicsynthesis)thoughmanyearly

Javatextsproudlyincludedvariantsoftheclassshownin

Example7-4.



Example7-4.Usingthebeep()method



publicclassBells

{

publicstaticvoidmain(String[]args)

{

//\u0007istheASCIIbell

System.out.println("BELL1\u0007");

try{

Thread.sleep(1000);//separatethebells

}

catch(InterruptedExceptione){}

//ringthebellagain,usingtheToolkitthistime

java.awt.Toolkit.getDefaultToolkit().beep();

System.out.println("BELL2");

System.out.flush();

}//endofmain()

}//endofBellsclass



TheASCIIcharacterbellworksonmanyplatforms,butonlyJava

applicationscanemploytheToolkitbeep()method.



WhatBellsillustratesisthepoorlow-levelaccessofferedby

Java.TheintroductionoftheJavaSoundAPIinJ2SE1.3fixed

thisweakness.



Theexamplesfromthissection(McDonald.java,PlaySound.java,and

Bells.java)canbefoundintheSoundExamps/McDonalds/directory.



TheSoundPlayer

SoundPlayer.java(locatedinSoundExamps/SoundPlayer/)

showsoffthecapabilitiesoftheAudioClipclass(seeFigure7-1)

inalongerexample.



Figure7-1.TheSoundPlayerapplication



Aselectionofsoundfilesindifferentformats(alllocatedinthe

Sounds/subdirectorybelowSoundPlayer/)areofferedup.They

canbeplayedonce,looped,orstopped.It'spossibletohave

multipleclipsplayingandloopingsimultaneously,andthestop

buttonterminatesallthecurrentlyplayingclips.Thisexampleis

somewhatsimilartotheJavaSoundtutorialexample,

SoundApplication.

Figure7-2givestheclassdiagramforSoundPlayer,showingall

thepublicandprivatemethodsandvariablesintheclass.

Twoimportantdatastructuresareinplayhere:

privateHashMapsoundsMap;

privateArrayListplayingClips;



soundsMapholdstheloadedAudioClips,indexedbytheirfilenames.

playingClipsmaintainsalistofcurrentlyplayingAudioClips(or,to



bemoreprecise,whatIthinkisplaying).



Figure7-2.ClassdiagramforSoundPlayer



loadSounds()loadstheAudioClipsandstorestheminsoundsMapfor



lateruse:

privatevoidloadSounds()

{



soundsMap=newHashMap();

for(inti=0;i
AudioClipclip=Applet.newAudioClip(

getClass().getResource(SOUND_DIR+soundFNms

if(clip==null)

System.out.println("Problemloading"+SOUND_DIR+sound

else

soundsMap.put(soundFNms[i],clip);

}

}



newAudioClip()isemployedsinceSoundPlayerisanapplication,and



theURLisspecifiedusingtheassumptionthatthefilesare

locallystoredintheSOUND_DIRsubdirectory(Sounds/).Thefinal

versionofSoundPlayerisaJARfile,createdinthisway:



jarcvmfmainClass.txtSoundPlayer.jarSoundPlayer.classSo



AlltheclassfilesandeverythingintheSounds/subdirectory

arepackedtogether.mainClass.txtcontainsasingleline:

Main-Class:SoundPlayer



TheJARcanbestartedbydouble-clickingitsiconorfromthe

commandline:

java-jarSoundPlayer.jar



playMusic()inSoundPlayerretrievestherelevantAudioClip,and



playsitonceorrepeatedly.Itstoresareferencetotheclipin

theplayingClipsArrayListtoregisterthattheclipisplaying:



privatevoidplayMusic(booleantoLoop)

{

StringchosenFile=(String)playListJcb.getSelectedItem(



//trytogettheAudioClip.

AudioClipaudioClip=(AudioClip)soundsMap.get(chosenFil

if(audioClip==null){

statusLabel.setText("Sound"+chosenFile+"notloade

return;

}

if(toLoop)

audioClip.loop();

else

audioClip.play();//playitonce



playingClips.add(audioClip);//storeareftotheplayin

Stringtimes=(toLoop)?"repeatedly":"once";

statusLabel.setText("Playingsound"+chosenFile+times

}//endofplayMusic()



playMusic()iscalledfromactionPerformed()whentheuser



pressesthePlayorLoopbuttonandispassedatoLoopargument

todistinguishbetweenthetwo.

stopMusic()stopsalltheplayingmusicbycallingAudioClip.stop()



onallthereferencesinplayingClips.Anissueisthatsomeofthe

clipsmayhavefinishedbutthere'snowaytodetectthem.This

isn'treallyaproblemsincecallingstop()onastoppedAudioClip

hasnoeffect:

privatevoidstopMusic()



{

if(playingClips.isEmpty())

statusLabel.setText("Nothingtostop");

else{

AudioClipaudioClip;

for(inti=0;i
audioClip=(AudioClip)playingClips.get(i);

audioClip.stop();//mayalreadyhavestopped,but

//stop()againdoesnoharm

}

playingClips.clear();

statusLabel.setText("Stoppedallmusic");

}

}



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 7.  Introducing Java Sound

Tải bản đầy đủ ngay(0 tr)

×