我有一个线程,它使用AudioTrack来合成一系列音符,并使用搜索条来改变节奏。
t = new Thread()
{
public void run()
{
setPriority(Thread.MAX_PRIORITY);
int buffersize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
buffersize, AudioTrack.MODE_STREAM);
short samples[] = new short[buffersize];
int amplitude = 10000;
double twopi = 2*Math.PI;
double ph = 0.0;
audiotrack.play();
double r = 1.0594630943593; //the 12th root of 2
frequency=261.63;
for(int k = 1; k<9; k++) //number of notes played
{
frequency*=r;
for (int i = 0; i < 4+4*temposliderval; i++) //duration of each note, if i = 50, note duration = 12 seconds
{
for (int j = 0; j < buffersize; j++)
{
samples[j] = (short) (amplitude * Math.sin(ph));
ph += twopi * frequency / sr;
}
audiotrack.write(samples, 0, buffersize);
}
}
audiotrack.stop();
audiotrack.release();
}
};
//play button
play = (Button)findViewById(R.id.play);
play.setBackgroundResource(R.mipmap.play);
play.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
t.start();
}
});
//stop button
stop = (Button)findViewById(R.id.stop);
stop.setBackgroundResource(R.mipmap.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
t.interrupt();
}
});
我希望能够在按下停止按钮时停止音频。调用t.interrupt()不起作用,所以我想知道当按下停止按钮时如何正确地停止线程目标是能够随时停止音频,并在再次按下播放按钮时重新启动。
最简单的方法可能是声明一个volatile
成员变量:
private volatile boolean mStop = false;
两个线程都可以访问的。您可以在线程的内部循环中轮询变量,并在设置后停止循环,并在按下按钮时将变量设置为true。
我想通了!这个方法似乎没有在其他地方列出,所以我一定很幸运:
只需将线程放入一个新方法中,并在点击播放按钮时调用该方法,而不是尝试停止线程,只需停止音轨的音频:
play = (Button)findViewById(R.id.play);
play.setBackgroundResource(R.mipmap.play);
play.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
playScale();
}
});
//stop button
stop = (Button)findViewById(R.id.stop);
stop.setBackgroundResource(R.mipmap.stop);
stop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
audiotrack.stop();
}
});
现在,每次按下播放按钮,线程都会简单地重新启动,尽管实际上并没有停止。
public void playScale()
{
t = new Thread()
{
public void run()
{
t.setPriority(Thread.MAX_PRIORITY);
int buffersize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
buffersize, AudioTrack.MODE_STREAM);
short samples[] = new short[buffersize];
int amplitude = 10000;
double twopi = 2 * Math.PI;
double ph = 0.0;
audiotrack.play();
double r = 1.0594630943593; //the 12th root of 2
frequency = 261.63;
for (int k = 1; k < 9; k++) //number of notes played
{
frequency *= r;
for (int i = 0; i < 4 + 4 * temposliderval; i++) //duration of each note, if i = 50, note duration = 12 seconds; minimum tempo = 60 bpm
{
for (int j = 0; j < buffersize; j++)
{
samples[j] = (short) (amplitude * Math.sin(ph));
ph += twopi * frequency / sr;
}
audiotrack.write(samples, 0, buffersize);
}
}
}
};
t.start();
}