Я хочу воспроизвести тональный импульс, повторяемый с определенной скоростью, например. 3 раза в секунду. Он работает примерно 20 раз, а затем падает, как показано ниже.Воспроизведение повторяющегося AudioTrack в активности Android
void playSound() {
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
В asynctask Я запускаю непрерывный цикл, который проверяет время и вызывает playSound при необходимости. Он работает в течение нескольких секунд, а затем получает эту ошибку,
01-02 18:24:45.035: E/AndroidRuntime(6599): Caused by: java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
, хотя дорожка инициализируется каждый раз.
Любое указание на то, что я делаю неправильно? Или может быть лучше?
Вот код:
public class DisplayBowieActivity extends Activity {
private final int duration = 200; // seconds
private final int sampleRate = 8000;
private final int numSamples = duration * sampleRate/1000;
private double sample[];// =new double[numSamples];
private final double freqOfTone = 1440; // hz
private int pulseLength;
private byte generatedSnd[];// = new byte[2 * numSamples];
private int period = 4; // hz
private AudioTrack audioTrack;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_bowie);
Intent intent = getIntent();
String smessage = intent.getStringExtra(MainActivity.SOUND_MESSAGE);
period = Integer.parseInt(smessage);
pulseLength = duration * sampleRate/1000;
System.out.print("+++ Period " + period);
System.out.print("+++ Pulse " + pulseLength);
genTone();
View view = this.getWindow().getDecorView();
view.setBackgroundColor(Color.parseColor("#8E8E38"));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.display_bowie, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
new SoundGen().execute(period);
}
private class SoundGen extends AsyncTask<Integer, Void, Void> {
@Override
protected Void doInBackground(Integer... hz) {
long mils = (int) (1000.0/hz[0]);
long start = System.currentTimeMillis();
long next = start + mils;
while (true) {
long now = System.currentTimeMillis();
if (now > next) {
next = now + mils;
playSound();
}
}
}
}
void genTone() {
sample = new double[numSamples];
generatedSnd = new byte[2 * numSamples];
int rate = numSamples/period;
for (int i = 0; i < numSamples; ++i) {
if (i % rate == 0) {
System.out.println("+++ Create tone " + i);
int j = 0;
for (j = 0; j < pulseLength; j++) {
sample[i + j] = Math.sin(2 * Math.PI * (i + j)
/(sampleRate/freqOfTone));
System.out.println("+++ SAMPLE " + (i + j) + " "
+ sample[i + j]);
}
i = i + j;
}
}
// 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);
}
}
void playSound() {
System.out.println("+++ PLAY ");
//audioTrack.stop();
//audioTrack.setPlaybackHeadPosition(0);
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
А вот полная ошибка:
01-02 18:24:45.035: E/AndroidRuntime(6599): FATAL EXCEPTION: AsyncTask #1
01-02 18:24:45.035: E/AndroidRuntime(6599): java.lang.RuntimeException: An error occured while executing doInBackground()
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.os.AsyncTask$3.done(AsyncTask.java:200)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.lang.Thread.run(Thread.java:1019)
01-02 18:24:45.035: E/AndroidRuntime(6599): Caused by: java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.media.AudioTrack.play(AudioTrack.java:824)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity.playSound(DisplayBowieActivity.java:164)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity$SoundGen.doInBackground(DisplayBowieActivity.java:90)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity$SoundGen.doInBackground(DisplayBowieActivity.java:1)
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.os.AsyncTask$2.call(AsyncTask.java:185)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
01-02 18:24:45.035: E/AndroidRuntime(6599): ... 4 more
возможно дубликат [неинициализированного исключением AudioTrack, когда я пытаюсь генерировать сигнал на 22-й раз] (http://stackoverflow.com/questions/7497598/uninitialized-audiotrack -exception-when-i-try-to-generate-tone-on-22nd-time) – KickAss