我正在使用一个应用程序,用户可以触摸屏幕并根据他/她接触某个音调的位置进行播放。为此,我有以下代码:
@Override
public boolean onTouchEvent(MotionEvent event) {
// Calculate the frequency that should be played
final double frequency = (event.getX()/mScreenWidth)*450 + 450;
// Use a new tread as this can take a while
mThread = new Thread(new Runnable() {
public void run() {
generateTone(frequency);
mHandler.post(new Runnable() {
public void run() {
playSound();
}
});
}
});
mThread.start();
return true;
}
void generateTone(double frequency) {
// Fill out the array
for (int i = 0; i < NUM_SAMPLES; ++i) SAMPLE_ARRAY[i] = Math.sin(2 * Math.PI * i / (SAMPLE_RATE/frequency));
// Convert to 16 bit PCM sound array
// Assumes the sample buffer is normalized.
int idx = 0;
for (final double dVal : SAMPLE_ARRAY) {
// Scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// In 16 bit WAV PCM, first byte is the low order byte
GENERATE_SND[idx++] = (byte) (val & 0x00ff);
GENERATE_SND[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
void playSound(){
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, GENERATE_SND.length, AudioTrack.MODE_STATIC);
audioTrack.write(GENERATE_SND, 0, GENERATE_SND.length);
try {
audioTrack.play();
} catch(IllegalStateException exception) {
Log.d("My App", "Tried to play sound, but audio track is not ready yet");
}
}
这种方法很有效,但当用户将手指移到屏幕上时,我得到以下错误:
12-28 11:19:14.928: E/AndroidRuntime(10433): FATAL EXCEPTION: main
12-28 11:19:14.928: E/AndroidRuntime(10433): java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
12-28 11:19:14.928: E/AndroidRuntime(10433): at android.media.AudioTrack.play(AudioTrack.java:899)
12-28 11:19:14.928: E/AndroidRuntime(10433): at com.mynamespace.projectone.Main.playSound(Main.java:77)
12-28 11:19:14.928: E/AndroidRuntime(10433): at com.mynamespace.projectone.Main$1$1.run(Main.java:47)
12-28 11:19:14.928: E/AndroidRuntime(10433): at android.os.Handler.handleCallback(Handler.java:615)
12-28 11:19:14.928: E/AndroidRuntime(10433): at android.os.Handler.dispatchMessage(Handler.java:92)
12-28 11:19:14.928: E/AndroidRuntime(10433): at android.os.Looper.loop(Looper.java:137)
12-28 11:19:14.928: E/AndroidRuntime(10433): at android.app.ActivityThread.main(ActivityThread.java:4931)
12-28 11:19:14.928: E/AndroidRuntime(10433): at java.lang.reflect.Method.invokeNative(Native Method)
12-28 11:19:14.928: E/AndroidRuntime(10433): at java.lang.reflect.Method.invoke(Method.java:511)
12-28 11:19:14.928: E/AndroidRuntime(10433): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
12-28 11:19:14.928: E/AndroidRuntime(10433): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
12-28 11:19:14.928: E/AndroidRuntime(10433): at dalvik.system.NativeStart.main(Native Method)
目前我在audioTrack.play()
周围使用try / catch构造捕获此错误,因此应用程序不会崩溃。这不是解决方案,因为声音仍然停止播放并且不会重新开始。有任何想法如何解决这个问题?
答案 0 :(得分:0)
如果模式是静态的,那么你需要在调用play()之前调用write()。
如果模式是流媒体,那么它并不重要。您可以选择在调用write()之前使用play()来填充数据,或者可以写()然后play()。无论哪种方式,它都是合法的。