ユーザーがディスプレイに表示される仮想ピアノで演奏できるピアノアプリを実装しようとしています。レイテンシーが低いため、AudioTrack クラスを使用しようとしていますが、これは多くの問題を引き起こします。私の問題は、音を速く再生することです。現時点では、ボタンを使用してテストしています。ボタンを押して高速にすると、次の例外が発生します。
09-11 15:06:19.089: E/AudioTrack(3729): AudioFlinger could not create track, status: -12
09-11 15:06:19.097: E/AudioTrack-JNI(3729): Error initializing AudioTrack
09-11 15:06:19.097: E/AudioTrack-Java(3729): [ android.media.AudioTrack ] Error code -20 when initializing AudioTrack.
09-11 15:06:19.097: D/AndroidRuntime(3729): Shutting down VM
09-11 15:06:19.097: W/dalvikvm(3729): threadid=1: thread exiting with uncaught exception (group=0x4001d888)
09-11 15:06:19.097: E/AndroidRuntime(3729): FATAL EXCEPTION: main
09-11 15:06:19.097: E/AndroidRuntime(3729): java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.media.AudioTrack.play(AudioTrack.java:764)
09-11 15:06:19.097: E/AndroidRuntime(3729): at com.example.audiotrackvssoundpoollayer.MainActivity.onClick(MainActivity.java:216)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.view.View.performClick(View.java:2461)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.view.View$PerformClick.run(View.java:8890)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.os.Handler.handleCallback(Handler.java:587)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.os.Handler.dispatchMessage(Handler.java:92)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.os.Looper.loop(Looper.java:123)
09-11 15:06:19.097: E/AndroidRuntime(3729): at android.app.ActivityThread.main(ActivityThread.java:4632)
09-11 15:06:19.097: E/AndroidRuntime(3729): at java.lang.reflect.Method.invokeNative(Native Method)
09-11 15:06:19.097: E/AndroidRuntime(3729): at java.lang.reflect.Method.invoke(Method.java:521)
09-11 15:06:19.097: E/AndroidRuntime(3729): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
09-11 15:06:19.097: E/AndroidRuntime(3729): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
09-11 15:06:19.097: E/AndroidRuntime(3729): at dalvik.system.NativeStart.main(Native Method)
AudioTrack を静的モードで使用しています。サウンドを再生するたびに、新しい AudioTrack(....) を使用して新しい AudioTrack オブジェクトを作成し、次に write(...) と play(....) を作成する必要があります。
インスタンス化が十分に高速ではないため、例外が発生すると思います...
コードは次のとおりです。サウンドは、別の非同期タスク クラスのハッシュマップに格納されます。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonA1 = (Button) findViewById(R.id.buttonA1);
buttonA1.setOnClickListener(this);
Button buttonA2 = (Button) findViewById(R.id.buttonA2);
buttonA2.setOnClickListener(this);
Button buttonA3 = (Button) findViewById(R.id.buttonA3);
buttonA3.setOnClickListener(this);
Button buttonA4 = (Button) findViewById(R.id.buttonA4);
buttonA4.setOnClickListener(this);
Button buttonA5 = (Button) findViewById(R.id.buttonA5);
buttonA5.setOnClickListener(this);
Button buttonA6 = (Button) findViewById(R.id.buttonA6);
buttonA6.setOnClickListener(this);
Button buttonA7 = (Button) findViewById(R.id.buttonA7);
buttonA7.setOnClickListener(this);
Button buttonA8 = (Button) findViewById(R.id.buttonA8);
buttonA8.setOnClickListener(this);
//***AudioTrack***
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
volume = actualVolume / maxVolume;
minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
assetManager = getResources().getAssets();
}
public void onClick(View button) {
switch(button.getId()) {
case R.id.buttonA1:
audioTrack1 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack1.write(soundMap.get(3), 0, minBufferSize * 65);
audioTrack1.play();
break;
case R.id.buttonA2:
audioTrack2 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack2.write(soundMap.get(3), 0, minBufferSize * 65);
audioTrack2.play();
break;
case R.id.buttonA3:
audioTrack3 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack3.write(soundMap.get(3), 0, minBufferSize * 65);
audioTrack3.play();
break;
case R.id.buttonA4:
audioTrack4 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack4.write(soundMap.get(3), 0, minBufferSize * 65);
audioTrack4.play();
break;
case R.id.buttonA5:
audioTrack5 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack5.write(soundMap.get(4), 0, minBufferSize * 65);
audioTrack5.play();
break;
case R.id.buttonA6:
audioTrack6 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack6.write(soundMap.get(5), 0, minBufferSize * 65);
audioTrack6.play();
break;
case R.id.buttonA7:
audioTrack7 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack7.write(soundMap.get(6), 0, minBufferSize * 65);
audioTrack7.play();
break;
case R.id.buttonA8:
audioTrack8 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 65, AudioTrack.MODE_STATIC);
audioTrack8.write(soundMap.get(7), 0, minBufferSize * 65);
audioTrack8.play();
break;
}
}
誰かがこの問題を解決するのを助けることができれば素晴らしいでしょう.おそらく静的モードの代わりにストリームモードを使用して、サウンドが前処理されるか、空のバイトバッファがaudiotrackに書き込まれ、ボタンをクリックするとハッシュマップサウンドがaudiotrackにストリーミングされます.