Вот столкнулся с проблемой
Класс который генерирует сигналы
Код: Выделить всё
public class Beeper {
private static Beeper instance;
public static Beeper getInstance(){
if(instance == null){
instance = new Beeper();
}
return instance;
}
private Beeper(){
player = new AudioTrackPlayer();
}
AudioTrackPlayer player;
public void generateLongBeep() {
byte[] buffer = makeSinWave(44000, 440, 1000, TimeUnit.MILLISECONDS);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_8BIT, buffer.length,
AudioTrack.MODE_STREAM);
audioTrack.setNotificationMarkerPosition((int)(1000 * 44000 / 1000));
audioTrack.write(buffer, 0, buffer.length);
while(player.state == AudioTrackPlayer.PLAYER_BUSY);
audioTrack.setPlaybackPositionUpdateListener(player);
player.state = AudioTrackPlayer.PLAYER_BUSY;
audioTrack.play();
}
public void generateMiddleBeep() {
byte[] buffer = makeSinWave(44000, 440, 500, TimeUnit.MILLISECONDS);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_8BIT, buffer.length,
AudioTrack.MODE_STREAM);
audioTrack.setNotificationMarkerPosition((int)(500 * 44000 / 1000));
audioTrack.write(buffer, 0, buffer.length);
while(player.state == AudioTrackPlayer.PLAYER_BUSY);
audioTrack.setPlaybackPositionUpdateListener(player);
player.state = AudioTrackPlayer.PLAYER_BUSY;
audioTrack.play();
}
public void generateShortBeep() {
byte[] buffer = makeSinWave(44000, 440, 130, TimeUnit.MILLISECONDS);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_8BIT, buffer.length,
AudioTrack.MODE_STREAM);
audioTrack.setNotificationMarkerPosition((int)(130 * 44000 / 1000));
audioTrack.write(buffer, 0, buffer.length);
while(player.state == AudioTrackPlayer.PLAYER_BUSY);
audioTrack.setPlaybackPositionUpdateListener(player);
player.state = AudioTrackPlayer.PLAYER_BUSY;
audioTrack.play();
}
private byte[] makeSinWave (double sampleRate, double frequency, long duration, TimeUnit timeUnit){
byte[] buffer = new byte[(int) (timeUnit.toMillis(duration) * sampleRate/1000)];
double period = sampleRate / frequency;
for (int i = 0; i < buffer.length; i++) {
double angle = 2d * Math.PI * i / period;
buffer[i] = (byte) (Math.sin(angle) * 127d);
}
return buffer;
}
public static final int BEEPER_FREE = 0;
public static final int BEEPER_BUSY = 1;
public int getState(){
return player.state;
}
public void setState(int state){
player.state = state;
}
class AudioTrackPlayer implements OnPlaybackPositionUpdateListener {
public static final int PLAYER_FREE = 0;
public static final int PLAYER_BUSY = 1;
int state;
@Override
public void onMarkerReached(AudioTrack track) {
if(track.getPlayState() == AudioTrack.PLAYSTATE_PLAYING){
state = PLAYER_FREE;
track.stop();
track.flush();
track.release();
}
}
@Override
public void onPeriodicNotification(AudioTrack track) {
}
}
}
Код: Выделить всё
@Override
public void onClick(View arg0) {
Thread thread = new Thread(new Runnable() {
public void run() {
Beeper.getInstance().setState(Beeper.BEEPER_FREE);
for(int i = 0; i < 8; i++){
try {
Thread.sleep(10000);
Beeper.getInstance().generateShortBeep();
Beeper.getInstance().generateShortBeep();
Beeper.getInstance().generateShortBeep();
Thread.sleep(15000);
Beeper.getInstance().generateShortBeep();
Beeper.getInstance().generateMiddleBeep();
Beeper.getInstance().generateShortBeep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
Иногда при первом нажатии все проходит нормально и сбой происходит при повторном нажатии.
Пробовал в начале метода run вызывать System.gc() однако это не принесло желаемого результата.
Оговорюсь, что тестировал только на одном устройстве. Когда произошел бы сбой на какам дибо другом устройстве (да и произошел ли бы вообще) сказать не могу.
В режиме отладки кода вызываю все методы шаг за шагом все проходит нормально
Зараннее благодарен за советы
С уважением
YK13