2012-06-22 2 views
0

화면의 일련의 단추를 누를 때 음표를 재생하는 응용 프로그램을 만듭니다. 또한 눌렀을 때 일련의 음표 (최대 10 개의 음표)를 재생하는 버튼이 있습니다. 응용 프로그램이 처음에는 잘 작동합니다. 그러나 재생할 일련의 음표가 있고 재생 버튼을 여러 번 눌러도 응용 프로그램이 결국 강제 종료됩니다. 어떤 도움이라도 대단히 감사하겠습니다.일련의 소리를 재생하면 강제로 닫힘

private final int duration = 1; // seconds 
private final int sampleRate = 10000; 
private final int numSamples = duration * sampleRate; 
private final double sample[] = new double[numSamples]; 
private double freqOfTone; // hz 

private final byte generatedSnd[] = new byte[2 * numSamples]; 

public void onPlayButtonClick(View v){ 
    playMultiNoteSound(); 
} 
synchronized void playMultiNoteSound(){ 

    CharSequence chrs1; 
    TextView lblNoteList; 
    lblNoteList=(TextView)findViewById(R.id.lblNoteList); 
    chrs1=lblNoteList.getText(); 

    for(int i=0;i<chrs1.length();i++){ 
     final int int1=i; 

     Thread thrdPlay=new Thread(new Runnable(){ 

      public void run(){ 
       int minSize =AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); 
       audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
         sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, minSize, 
         AudioTrack.MODE_STREAM); 
       char chrCurrent; 
       CharSequence chrs; 


       TextView lblNoteList; 
       lblNoteList=(TextView)findViewById(R.id.lblNoteList); 
       chrs=lblNoteList.getText(); 
       chrCurrent=chrs.charAt(int1); 
       Double[]allTones; 
       allTones= new Double[chrs.length()]; 
       allTones[int1]=getToneForText(chrCurrent); 
       byte[] results; 
       results=genSelectTone(allTones[int1]); 
       audioTrack.write(results, 0, results.length); 
       audioTrack.setStereoVolume(1.0f, 1.0f); 
       audioTrack.play(); 
       if(audioTrack.getPlayState()==AudioTrack.PLAYSTATE_STOPPED){ 
        audioTrack.stop(); 
        audioTrack.release(); 
       } 
      } 
     }); 
     thrdPlay.setDaemon(true); 
     thrdPlay.start(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if(thrdPlay!=null){ 
      thrdPlay.stop(); 
      thrdPlay=null; 
     } 
     } 

} 
public double getToneForText(char val){ 
    Float dblResult; 
    dblResult=0f; 
    switch (val){ 
    case '1': 
     dblResult=261.63f; 
     break; 
    case '2': 
     dblResult=293.66f; 
     break; 
    case '3': 
     dblResult=329.63f; 
     break; 
    case '4': 
     dblResult=349.23f; 
     break; 
    case '5': 
     dblResult=392.0f; 
     break; 
    case '6': 
     dblResult=440.0f; 
     break; 
    case '7': 
     dblResult=493.88f; 
     break; 
    case '8': 
     dblResult=523.25f; 
     break; 
    case '9': 
     dblResult=587.33f; 
     break; 
    case '0': 
     dblResult=659.26f; 
     break; 
    }  
    return dblResult; 
} 

나는 그것이 모두 관련 코드라고 생각합니다. 추가 정보/코드가 필요한 경우 알려주십시오.

+1

강제 종료가 발생하면 예외의 스택 추적이 발생합니다. logcat 출력을 게시하십시오. – Squonk

+1

@Squonk이 제안한 것과는 별도로 (당신이해야하는), 당신은 logcat을 읽는 방법을 찾는 것을 고려해 볼 수도 있습니다. 앱이 '예외'를 ​​던질 때마다 새로운 질문을하지 않아도됩니다. – adneal

+0

저는 LogCat을 사용했다고 언급하지 않았습니다. 오류는 다음과 같습니다. obtainBuffer 트랙을 사용 불가능하게하고 다시 시작합니다. – user1458354

답변

0

매 반복마다 audioTrack을 다시 초기화하면 안됩니다. 대신 루프 전에 초기화하고 audioTrack.write 루프를 사용하십시오. 버퍼를 채우지 않고 다시 초기화하는 것입니다.

두 번째로, 제안 사항과 같이 동일한 스레드에서 GUI를 업데이트하고 사운드를 재생해서는 안됩니다. 대신 AsyncTask을 사용해보십시오.

관련 문제