Страница 1 из 1

Проблема при генерации нескольких звуковых сигналов в цикле.

Добавлено: 21 фев 2015, 20:36
YK13
Всем доброго времени суток

Вот столкнулся с проблемой

Класс который генерирует сигналы

Код: Выделить всё

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