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

関連するコードはこれですべてだと思います。追加情報/コードが必要な場合はお知らせください。

4

1 に答える 1

0

audioTrack反復ごとに再初期化しないでください。代わりに、ループの前に初期化し、ループで使用audioTrack.writeします。バッファをいっぱいにすることなく、単に再初期化しています。

第二に、オファーと同じように、GUI を更新して同じスレッドでサウンドを再生するべきではありません。AsyncTask代わりに使用してみてください。

于 2013-02-25T19:12:51.957 に答える