Почему вывод веб-аудио от генератора не работает должным образом?

Вот код:

Я хочу создать аудиопрограмму, которая может воспроизводить звук от очень низкой частоты до высокой частоты.

Однако этот код приводит к другому результату (даже с одним и тем же устройством):

  1. Звук появляется внезапно — ожидаемый результат — он появляется постепенно. Я уверен, что со слухом у меня все в порядке, потому что я попросил своих друзей услышать;
  2. На одной и той же частоте звук звучит по-разному.

ВНИМАНИЕ: перед запуском этого скрипта уменьшите громкость на очень низкий уровень, если вам что-то больно.

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// create Oscillator node
var oscillator = audioCtx.createOscillator();

var osc_arr = [];

function purgeSound(){
  osc_arr.forEach(function(v){
    try {
      v.stop();
      v.disconnect(audioCtx.destination);
    } catch (e) {}
  })
}

function playSoundAtFreq(fq){
  purgeSound();
  var osc = audioCtx.createOscillator();
  osc_arr.push(osc);
  osc.type = 'square';
  osc.frequency.setValueAtTime(fq, audioCtx.currentTime); // value in hertz
  $('#fff').val(fq);
  osc.connect(audioCtx.destination);
  osc.start();
}

$('#stop').click(function(){
  purgeSound();
  _break = true;
})

var _break = false;
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
var pointer = 0;
var go = appendAttemptAsync(10000);
async function appendAttemptAsync(range) {
  if(_break) return;
  var target = pointer+range;
  for (pointer; pointer<range; pointer++) {
    playSoundAtFreq(pointer);
    console.log(pointer)
    //if(pointer % 1 == 0) {
      await sleep(100)
    //}
  }
  return 5221;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='stop'>stop</button>
<input id="fff" type="text" />

ВНИМАНИЕ: перед запуском этого скрипта уменьшите громкость на очень низкий уровень, если вам что-то больно.

Спасибо за любые предложения по улучшению моего кода.


person AGamePlayer    schedule 11.10.2019    source источник
comment
Что значит выходит постепенно? Что значит звук звучит по разному на одной и той же частоте? Ваш тест не дает той же частоты.   -  person Raymond Toy    schedule 11.10.2019
comment
Под словом «постепенно» я подразумеваю, что хочу создать звук, который создается от низкой частоты к высокой частоте.   -  person AGamePlayer    schedule 12.10.2019
comment
Не уверен, что вы ищете. По крайней мере, в Chrome вы ничего не услышите, пока не нажмете «Стоп», потому что политика автозапуска Chrome блокирует вывод до тех пор, пока не будет жеста пользователя. Если вы добавите кнопку запуска для запуска осцилляторов, то я подозреваю, что она у вас сработает.   -  person Raymond Toy    schedule 14.10.2019
comment
Но для моего Chrome он запускается автоматически. Ему не нужна кнопка запуска. И то, что я ищу, выглядит примерно так:youtube.com/watch?v =H-iCZElJ8m0 Я хочу использовать JavaScript для имитации того, что показано в этом видео.   -  person AGamePlayer    schedule 15.10.2019


Ответы (1)


Если вы хотите, чтобы осциллятор работал, как в видео на YouTube, которое as-expected?noredirect=1#comment103121555_58335956">вы упомянули, вы можете сделать что-то вроде:

let osc = new OscillatorNode(audioCtx);
osc.connect(audioCtx.destination);
osc.frequency.setValueAtTime(20, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(audioCtx.sampleRate / 2, audioCtx.currentTime + 300);
osc.start();

Измените 300 на подходящее время, в течение которого распространяется тон. Я произвольно выбрал 5 минут.

Я не знаю, почему ваш пример не работает, но этот фрагмент — типичный способ изменить тон с помощью WebAudio.

person Raymond Toy    schedule 15.10.2019
comment
Привет, Рэймонд, большое спасибо. Это работает, но у меня есть еще один вопрос, я использовал свой iPhone-X для воспроизведения, он не работает, поддерживает ли веб-аудио только рабочий стол? - person AGamePlayer; 16.10.2019
comment
WebAudio, безусловно, работает на мобильных устройствах. Извините, но я не знаю, почему это не работает на iPhone. Я думаю, что лучше всего сообщить об этом в Apple и/или WebKit. - person Raymond Toy; 16.10.2019
comment
у вас есть другой мобильный бренд, который может воспроизводить звук? Просто интересно... Мне интересно написать о проблеме, но если есть устройство, которое может работать, было бы проще их подтолкнуть :) - person AGamePlayer; 16.10.2019
comment
У меня есть только устройства Android, и ваш codepen отлично работает для меня. - person Raymond Toy; 16.10.2019
comment
Конечно. Я попробовал древний Nexus 4 и Pixel 2 с довольно свежими версиями Chrome. Это те устройства, которые у меня сейчас есть под рукой. - person Raymond Toy; 16.10.2019
comment
Я думаю, что причина, по которой codepen не работает в Safari, заключается в этой строке let osc = new OscillatorNode(audioCtx);. Safari не поддерживает синтаксис конструктора. Вы можете переписать это так: let osc = audioCtx.createOscillator();. Или, если вы хотите придерживаться нового синтаксиса, вы можете использовать стандартизированный аудиоконтекст, который также позволяет использовать конструктор в Safari. - person chrisguttandin; 18.10.2019