2011-11-20 97 views
2

我在播放声音的开始和结束处(从SD卡开始播放wav)获得点击。它必须是跟踪缓冲区,但我不知道解决方案。另外,每当声音播放时我都会创建一个新的,这是好的还是有更好的方法?有很多声音播放一遍又一遍。下面是代码:Android AudioTrack在开始和结束声音时点击

public void PlayAudioTrack(final String filePath, final Float f) throws IOException 
    { 

    new Thread(new Runnable() { public void run() { 
      //play sound here 
     int minSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT);   
      AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
      AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, 
      minSize, AudioTrack.MODE_STREAM); 

     track.setPlaybackRate((int) (44100*f)); 

    if (filePath==null) 
    return; 

    int count = 512 * 1024; 
    //Read the file.. 
    byte[] byteData = null; 
    File file = null; 
    file = new File(filePath); 

    byteData = new byte[(int)count]; 
    FileInputStream in = null; 
    try { 
    in = new FileInputStream(file); 

    } catch (FileNotFoundException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 

    int bytesread = 0, ret = 0; 
    int size = (int) file.length(); 

    while (bytesread < size) { 
    try { 
     ret = in.read(byteData,0, count); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    track.play(); 
    if (ret != -1) { 
    // Write the byte array to the track 
    track.write(byteData,0, ret); bytesread += ret; 
    } 
    else break; } 

    try { 
     in.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } track.stop(); track.release(); 
    } 

     }).start(); 
     } 

非常感谢所有帮助

+0

我的音频体验不在Android上,但在写入任何字节之前调用track.play()似乎很奇怪。你不应该先写字节吗? – AShelly

+0

不,你需要用play()打开audiotrack然后写入它,因为它的mode_streaming。我认为它可能不会阅读wav标题的权利或某事。 – user1033558

+0

wtf你认为你在做ChrisWue吗?编辑随机帖子获得徽章对任何人都不是很有帮助吗?你至少可以试着回答...... – user1033558

回答

1

我在使用AudioTrack每个轨道的开始有这些相同的点击。我通过关闭音轨音量,等待半秒钟,然后恢复正常音量来解决这个问题。我不再有任何点击。这是代码的相关位。

at.play(); 
    at.setStereoVolume (0.0f, 0.0f); 

    new Thread (new Runnable(){ 
     public void run() { 
      try{ 
       Thread.sleep(500); 
      } catch (InterruptedException ie) { ; } 
      at.setStereoVolume (1.0f, 1.0f); 
     } 
    }).start(); 

    new Thread (new Runnable(){ 
     public void run() { 
      int i = 0; 
      try{ 
       buffer = new byte[512]; 
       while(((i = is.read(buffer)) != -1) && !paused){ 
        at.write(buffer, 0, i); 
        position += i; 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      if (!paused){ 
       parent.trackEnded(); 
      } 
     } 
    }).start(); 
} 
3

您是否也可能播放PCM波形文件标题?

每个PCM波形文件在文件的开头都有一个小标题,如果播放该文件,则播放标题字节,这可能会导致点击开始。

+1

事实上,这些44个字节的WAVE-header听起来像是一个点击,如果播放。当AT开始播放这样的文件时,解决方案是跳过44个字节。 – Stan