Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.11.2024, 16:42
Интересующийся
Отправить личное сообщение для AlexHutor Посмотреть профиль Найти все сообщения от AlexHutor
 
Регистрация: 25.03.2016
Сообщений: 12

Тонгенератор
Здравствуйте, уважаемые специалисты!
Мне нужна помощь в создании простейшего тонгенератора. В сети нашел вот этот код:
var context = new AudioContext();
var oscillator = context.createOscillator();
oscillator.type = 'sine'; // форма сигнала
oscillator.frequency.value = 500; // частота
oscillator.connect(context.destination);
// oscillator.start(); для запуска
// oscillator.stop(); для завершения

Проблема такая: генератор запускается, останавливается, а повторно не запускается, не срабатывает oscillator.start()
Подозреваю, что решение простое, но я не специалист в этом, так что не ругайте. Очень буду признателен за помощь!
Ответить с цитированием
  #2 (permalink)  
Старый 15.11.2024, 16:57
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,228

Сообщение от AlexHutor
генератор запускается, останавливается, а повторно не запускается
А так?

<button id='bstart'>Старт</button>
<button id='bstop'>Стоп</button>

<script>

bstart.addEventListener('click', _ => {
	const context = new AudioContext();
	const oscillator = context.createOscillator();
	// форма сигнала
	oscillator.type = 'sine'; 
	// частота
	oscillator.frequency.value = 500; 
	oscillator.connect(context.destination);
	// для запуска
	oscillator.start();
	const fstop = _ => {
		// для завершения
		oscillator.stop(); 
		bstop.removeEventListener('click', fstop)
	}
	bstop.addEventListener('click', fstop)
})
</script>
Ответить с цитированием
  #3 (permalink)  
Старый 15.11.2024, 17:28
Интересующийся
Отправить личное сообщение для AlexHutor Посмотреть профиль Найти все сообщения от AlexHutor
 
Регистрация: 25.03.2016
Сообщений: 12

Сообщение от ksa Посмотреть сообщение
А так?
Спасибо большое! Так работает. Но мне нужно немного другое решение.
Кнопка должна быть одна, она переключает value скрытого инпута с 0 на 1 и обратно, и в зависимости от значения срабатывает либо старт, либо стоп. Еще один input служит для изменения частоты тона, и генератор должен на это изменение реагировать
Ответить с цитированием
  #4 (permalink)  
Старый 15.11.2024, 17:43
Интересующийся
Отправить личное сообщение для AlexHutor Посмотреть профиль Найти все сообщения от AlexHutor
 
Регистрация: 25.03.2016
Сообщений: 12

Иными словами, мне нужно, чтобы было две функции - старт и стоп, а запускать их чтобы я мог с разных источников
Ответить с цитированием
  #5 (permalink)  
Старый 16.11.2024, 00:35
Интересующийся
Отправить личное сообщение для AlexHutor Посмотреть профиль Найти все сообщения от AlexHutor
 
Регистрация: 25.03.2016
Сообщений: 12

Вот пример тонгенератора с функционалом, который мне нужен:

<html>

<head>

<title>Тонгенератор</title>

<meta charset="utf-8">
<meta http-equiv="Content-Language" content="ru" />

<style type="text/css">

#din {
    width: 50px;
    height: 50px;
    padding: 6px;
    border: #89b 2px solid;
    border-radius: 100%;
    margin: 5px;
    background-color: #fff;
    text-align: center;
    font-weight: bold;
    color: #89b;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-flow: column;
	outline:none;
	-webkit-tap-highlight-color: rgba(0,0,0,0);
	-webkit-tap-highlight-color: transparent;
}

#A4fr {
    border: 0;
    width: 70px;
    font-size: 40px;
    text-align: center;
    color: #78a;
    cursor: pointer;
}

.out {
	visibility: hidden;
	display:none;
    }
</style>

</head>

<body>

<input name="ttdin" id="ttdin" class="out" value=0 />

<center>

<input
	id="A4fr"
	value="440"
	onClick="A4fr.value = A4fr.value==444 ? 435 : +A4fr.value+1, StartStopOsc()"
	onfocus="this.blur()"
	readonly="readonly" />
<input
	id="din"
	value="Start"
	onClick="ttdin.value = ttdin.value==0 ? 1 : 0; din.value = ttdin.value==0 ? 'Start' : 'Stop'; StartStopOsc()"
	onfocus="this.blur()"
	readonly="readonly" />

<script>
    const context = new AudioContext();
    const oscillator = context.createOscillator();
    // форма сигнала
    oscillator.type = 'sine';
    oscillator.connect(context.destination);

function StartStopOsc(){
    // частота
    oscillator.frequency.value = +A4fr.value;
    // для запуска
    if(ttdin.value==1)oscillator.start();
    // для завершения
    if(ttdin.value==0)oscillator.stop();
}
</script>

</center>

</body>
</html>


Единственная загвоздка - тонгенератор не запускается после первой остановки. Всё остальное меня устраивает: когда генератор запущен, при смене частоты с 440 на другую, от 435 до 444 (это камертон для настройщиков фортепиано), меняется и частота запущенного генератора. Правда запускается он только один раз
Ответить с цитированием
  #6 (permalink)  
Старый 16.11.2024, 09:42
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

<html>

<head>

<title>Тонгенератор</title>

<meta charset="utf-8">
<meta http-equiv="Content-Language" content="ru" />

<style type="text/css">

#din {
    width: 50px;
    height: 50px;
    padding: 6px;
    border: #89b 2px solid;
    border-radius: 100%;
    margin: 5px;
    background-color: #fff;
    text-align: center;
    font-weight: bold;
    color: #89b;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-flow: column;
	outline:none;
	-webkit-tap-highlight-color: rgba(0,0,0,0);
	-webkit-tap-highlight-color: transparent;
}

#A4fr {
    border: 0;
    width: 70px;
    font-size: 40px;
    text-align: center;
    color: #78a;
    cursor: pointer;
}

.out {
	visibility: hidden;
	display:none;
    }
</style>

</head>

<body>

<input name="ttdin" id="ttdin" class="out" value=0 />

<center>

<input
	id="A4fr"
	value="440"
	onfocus="this.blur()"
	readonly="readonly" />
<input
	id="din"
	value="Start"
	onfocus="this.blur()"
	readonly="readonly" />
</center>

<script>
const A4fr = document.getElementById('A4fr');
const din = document.getElementById('din');
	
A4fr.addEventListener ('click', () => {
	A4fr.value = A4fr.value== 444 ? 435 : +A4fr.value + 1;
	Osc();
});

din.addEventListener ('click', () => {
	ttdin.value = ttdin.value==0 ? 1 : 0; 
	din.value = ttdin.value==0 ? 'Start' : 'Stop'; 
	StartStop();
});

let context;
let oscillator;

function Osc () {
	oscillator.frequency.value = +A4fr.value;
}

function StartStop(){
    // частота
    // для запуска
    if(ttdin.value==1) {
		context = new AudioContext();
		oscillator = context.createOscillator();
		// форма сигнала
		oscillator.type = 'sine';
		oscillator.frequency.value = +A4fr.value;
		oscillator.connect(context.destination);
		oscillator.start();
    // для завершения
    } else {
		oscillator.stop();
	}
}
</script>

</body>
</html>
Ответить с цитированием
  #7 (permalink)  
Старый 16.11.2024, 11:30
Интересующийся
Отправить личное сообщение для AlexHutor Посмотреть профиль Найти все сообщения от AlexHutor
 
Регистрация: 25.03.2016
Сообщений: 12

Спасибо вам огромное!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск