Å bli føtt våt i Android's SoundPool

Min 13 år gamle sønn og jeg har skrevet et enkelt puslespill for å kjøre på Kindle Fire. For ham er det en sjanse til å lære noe om koding. For meg er det en sjanse til å tilbringe tid med ham og leke med noen av de "morsomme" API-anropene i Android SDK som jeg aldri ser ut til å finne en unnskyldning å bruke i den daglige apputviklingen min, som pleier å være mer forretningsfokusert.

Den siste helgen bestemte vi oss for at spillet offisielt var langt nok til at det trengtes litt lyd for å livne opp det. Tidligere hadde jeg skrevet en tutorial om å lage et lydtavle. I det innlegget brukte jeg Android media player-klassen, så dette virket som stedet å begynne. På kort tid hadde jeg tittelskjermen som spilte en MIDI-fil, og jeg trodde vi satt fast. Sønnen min ble ikke imponert.

Han fortalte at det føltes som "et gammelt spill", og det vi virkelig trengte var kule små gitarriff-lydeffekter. Han fortsatte å finne en serie korte lydklipp han ønsket å injisere på forskjellige viktige deler av spillet. Dette var helt greit og bra, men mediespillerklassen i Android er treg til å spinne opp, har litt overhead og strømmer lyden fra media i stedet for minne. Sluttresultatet er at det er for stort og klønete å bruke for lydeffekter i sanntid under spill.

Fast bestemt på å ikke være forfatteren av "et gammelt spill", dykke jeg inn i Android-dokumentasjonen. Det var der jeg oppdaget lydbassengklassen. SoundPool er et Android-bibliotek som er spesielt målrettet mot å spille av korte lydklipp. Den er designet for å være lydhør, lett og fleksibel.

Prosjektet som følger er en kort demonstrasjon av hvordan du bruker SoundPool API. Følg gjerne med, eller last ned hele prosjektet.

1. Start et nytt prosjekt i Eclipse. Målrette Android SDK 1.6 eller nyere. Avhengig av hvilken versjon av ADT-pluginen du har, kan det hende du må endre navn på oppstartaktiviteten til Main.java for å matche prosjektfilene mine.

2. I mappen / res må vi lage en katalog som heter / raw. Det er her du vil plassere lydklippene dine. Dokumentasjonen sier at lydbassengklassen kan håndtere WAV-filer, men jeg fant at den oppførte seg inkonsekvent til jeg byttet til OGG. Heldigvis er det mange gratis applikasjoner på nettet for å konvertere mellom WAV og OGG, så dette burde ikke være et stort problem.

3. I mappen / res / raw har jeg lagt til to lydklipp: set_trap.ogg og spring_trap.ogg. Dette er bare et par lydklipp jeg lastet ned av en musefelle som ble satt og deretter sprung.

4. Nå må vi sette sammen en enkel layout i /res/layout/main.xml. I forbindelse med demoen bruker vi en lineær layout med tekstvisning og noen få knapper.

 main.xml  "1.0" encoding = "utf-8" ?> 
 "Http://schemas.android.com/apk/res/android" 
 android: layout_width = "fill_parent" 
 android: layout_height = "fill_parent" 
 android: orientering = "vertikal" > 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 
 android: text = "Sound FX Demo" 
 android: textSize = "24sp" 
 android: gravitasjon = "sentrum" 
 android: textColor = "#ffffff" 
 android: paddingBottom = "20dip" /> 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 
 android: orientering = "horisontal" 
 android: gravitasjon = "sentrum" 
 android: padding = "8dip" > 
 android: layout_width = "wrap_content" 
 android: layout_height = "wrap_content" 
 android: text = "Spill # 1" 
 android: id = "@ + id / fx01" /> 
 android: layout_width = "wrap_content" 
 android: layout_height = "wrap_content" 
 android: text = "Spill # 2" 
 android: id = "@ + id / fx02" /> 
 android: layout_width = "wrap_content" 
 android: layout_height = "wrap_content" 
 android: text = "Stopp alle" 
 android: id = "@ + id / stop" /> 

5. Neste trinn er å kode opp Main.java-filen i mappen / src. Vi begynner med å erklære noen få variabler på klassetrinn og definere et par konstanter.

 Main.java 
 pakke com.authorwjf.soundfx; 
 importer java.util.HashMap; 
 import android.app.Aktivitet; 
 import android.content.Context; 
 import android.media.AudioManager; 
 import android.media.SoundPool; 
 import android.os.Bundle; 
 import android.view.View; 
 import android.view.View.OnClickListener; 
 import android.widget.Button; 
 public class Main utvider aktivitetsredskaper OnClickListener { 
 privat SoundPool mSoundPool; 
 privat AudioManager mAudioManager; 
 privat HashMap mSoundPoolMap; 
 privat int mStream1 = 0; 
 privat int mStream2 = 0; 
 endelig statisk int LOOP_1_TIME = 0; 
 endelig statisk int LOOP_3_TIMES = 2; 
 endelig statisk int SOUND_FX_01 = 1; 
 endelig statisk int SOUND_FX_02 = 2; 
 } 

6. Det er på tide å legge til vår on create overstyring. Vi må initialisere lydbassenget, laste inn lydklippene i minnet og koble opp knappene. Sørg for å undersøke konstruktøren for lydbassenget. Den første parameteren er spesielt antall samtidige strømmer lydbassenget ditt kan spille av. Siden jeg bare har to lydklipp, har jeg gitt to i form av demoen vår.

 Main.java 
 @Overstyring 
 public void onCreate (Bundle savedInstanceState) { 
 super .onCreate (savedInstanceState); 
 setContentView (R.layout. main ); 
 // sette opp lydspilleren vår 
 mSoundPool = ny SoundPool (2, AudioManager . STREAM_MUSIC, 0); 
 mAudioManager = (AudioManager) getSystemService (Kontekst. AUDIO_SERVICE ); 
 mSoundPoolMap = ny HashMap (); 
 // last fx 
 mSoundPoolMap.put ( SOUND_FX_01, mSoundPool.load ( dette, R.raw. set_trap, 1)); 
 mSoundPoolMap.put ( SOUND_FX_02, mSoundPool.load ( dette, R.raw. spring_trap, 1)); 
 // trådknapper 
 Knapp b = (Knapp) findViewById (R.id. Fx01 ); 
 b.setOnClickListener ( dette ); 
 b = (Knapp) findViewById (R.id. fx02 ); 
 b.setOnClickListener ( dette ); 
 b = (Knapp) findViewById (R.id. stopp ); 
 b.setOnClickListener ( dette ); 
 } 

7. Vi må skrive vår klikkbehandler. Når du spiller en lyd, må du stille inn volumet mellom 0, 0f til 0, 99f. Det er lite sannsynlig at brukeren din vil sette pris på at du bare sprenger lyden FX på fullt volum hvis de allerede har skrudd ned medievolumet på enheten. Så hvis du tar en titt på den første delen av onClick-overstyringen min, vil du se et lite triks som fungerer fint for å sette opp riktig volumnivå. To andre bemerkelsesverdige elementer er loopparameteren for spillmetoden, som er n - 1 (ikke n) og stoppmetoden, som bruker håndtaket til en tidligere åpnet strøm og ikke hasjindeksen.

 Main.java 
 @Overstyring 
 public void onClick (Vis v) { 
 float streamVolume = mAudioManager.getStreamVolume ( AudioManager . STREAM_MUSIC ); 
 streamVolume = streamVolume / mAudioManager.getStreamMaxVolume ( AudioManager . STREAM_MUSIC ); 
 bytte (v.getId ()) { 
 sak R.id. fx01 : 
 mSoundPool.stop (mStream1); 
 mStream1 = mSoundPool.play (mSoundPoolMap.get ( SOUND_FX_01 ), streamVolume, streamVolume, 1, LOOP_1_TIME, 1f); 
 pause ; 
 sak R.id. fx02 : 
 mSoundPool.stop (mStream2); 
 mStream2 = mSoundPool.play (mSoundPoolMap.get ( SOUND_FX_02 ), streamVolume, streamVolume, 1, LOOP_3_TIMES, 1f); 
 pause ; 
 sak R.id. stopp : 
 mSoundPool.stop (mStream1); 
 mSoundPool.stop (mStream2); 
 pause ; 
 } 
 } 

Det er det. Skru opp høyttalerne og ta dem med på en prøvekjøring. Som det ofte er tilfelle med Android SDK, har SoundPool sine oppgaver. Imidlertid, hvis du holder deg med OGG-filer, er klar over volumet og holder klippene under noen sekunder, tror jeg at du vil finne klassen ganske nyttig. Og enda viktigere, du blir ikke beskyldt for å ha skrevet en "gammel mann" -app!

Figur A

© Copyright 2021 | pepebotifarra.com