gpt4 book ai didi

android - 当我第 22 次尝试生成音调时出现未初始化的 AudioTrack 异常

转载 作者:太空狗 更新时间:2023-10-29 15:56:33 27 4
gpt4 key购买 nike

我有一个要求,我需要显示一个像屏幕一样的拨号盘,并且每当用户按下拨号盘按钮时我必须生成 1khz 音调(不是 DTMF 音调)。

我使用以下链接中的代码生成 1 khz 音调:

Playing an arbitrary tone with Android

当我开始在拨号盘屏幕上调用按钮直到按下 21 次时,它成功地产生了提示音,但在第 22 次尝试后我收到应用程序无响应 (ANR) 错误,我需要关闭应用程序。

下面是我的代码:

 final float duration = 0.3f; // seconds
final int sampleRate = 4000;
final int numSamples = (int)duration * sampleRate + 100;
final double sample[] = new double[numSamples];
final double freqOfTone = 1000; // hz
final byte generatedSnd[] = new byte[2 * numSamples];

final Handler handler = new Handler();


public void onClick(View v) {
// TODO Auto-generated method stub

int id = v.getId();

playSound();
}


private void playSound()
{

final Thread thread = new Thread(new Runnable() {
public void run() {
genTone();
handler.post(new Runnable() {

public void run() {
playSound1();
}
});
}
});
thread.start();


}

void playSound1(){
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, numSamples,
AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);


audioTrack.play();
}

void genTone(){
// fill out the array
for (int i = 0; i < numSamples; ++i) {
sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
}

// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
for (final double dVal : sample) {
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);

}
}

每次按下拨号盘上的按钮时都会调用 onClick() 方法。

使用上面的代码,我在 Logcat 中得到了这个输出:

05.500 E/AudioFlinger(   85): no more track names available

09-21 05:20:05.500 E/AudioTrack( 133): AudioFlinger could not create track, status: -12

09-21 05:20:05.503 E/SoundPool( 133): Error creating AudioTrack

09-21 05:20:05.535 E/AudioFlinger( 85): no more track names available

09-21 05:20:05.535 E/AudioTrack( 6080): AudioFlinger could not create track, status: -12

09-21 05:20:05.535 E/AudioTrack-JNI( 6080): Error initializing AudioTrack

09-21 05:20:05.535 E/AudioTrack-Java( 6080): [ android.media.AudioTrack ] Error code -20 when initializing AudioTrack.

09-21 05:20:05.535 D/AndroidRuntime( 6080): Shutting down VM

09-21 05:20:05.535 W/dalvikvm( 6080): threadid=1: thread exiting with uncaught exception (group=0x40015578)

09-21 05:20:05.539 E/AndroidRuntime( 6080): FATAL EXCEPTION: main

09-21 05:20:05.539 E/AndroidRuntime( 6080): java.lang.IllegalStateException: play() called on uninitialized AudioTrack.

09-21 05:20:05.539 E/AndroidRuntime( 6080): at android.media.AudioTrack.play(AudioTrack.java:824)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at com.android.dial.DialPadScreen.playSound1(DialPadScreen.java:274)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at com.android.dial.DialPadScreen$1$1.run(DialPadScreen.java:248)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at android.os.Handler.handleCallback(Handler.java:587)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at android.os.Handler.dispatchMessage(Handler.java:92)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at android.os.Looper.loop(Looper.java:123)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at android.app.ActivityThread.main(ActivityThread.java:3687)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at java.lang.reflect.Method.invokeNative(Native Method)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at java.lang.reflect.Method.invoke(Method.java:507)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)

09-21 05:20:05.539 E/AndroidRuntime( 6080): at dalvik.system.NativeStart.main(Native Method)

09-21 05:20:05.542 E/ ( 133): Dumpstate > /data/log/dumpstate_app_error

09-21 05:20:05.542 W/ActivityManager( 133): Force finishing activity com.android.dial/.DialPadScreen

我正在打印“audioTrack”的状态,直到第 21 次我得到值 1 (STATE_INITIALIZED) 之后我得到值“0”(STATE_UNINITIALIZED)。不知道为什么状态会发生变化。

请帮助我我需要做哪些更改来防止我的应用程序中出现此 froce close 问题。或者请建议是否有任何替代方法。

最佳答案

关于 21 次成功生成音调和下一次失败的次数,我认为您必须释放先前创建的调用 audioTrack.release() 方法的实例。

为了避免 IllegalStateException:
在创建了 AudioTrack 的实例之后,您必须测试它是否已正确初始化。
使用MODE_STATIC模式,如果没有正确初始化,状态会是:STATE_UNINITIALIZED,相反,如果正确初始化:STATE_NO_STATIC_DATA,当您调用 write 方法时,状态将更改为 STATE_INITIALIZED
使用MODE_STREAM模式,如果没有正确初始化,状态会是:STATE_UNINITIALIZED,相反,如果正确初始化:STATE_INITIALIZED
阅读 AudioTrack 的源代码我看到了。我觉得这很奇怪,因为构造函数返回的对象是不可用的,因为构造后无法初始化。

关于android - 当我第 22 次尝试生成音调时出现未初始化的 AudioTrack 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7497598/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com