AudioTrack:在未初始化的 AudioTrack 上调用 play()
Posted
技术标签:
【中文标题】AudioTrack:在未初始化的 AudioTrack 上调用 play()【英文标题】:AudioTrack: play() called on uninitialized AudioTrack 【发布时间】:2012-07-02 18:13:11 【问题描述】:我正在尝试使用 AudioTrack 类。基本上,当用户触摸屏幕上的特定对象时,我的应用程序必须产生声音。我使用this example 作为指导。 我的应用程序似乎可以正常工作,但通常在触摸屏幕大约一分钟后它会崩溃:
07-02 20:40:53.459: E/androidRuntime(11973): FATAL EXCEPTION: Thread-10
07-02 20:40:53.459: E/AndroidRuntime(11973): java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
07-02 20:40:53.459: E/AndroidRuntime(11973): at android.media.AudioTrack.play(AudioTrack.java:824)
07-02 20:40:53.459: E/AndroidRuntime(11973): at com.mysounds_experimental.SoundThread.playSound(SoundThread.java:108)
07-02 20:40:53.459: E/AndroidRuntime(11973): at com.mysounds_experimental.SoundThread.run(SoundThread.java:69)
类中产生声音的方法
public void initAudioTrack()
int bufferSize = 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
, bufferSize
, AudioTrack.MODE_STREAM);
private void playSound()
audioTrack.write(generatedSnd, 0, numSamples);
audioTrack.play();
public void stopPlaying()
audioTrack.flush();
audioTrack.stop();
audioTrack.release();
@Override
public void run()
while (mRun)
try
Thread.sleep(200);
while(soundCycle)
if(freqOfTone != -1f)
generateTone();
playSound();
Thread.sleep(200);
catch(InterruptedException e)
// soundCycle = false;
// soundPool.stop(BEEP);
这是我的线程使用的自定义视图中的一种方法
@Override
public boolean onTouchEvent(final MotionEvent ev)
int currentXPosition = (int) ev.getX();
int currentYPosition = (int) ev.getY();
if(ev.getX() < smBitmap.getWidth())
if(ev.getY() < smBitmap.getHeight())
tempCol = smBitmap.getPixel(currentXPosition, currentYPosition);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK)
case MotionEvent.ACTION_DOWN:
sThread.freqOfTone = getFreqPreset(tempCol);
if(col != tempCol)
// sThread.initAudioTrack();
sThread.interrupt();
if(shouldInit)
shouldInit = false;
sThread.initAudioTrack();
sThread.soundCycle = true;
col = tempCol;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
sThread.freqOfTone = getFreqPreset(tempCol);
if (tempCol == -1 || tempCol == 0)
sThread.soundCycle = false;
shouldInit = true;
// sThread.stopPlaying();
sThread.interrupt();
invalidate();
else
if(col != tempCol)
sThread.interrupt();
col = tempCol;
invalidate();
else
sThread.soundCycle = true;
col = tempCol;
invalidate();
break;
// case ACTION_MOVE
case MotionEvent.ACTION_UP:
sThread.soundCycle = false;
shouldInit = true;
// sThread.stopPlaying();
sThread.interrupt();
col = -1;
mActivePointerId = INVALID_POINTER_ID;
break;
// case ACTION_UP
return true;
任何想法为什么会发生这种情况?
【问题讨论】:
// sThread.initAudioTrack();
取消注释
对不起,我的意思是取消注释。
你成功移除这个异常了吗??你是怎么做到的。我遇到了同样的错误。
【参考方案1】:
为什么你注释掉了你的 stopPlaying() 方法?
您只能创建 32 个音轨。如果你想要更多,你应该调用 release() 方法。
【讨论】:
【参考方案2】:我认为您需要先致电play()
,然后再致电write()
。
但我也注意到,当您创建大量 AudioTrack
实例时,即使您认为自己正在清理所有内容,有时 play()
也无法工作,并且轨道未初始化。
您会想尝试...捕获这个IllegalStateException
,并避免调用write()
,直到play()
正常工作而不会引发异常。
【讨论】:
以上是关于AudioTrack:在未初始化的 AudioTrack 上调用 play()的主要内容,如果未能解决你的问题,请参考以下文章