当我尝试生成第22次未初始化的语气异常AudioTrack [英] uninitialized AudioTrack exception when I try to generate tone on 22nd time
问题描述
我有我需要显示拨号盘屏幕一样的要求,我不得不产生1kHz的音(DTMF未音)每当在拨号盘按钮,用户presses。
I have a requirement that I need to display a dial pad like screen and I have to generate 1khz tone (not DTMF tone) whenever user presses on a dial pad buttons.
我已经使用了code从下面的链接,产生1 kHz音调:
I have used the code from the below link to generate 1 khz tone:
播放与Android 的任意音
当我在我的拨号盘屏幕上开始拨号键,直到21 presses它成功生成基调,但22日尝试之后我得到应用无响应(ANR)错误,我需要关闭应用程序。
When I started dialing buttons on my dialpad screen till 21 presses it is successfully generating tone but after 22nd attempt I am getting Application Not Responding (ANR) error and I need to close the app.
下面是我的code:
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()方法将在每次当我美元的拨号盘p $ PSS按键时调用。
onClick() method will be called each time when I press buttons on the dialpad.
上述code,我在LogCat中得到这样的输出:
with the above code I am getting this output in 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)。不知道为什么,状态得到改变。
I am printing the state of the "audioTrack" till 21th time I am getting value 1 (STATE_INITIALIZED) after that I am getting value '0' (STATE_UNINITIALIZED). Dont know why state is getting changed.
请帮我什么,我需要做的prevent这个力的确定关闭问题在我的应用程序的变化。
或请建议,如果有任何替代做到这一点。
Please help me what are the changes I need to do prevent this froce close issue in my app. or Please suggest if there's any alternative to do this.
推荐答案
关于21成功生成色调的数量和接下来的失败,我认为你必须释放previously创建的实例调用 audioTrack .release()
方法。
为了避免在 IllegalStateException异常
:
创建后 AudioTrack
的一个实例,你必须测试它是否很好初始化。
使用 MODE_STATIC
模式下,如果它不能正常初始化,国家将: STATE_UNINITIALIZED
,
相反,如果正确初始化: STATE_NO_STATIC_DATA
,当你调用write方法的状态将被更改为 STATE_INITIALIZED
使用 MODE_STREAM
模式下,如果它不能正常初始化,国家将: STATE_UNINITIALIZED
,
相反,如果正确初始化: STATE_INITIALIZED
。
结果
阅读 AudioTrack
来源我看到。我想是因为通过构造函数返回的对象是无法使用,因为它是不可能建设后,初始化,这是很奇怪的。
About the number of 21 successfully generated tones and next fails, I think you have to free the previously created instances invoking audioTrack.release()
method.
In order to avoid the IllegalStateException
:
After created an instance of AudioTrack
you have to test if it is well initialized.
Using MODE_STATIC
mode, if it does not correctly initialize, the state will be: STATE_UNINITIALIZED
,
instead, if correctly initialized: STATE_NO_STATIC_DATA
, when you invoke write method the state will be changed to STATE_INITIALIZED
.
Using MODE_STREAM
mode, if it does not correctly initialize, the state will be: STATE_UNINITIALIZED
,
instead, if correctly initialized: STATE_INITIALIZED
.
Reading on source of AudioTrack
I seen that. I think this is very strange because the object returned by constructor is not usable because it is not possible to initialize after construction.
这篇关于当我尝试生成第22次未初始化的语气异常AudioTrack的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!