2013-07-22 3 views
1

PCM 사운드 데이터 (예 : 음악 트랙)를 처리하기 위해 Android 앱을 구현하고 있습니다. AudioTrack 클래스를 사용하여 음악을 재생하기로 결정했지만 전체 응용 프로그램을 차단하고 있기 때문에 활동과 동일한 스레드에 배치 할 수 없습니다. 여기에 질문이 있습니다. AudioTrack 작업을 별도의 스레드에 넣어야합니까? 또는 비동기 작업 (또는 다른 옵션)에서? 가장 좋은 방법은 무엇일까요? 음악 파일을 재생/일시 중지/정지 및 변경해야합니다.안드로이드를 사용하는 가장 좋은 방법 Audiotrack

지금 자바 스레드로 관리하려고하고 거의 괜찮아요. (소리의 일부를 "떨어 뜨리는") 거의 일시 중지되었지만 음악 파일을 변경할 때 이전 중지 및 theres 혼합 된 출력 theres (내 thread 구현에 뭔가 잘못된 생각).

아니요,이 앱에서 MediaPlayer를 사용할 수 없습니다 (즉석에서 PCM 데이터를 수정하고 싶습니다).

구글과 여기 stackoverflow에 대한 도움을 찾고 있었지만 아무런 도움이되지 않았습니다.

누군가 내 모습을보고 싶다면 다음은 현재 구현 한 것입니다.

public class AudioPlayerManager { 

private AudioTrack track; 
private Thread thread; 
private AudioTrackThread trackThread = new AudioTrackThread(); 

public int getPlayState() { 
    return track.getPlayState(); 
} 

public int getAudioSession() { 
    return track.getAudioSessionId(); 
} 

class AudioTrackThread implements Runnable { 
    private String filePath = "/music/wav/musicfile.wav"; 

    @Override 
    public void run() { 
     try { 
      playWaveFile(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void playWaveFile() throws FileNotFoundException {  
     int minSize = AudioTrack.getMinBufferSize(44100, 
       AudioFormat.CHANNEL_OUT_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT); 
     track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
       AudioFormat.CHANNEL_OUT_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT, minSize, 
       AudioTrack.MODE_STREAM); 

     File file = new File(FileListingUtils.getExternalStorageRootFile(), 
       filePath); 
     InputStream is = new FileInputStream(file); 

     byte[] music = new byte[512]; 
     track.play(); 

     try { 
      handleSound(is, music); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     track.stop(); 
     track.release(); 
    } 

    private void handleSound(InputStream is, byte[] music) 
      throws IOException { 
     int i; 
     while ((i = is.read(music)) != -1) { 
      track.write(music, 0, i); 
     } 
    } 
} 

public void playNew() { 
    if (track != null) { 
     track.stop(); 
     //track.flush(); 
     track.release(); 
    } 

    thread = new Thread(trackThread); 
    thread.start(); 
} 

public void playOrResume() { 
    this.track.play(); 
} 

public void pause() { 
    this.track.pause(); 
} 

} 모든 도움을

감사합니다!

M.

답변

1

스레드 수명주기가 올바르지 않습니다. 먼저 재생이 중지되거나 완료 될 때마다 현재 스레드를 닫고 (인터럽트) 스레드의 새 인스턴스를 만들고 이전 스레드를 닫아야합니다.

두 번째로 스레드 외부에서 track.stop()으로 전화를 걸고 있습니다. 스레드 내에서 public stop 메소드를 구현 한 다음 finalization 코드를 삽입 한 다음 playNew() 메소드에서 yourthread.stop()을 호출해야합니다. 어딘가에 내가 음악 서비스를 재생하는 것을 읽고 스레드가 android documentation에서 서비스 및 스레드에 대한 더 나은 option.Read 될 것입니다, 당신의 구현에 대한

public void playNew() { 

//the following if clause should go to thread's stop() method. 
    // if (track != null) { 
    // track.stop(); 
//track.flush(); 
// track.release(); 
// } 
    //create a new thread if its null 
if(thread ==null){ 
thread = new Thread(new AudioTrackThread()); 
thread.start();} 
//stop the current thread 
else{ 
thread.stop(); 
thread=null;} 
} 

: 그래서 여기

은 의사입니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 불행히도 효과는 같습니다. 구현을 조금 변경했는데 다음 트랙을로드하는 것 외에는 모든 것이 잘 작동합니다. 그러나 나는 앞으로 그 문제로 돌아갈 것이다. 감사합니다. – Michal

+0

당신은 오신 것을 환영합니다. 다른 사람들에게 도움이되는 답을 게시 해주십시오. –

+1

답변은 어디에 있습니까? –