2011-10-01 18 views
5

Estoy trabajando en un programa de Android que necesita reproducir archivos de audio repetidamente con un tiempo muy exacto (programa de música).AudioTrack solo reproducirá audio una vez

Estoy usando un "AudioTrack" en este momento que tiene los datos PCM cargados desde una muestra WAV.

aquí está el código con el que estoy probando esta característica. simplemente gira hasta que es hora de reproducir la muestra, luego la reproduce y repite esto 8 veces.

Aquí está el código que estoy usando, hágamelo saber si usted necesita ver más:

class Sequencer { 
    private final double BPM = 120; 
    private final double BPMS = (BPM/60/1000); 
    private long QUARTER_NOTE_DELAY = (long)(1/BPMS); 

    private final int PCM_BYTE_OFFSET = 44; 

    private long lastTick; 
    private long now = 0; 

    private int sampleRate = 8000; 
    private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_STEREO; 
    private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 
    private int bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat)*5; 

    private AudioTrack playbackBuffer = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate, 
      channelConfig,audioFormat,bufferSize,AudioTrack.MODE_STATIC);; 

    private byte[] pcmArray; 

    public Sequencer() 
    { 
     Log.d("AudioTrack", "BUFFER SIZE: " +bufferSize); 

     String path = "samples/classical_guitar_c5_16bit.wav"; 
     try { 
      pcmArray = parsePCMData(path); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.e("Error Initializng Sequencer", "File not Found: " + path); 
      e.printStackTrace(); 
     } 


    } 

    public void play() { 
     new Thread() { 
      public void run() { 

       lastTick = 0; 
       // play 10 times 
       Log.d("Sequencer", "QUARTER-NOTE = " + QUARTER_NOTE_DELAY + "ms"); 
       for (int i = 0; i < 8; i++) 
       { 
        lastTick = System.currentTimeMillis(); 
        while (!update(i)); 
       } 

       playbackBuffer.flush(); 

      } 
     }.start(); 

    } 

    public void stop() { 

    } 

    //load PCM data into the buffer 
    private void loadPCMData(byte[] pcmData) 
    { 
     int numBytesWritten = playbackBuffer.write(pcmData, PCM_BYTE_OFFSET, (pcmData.length-PCM_BYTE_OFFSET)); 
     Log.d("AudioTrack", "LOADED " + numBytesWritten + " BYTES" + " IN " + (System.currentTimeMillis()- now) + "ms!"); 
    } 

    private byte[] parsePCMData(String path) throws IOException 
    { 
     InputStream fileIn = assetManager.open(path); 
     BufferedInputStream buffIn = new BufferedInputStream(fileIn, 8000); 
     DataInputStream dataIn = new DataInputStream(buffIn); 
     byte[] pcmArray; 
     ArrayList<Byte> pcmVector = new ArrayList<Byte>(); 
     int numBytes; 

     //Read the file into the "music" array 
     for(int i=0; dataIn.available() > 0; i++) 
     { 
      pcmVector.add(dataIn.readByte()); 
     } 
     //Close the input streams 
     dataIn.close();               
     buffIn.close(); 
     fileIn.close(); 
     numBytes = pcmVector.size(); 
     pcmArray = new byte[numBytes]; 

     //Copy the data from the arrayLast to the byte array 
     for(int i=0; i<numBytes; i++) 
     { 
      pcmArray[i] = (Byte) pcmVector.get(i); 
     } 

     return pcmArray; 
    } 

    //Start Playback of PCM data 
    private void startPlayback() 
    { 
     //stop playback 
     if(playbackBuffer.getState() != AudioTrack.STATE_NO_STATIC_DATA) 
     { 
      playbackBuffer.stop(); 
      playbackBuffer.flush(); 
     } 

     //start loading the next batch of sounds 
     loadPCMData(pcmArray); 

     //reset head position 
     playbackBuffer.setPlaybackHeadPosition(0); 
     //playbacksounds 
     playbackBuffer.play(); 
    } 

    private boolean update(int i) { 

     now = System.currentTimeMillis(); 

     if (now - lastTick >= QUARTER_NOTE_DELAY) { 
      //start Sounds 
      Log.d("AudioTrack: ", "Starting Playback. Current State: " + Integer.toString(playbackBuffer.getState())); 
      startPlayback(); 
      Log.d("AudioTrack: ", "Playback Started. Current State: " + Integer.toString(playbackBuffer.getState())); 
      Log.d("MainMenu.java: ", "Event Triggered after " + Long.toString(now-lastTick) +"ms"); 
      lastTick = now; 
      //update UI in a seperate thread 
      beatCounter.post(updateUI); 
      return true; 
     } 

     else{ 
      return false; 
     } 
    } 

} 

Se juega perfectamente en el primero de los ocho bucles, pero después de eso sólo hay silencio, sin errores o advertencias visibles. (aunque el estado permanecerá en 1, que es "STATE_INITIALIZED" que significa "Estado de un AudioTrack que está listo para usarse".

Soy consciente de que AudioTrack tiene una función de bucle, así como el método "reloadStaticData", pero cuando comienzo a escribir la aplicación real, estoy probando esto para que los datos cambien cada vez según una secuencia generada por el usuario)

Además, inicialmente intenté hacer esto tanto con mediaplayer como con soundpool, pero ambos me dieron demasiada latencia

Como prueba también lo intenté con la reinicialización del AudioTrack completamente en cada ciclo, pero eso me dio demasiada latencia para ser realmente útil.

Me disculpo por el código desordenado, realmente espero que sea algo estúpido que estoy haciendo mal, ya que me estoy frustrando mucho.

Gracias!

prueba en Android 2.2.2, en un dispositivo terminal inalámbrico (no emulado)

Aquí está mi salida LogCat:

10-01 05:07:22.016: DEBUG/AndroidRuntime(23316): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 
10-01 05:07:22.016: DEBUG/AndroidRuntime(23316): CheckJNI is OFF 
10-01 05:07:22.016: DEBUG/dalvikvm(23316): creating instr width table 
10-01 05:07:22.094: DEBUG/AndroidRuntime(23316): --- registering native functions --- 
10-01 05:07:22.461: DEBUG/dalvikvm(22329): GC_EXPLICIT freed 236 objects/13984 bytes in 39ms 
10-01 05:07:23.547: DEBUG/PackageParser(1089): Scanning package: /data/app/vmdl67886.tmp 
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): wakeWhenReadyLocked(26) 
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): handleWakeWhenReady(26) 
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000) 
10-01 05:07:23.680: INFO/power(1089): *** set_screen_state 1 
10-01 05:07:23.696: DEBUG/Sensors(1089): using sensors (name=sensors) 
10-01 05:07:24.088: INFO/PackageManager(1089): Removing non-system package:com.android.test 
10-01 05:07:24.088: INFO/Process(1089): Sending signal. PID: 23293 SIG: 9 
10-01 05:07:24.088: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081 
10-01 05:07:24.102: INFO/WindowManager(1089): WIN DEATH: Window{44b41118 com.android.test/com.android.test.MainMenu paused=false} 
10-01 05:07:24.118: INFO/UsageStats(1089): Unexpected resume of com.android.launcher while already resumed in com.android.test 
10-01 05:07:24.196: DEBUG/SurfaceFlinger(1089): Screen about to return, flinger = 0x120f38 
10-01 05:07:24.446: DEBUG/PackageManager(1089): Scanning package com.android.test 
10-01 05:07:24.446: INFO/PackageManager(1089): Package com.android.test codePath changed from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk; Retaining data and using new 
10-01 05:07:24.453: INFO/PackageManager(1089): /data/app/com.android.test-1.apk changed; unpacking 
10-01 05:07:24.453: DEBUG/installd(1012): DexInv: --- BEGIN '/data/app/com.android.test-1.apk' --- 
10-01 05:07:24.602: DEBUG/dalvikvm(23325): creating instr width table 
10-01 05:07:24.641: DEBUG/dalvikvm(23325): DexOpt: load 11ms, verify 23ms, opt 0ms 
10-01 05:07:24.649: DEBUG/installd(1012): DexInv: --- END '/data/app/com.android.test-1.apk' (success) --- 
10-01 05:07:24.657: DEBUG/PackageManager(1089): Activities: com.android.test.AndroidTestActivity com.android.test.MainMenu 
10-01 05:07:24.657: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081 
10-01 05:07:24.657: WARN/PackageManager(1089): Code path for pkg : com.android.test changing from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk 
10-01 05:07:24.657: WARN/PackageManager(1089): Resource path for pkg : com.android.test changing from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk 
10-01 05:07:24.829: INFO/installd(1012): move /data/dalvik-cache/[email protected]@[email protected] -> /data/dalvik-cache/[email protected]@[email protected] 
10-01 05:07:24.829: DEBUG/PackageManager(1089): New package installed in /data/app/com.android.test-1.apk 
10-01 05:07:24.868: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000) 
10-01 05:07:25.000: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000) 
10-01 05:07:25.211: WARN/InputManagerService(1089): Got RemoteException sending setActive(false) notification to pid 23293 uid 10081 
10-01 05:07:25.274: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081 
10-01 05:07:25.571: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 24967 objects/1341840 bytes in 159ms 
10-01 05:07:25.672: DEBUG/VoiceDialerReceiver(22354): onReceive Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.android.test flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) } 
10-01 05:07:25.977: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 6005 objects/330448 bytes in 141ms 
10-01 05:07:26.016: DEBUG/VoiceDialerReceiver(22354): onReceive Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.android.test flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) } 
10-01 05:07:26.250: INFO/installd(1012): unlink /data/dalvik-cache/[email protected]@[email protected] 
10-01 05:07:26.258: DEBUG/AndroidRuntime(23316): Shutting down VM 
10-01 05:07:26.266: DEBUG/dalvikvm(23316): Debugger has detached; object registry had 1 entries 
10-01 05:07:26.282: INFO/AndroidRuntime(23316): NOTE: attach of thread 'Binder Thread #3' failed 
10-01 05:07:26.680: DEBUG/AndroidRuntime(23330): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 
10-01 05:07:26.680: DEBUG/AndroidRuntime(23330): CheckJNI is OFF 
10-01 05:07:26.680: DEBUG/dalvikvm(23330): creating instr width table 
10-01 05:07:26.735: DEBUG/AndroidRuntime(23330): --- registering native functions --- 
10-01 05:07:27.047: INFO/ActivityManager(1089): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.android.test/.AndroidTestActivity } 
10-01 05:07:27.110: DEBUG/AndroidRuntime(23330): Shutting down VM 
10-01 05:07:27.110: DEBUG/dalvikvm(23330): Debugger has detached; object registry had 1 entries 
10-01 05:07:27.110: INFO/ActivityManager(1089): Start proc com.android.test for activity com.android.test/.AndroidTestActivity: pid=23337 uid=10081 gids={} 
10-01 05:07:27.125: INFO/AndroidRuntime(23330): NOTE: attach of thread 'Binder Thread #3' failed 
10-01 05:07:27.203: INFO/WindowManager(1089): Setting rotation to 1, animFlags=1 
10-01 05:07:27.227: INFO/ActivityManager(1089): Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=2 layout=34 uiMode=17 seq=554} 
10-01 05:07:27.613: INFO/ActivityManager(1089): Displayed activity com.android.test/.AndroidTestActivity: 513 ms (total 513 ms) 
10-01 05:07:27.657: WARN/IInputConnectionWrapper(17894): showStatusIcon on inactive InputConnection 
10-01 05:07:28.073: INFO/ActivityManager(1089): Starting activity: Intent { act=com.android.test.CLEARSPLASH cmp=com.android.test/.MainMenu } 
10-01 05:07:28.141: DEBUG/AudioTrack(23337): BUFFER SIZE: 14860 
10-01 05:07:28.571: INFO/ActivityManager(1089): Displayed activity com.android.test/.MainMenu: 488 ms (total 488 ms) 
10-01 05:07:29.930: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 3588 objects/165776 bytes in 182ms 
10-01 05:07:40.172: DEBUG/Sequencer(23337): QUARTER-NOTE = 500ms 
10-01 05:07:40.680: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 2 
10-01 05:07:40.680: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:40.688: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:40.688: DEBUG/MainMenu.java:(23337): Event Triggered after 502ms 
10-01 05:07:41.203: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:41.203: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:41.203: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:41.203: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:41.711: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:41.711: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:41.719: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:41.719: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:42.227: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:42.235: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:42.235: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:42.235: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:42.743: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:42.743: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:42.750: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:42.750: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:43.258: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:43.258: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:43.258: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:43.258: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:43.774: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:43.774: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms! 
10-01 05:07:43.782: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:43.782: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:44.289: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1 
10-01 05:07:44.297: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 2ms! 
10-01 05:07:44.305: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1 
10-01 05:07:44.305: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms 
10-01 05:07:44.344: DEBUG/dalvikvm(22433): GC_EXPLICIT freed 827 objects/40752 bytes in 67ms 
10-01 05:07:49.422: DEBUG/dalvikvm(20018): GC_EXPLICIT freed 596 objects/30440 bytes in 67ms 
10-01 05:07:54.563: DEBUG/dalvikvm(22329): GC_EXPLICIT freed 143 objects/10072 bytes in 80ms 
10-01 05:07:59.696: DEBUG/dalvikvm(22354): GC_EXPLICIT freed 547 objects/30048 bytes in 68ms 
10-01 05:08:09.977: DEBUG/dalvikvm(22363): GC_EXPLICIT freed 483 objects/22512 bytes in 111ms 
10-01 05:08:10.219: INFO/power(1089): *** set_screen_state 0 
10-01 05:08:10.237: DEBUG/SurfaceFlinger(1089): About to give-up screen, flinger = 0x120f38 
10-01 05:08:10.258: DEBUG/Sensors(1089): using accelerometer (name=accelerometer) 
10-01 05:08:15.430: DEBUG/StatusBar(1089): DISABLE_EXPAND: yes 
10-01 05:08:15.469: DEBUG/GoogleLoginService(16965): onBind: Intent { act=android.accounts.AccountAuthenticator cmp=com.google.android.gsf/.loginservice.GoogleLoginService } 
10-01 05:08:15.469: INFO/WindowManager(1089): Setting rotation to 0, animFlags=1 
10-01 05:08:15.493: INFO/ActivityManager(1089): Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=1 layout=34 uiMode=17 seq=555} 
10-01 05:08:15.821: DEBUG/dalvikvm(23337): GC_FOR_MALLOC freed 1766 objects/427920 bytes in 193ms 
10-01 05:08:15.899: DEBUG/AudioTrack(23337): BUFFER SIZE: 14860 
+0

¿Por qué bucle durante 8 veces? verifique esta línea: 'for (int i = 0; i <8; i ++)' – iTurki

Respuesta

1

tal vez debería tratar de usar el modo en el streaming de AudioTrack en lugar de una estática .

Cuestiones relacionadas