我有一个带有AudioTrack的线程,我想在按钮DOWN上调用,在按钮UP上我想停止音频。到目前为止,一切都很好。我的应用程序具有活动A和活动B。活动A是我从中启动活动B的某个菜单,活动B是我称为AudioTrack的主要活动,依此类推。问题是,一切正常,直到我第三次参加活动B,然后这才发生。
E/AudioTrack: AudioFlinger could not create track, status: -12
E/AudioTrack-JNI: Error -12 initializing AudioTrack
E/android.media.AudioTrack: Error code -20 when initializing AudioTrack.
java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
对于第1次和第2次,我什至不必调用播放,只需输入活动B,但是当我想第3次调用播放时,就会发生此错误。为什么?
Activity B playTune(){
if(tuneThread == null){
tuneThread = new startSI();
// tuneThread.setTuneFreq(tuneFreq);
tuneThread.start();
}
return this;
}
void setTuneFreq(double tuneFreq) {
this.tuneFreq = tuneFreq;
if(tuneThread != null){
tuneThread.setTuneFreq(tuneFreq);
}
}
void stopTune(){
if(tuneThread != null){
tuneThread.stopTune();
tuneThread = null;
}
}
protected void onPause() {
stopTune();
super.onPause();
}
protected void onStop() {
stopTune();
super.onStop();
这就是我调用和/或停止线程的方式
setTuneFreq(double);
我之所以调用OnSenzorChanged(事件监听器),是因为我需要基于陀螺仪数据的频率。
playTune();
在按下按钮之后,在ACTION_DOWN之后我在OnTouchListener中调用,并且只要按下它,AudioTrack就会生成信号(直到ACTION_UP),然后我调用
stopTune();
public class startSI extends Thread {
private boolean isRunning;
private double tuneFreqSI;
private int sr = 44100;
private int sibuffsize = AudioTrack.getMinBufferSize(sr,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
private AudioTrack siaudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, sibuffsize,
AudioTrack.MODE_STREAM);
@Override
public void run() {
super.run();
isRunning = true;
short samples[] = new short[sibuffsize];
int amp = 32767;
double twopi = 8. * Math.atan(1.);
double ph = 0.0;
try {
siaudioTrack.play();
} catch(IllegalStateException e) {
System.out.println("error play "+e);
}
while (isRunning) {
double fr = tuneFreqSI;
double fLFO = frLFO;
for (int i = 0; i < sibuffsize; i++) {
samples[i] = (short) (amp * Math.sin(ph));
ph += twopi * fr / sr;
}
siaudioTrack.write(samples, 0, sibuffsize);
}
try {
siaudioTrack.stop();
siaudioTrack.release();
}catch(IllegalStateException e) {
System.out.println("error stop "+e);
}
}
public void setTuneFreq(double tuneFreq, double frLFO, double ampLFO) {
this.tuneFreqSI = tuneFreq;
this.frLFO = frLFO;
this.ampLFO = ampLFO;
}
public void stopTune() {
isRunning = false;
try {
this.join();
this.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我在做什么错了?
答案 0 :(得分:-1)
我认为,您的音频轨道同时已被垃圾收集器破坏。因此,我建议您使用此行在run()方法开始时重新初始化siaudioTrack。
this.siaudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, sibuffsize, AudioTrack.MODE_STREAM);