powered by simpleCommunicator - 2.0.35     © 2025 Programmizd 02
Форумы / Разработка под мобильные платформы [игнор отключен] [закрыт для гостей] / Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
6 сообщений из 6, страница 1 из 1
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38885105
YK13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток

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

Класс который генерирует сигналы
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
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) {

		}
		
	}
}



Обработчик нажатия кнопки
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
	@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
...
Рейтинг: 0 / 0
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38885130
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YK13
Код: java
1.
while(player.state == AudioTrackPlayer.PLAYER_BUSY);


Пустые цикли - зло. Если уж если так нужно их использовать, то в нем дергать Thread.yield();

По теме: если отладка не помогает, то придется использовать логирование через Log.d/v/e и т.п. Студия, Эклипс и девайс монитор из сдк умеют на ходу выводить логи. Вставлять куда угодно, пока картина не прояснится.
...
Рейтинг: 0 / 0
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38885261
YK13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про Thread.yeld() не знал - спасибо

Насчет логирования - придется, хотя к сожалению не всегда помогает. Да и ума не приложу что именно нужно здесь выводить в log. А так на вскидку ничего (из собственного опыта например) в голову ни приходит? Какие могут быть здесь варианты - где вероятнее всего может быть ошибка?
...
Рейтинг: 0 / 0
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38885285
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YK13, я со звуком совсем не работал.
...
Рейтинг: 0 / 0
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38885288
YK13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Жалко, а я уж было подумал что вы гуру в этой области :)
Все равно спасибо за дельные советы в этой и предыдущей ветке
...
Рейтинг: 0 / 0
Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
    #38886102
YK13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В логе увидел что обычно перед сбоем (не непосредственно) появляется сообщение GC_FOR_ALLOC .....
Погуглил но так и не понял как с ним кардинально бороться.

Вот что еще интересно. Пересоздал проект в AndroidStudio (до этого был в eclipse) - пока что сбоев не было

Всё таки хотелось бы разобраться в проблеме.
Заранее благодарен всем за советы и идеи
С уважением
YK13
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Разработка под мобильные платформы [игнор отключен] [закрыт для гостей] / Генерация нескольких звуковых сигналов в цикле. Не доходит до конца
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]