2011-10-01 30 views
5

Tôi đang làm việc trên một chương trình Android cần lặp lại các tệp âm thanh với thời gian chính xác (chương trình âm nhạc).AudioTrack sẽ chỉ phát âm thanh một lần

Tôi đang sử dụng "AudioTrack" ngay bây giờ có dữ liệu PCM được tải từ một mẫu WAV.

đây là mã im thử nghiệm tính năng này. nó chỉ lặp lại cho đến lúc chơi mẫu, sau đó phát nó và lặp lại 8 lần này.

Đây là mã mà tôi đang sử dụng, cho tôi biết nếu bạn cần để xem chi tiết:

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; 
     } 
    } 

} 

Nó đóng một cách hoàn hảo vào ngày đầu tiên trong tám vòng, nhưng sau đó có chỉ là sự im lặng, không có có thể nhìn thấy lỗi hoặc cảnh báo. (mặc dù tiểu bang sẽ vẫn ở mức 1 là "STATE_INITIALIZED" có nghĩa là "Trạng thái của AudioTrack sẵn sàng để sử dụng".

Tôi biết rằng AudioTrack có tính năng lặp, cũng như phương thức "reloadStaticData", nhưng khi tôi bắt đầu viết ứng dụng thực tế, tôi đang thử nghiệm điều này cho dữ liệu sẽ thay đổi mỗi lần dựa trên chuỗi được tạo bởi người dùng)

Ngoài ra, ban đầu tôi đã thử làm điều này với cả trình phát và âm thanh nhưng cả hai đều cho tôi quá nhiều thời gian chờ.

Là một thử nghiệm tôi cũng đã thử nó với re-initializing các AudioTrack hoàn toàn mỗi vòng lặp thông qua nhưng điều đó đã cho tôi quá nhiều độ trễ để được thực sự hữu ích.

Tôi xin lỗi vì mã lộn xộn, tôi thực sự hy vọng nó chỉ là một cái gì đó ngu ngốc tôi đang làm sai, như tôi đang nhận được rất thất vọng.

Cảm ơn!

thử nghiệm trên Android 2.2.2, trên một thiết bị thiết bị cầm tay (không phải mô phỏng)

Đây là sản lượng LogCat tôi:

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

Tại sao bạn lặp lại 8 lần? kiểm tra dòng này: 'for (int i = 0; i <8; i ++)' – iTurki

Trả lời

1

Có lẽ bạn nên cố gắng sử dụng chế độ streamming của AudioTrack thay vì một tĩnh .

Các vấn đề liên quan