2017-02-16 16 views
0

У меня есть LFO, связанный с biquadFilter.Веб-аудио API - LFO с треугольной формой, связанной с кликами biquadFilter

Когда коэффициент усиления LFO больше текущего значения biquadFilter.frequency.value, он вызывает заметное нажатие звука.

Есть ли способ предотвратить это нажатие?

BiquadFilter имеет на нем конверт, поэтому частота сместится вверх и вниз после нажатия клавиши на клавиатуре.

Это то, что я думаю, что происходит:

LFO cutting through envelope value.

Это то, что я хотел бы случиться: LFO respecting the filter.

Вот минимальный пример: http://codepen.io/js-bs/pen/bgyZPx

var audioContext = new AudioContext(); 
var masterGain = audioContext.createGain() 
masterGain.connect(audioContext.destination) 
masterGain.gain.value = .3; 

// Filter 
var filter = audioContext.createBiquadFilter(); 
filter.type = 'lowpass' 
filter.frequency.value = 0; 
filter.connect(masterGain); 

// Oscillator 
var osc = audioContext.createOscillator(); 
osc.frequency.value = 440; 
osc.type = 'square'; 
osc.start(); 
osc.connect(filter); 

// LFO 
var lfo = this.audioContext.createOscillator(); 
var lfoGain = this.audioContext.createGain(); 
lfo.type = 'triangle'; 
lfo.start(); 
lfo.connect(lfoGain); 
lfo.frequency.value = 5; 
lfoGain.gain.value = 10000; 
lfoGain.connect(filter.frequency); 

document.addEventListener('click', function(e){ 
    if(e.target.id==='lfo' && e.target.checked){ 
    lfo.connect(lfoGain); 
    } else if (e.target.id==='lfo') { 
    lfo.disconnect(); 
    } 
}) 

document.addEventListener('mousedown', filterEnvelopeOn); 
document.addEventListener('mouseup', filterEnvelopeOff); 

function filterEnvelopeOn() { 
    let now = audioContext.currentTime; 
    let frequency = filter.frequency; 
    let attack = 0.5; 
    let decay = 0.4; 
    let sustain = 200; 

    let freq = 10000; 
    frequency.cancelScheduledValues(0) 
    frequency.setValueAtTime(60, now) 
    frequency.linearRampToValueAtTime(freq, now + attack) 
    frequency.linearRampToValueAtTime(sustain, now + attack + decay) 
} 

function filterEnvelopeOff() { 
    filter.frequency.cancelScheduledValues(0); 
    let now = audioContext.currentTime; 
    let frequency = filter.frequency; 
    let release = 0.1; 
    frequency.cancelScheduledValues(0); 
    frequency.setValueAtTime(frequency.value, now); 
    frequency.linearRampToValueAtTime(0, now + release); 
    } 
+1

Можете ли вы создать небольшой пример? Мне не нравится читать и понимать, как использовать все библиотеки, которые вы используете. –

+0

Да, я могу создать минимальное воспроизведение. Я не использую никаких веб-аудио-библиотек, а только стандартную библиотеку, когда речь заходит об аудио. Библиотеки, которые я использую, предназначены только для пользовательского интерфейса. – looshi

+1

Это было бы замечательно. Благодаря! –

ответ

1

Если я изменить свой codepen пример кода из:

lfoGain.connect (filter.frequency);

к:

lfoGain.connect (filter.detune);

Звуковой щелчок пропал, и синтезатор звучит так, как я его намерен.

Если кто-нибудь может объяснить, почему это работает, это было бы полезно, и я помету ваш ответ как принятый.

Когда у вас есть AudioNodes, подключенные к AudioParam, AudioParam принимает свое значение как все выходы AudioNodes и его собственное значение, добавленное вместе. В вашем случае значения, выводимые вашим диапазоном lfoGain, варьируются от -10000 до +10000, потому что выход генератора колеблется от -1 до 1, и эти значения затем умножаются на значение вашего lfoGain.gain.

Если у вас есть ваш lfoGain, подключенный к частоте, вы говорите, что частота колеблется между 0 Гц и + 20000 Гц (10000 ± 10000) сразу после атаки вашего конверта между -9800 Гц и + 10200 Гц (200 ± 10000) на вашем выдержке и между -10000 Гц и + 10000 Гц (0 ± 10000) после выпуска вашего конверта.

Если вы используете ваш lfoGain, подключенный к detune, вычисленная частота будет колебаться пропорционально частоте, заданной с помощью конверта.

computedFrequency (т) = частота (т) * пау (2, расстроить (т)/1200)

Вы сейчас говорите значение расстройки колебаться между -10000cents и + 10000cents (0 ± 10000), и это колебание, а не добавление к частоте, умножает его на величину, которая приблизительно находится между 1/323 и 323.

Сразу же после атаки конверта минимальная вычисленная частота в колебании составляет приблизительно 31 Гц , при выдержке минимум составляет около 0,62 Гц, а после выпуска вашего конверта вычисленная частота ncy находится между 0 и 0 (0/323, 0 * 323).

Это, по крайней мере, то, что ему говорят, фактическая реализация может отличаться.

+0

на основе вашего ответа, можно ли подключить LFO к «частоте» AudioParam и не слышать щелчок? Если фильтр имеет известное значение, которое не изменяется со временем - тогда кажется возможным подключить LFO к «частоте» AudioParam без слышимого щелчка. Однако, поскольку фильтр меняет значения со временем, LFO должен будет соответствующим образом скорректировать его коэффициент усиления - и это действительно невозможно. – looshi

+0

Вы можете изменить значение lfoGain.gain, используя тот же конверт, который изменяет частоту фильтра. Я сделал быстрое редактирование на вашем ручке, чтобы показать результат: http://codepen.io/ivthefourth/pen/vxGJaV Вы также можете попробовать использовать пользовательскую PeriodicWave для создания формы треугольного треугольника с диапазоном от 0 до 1 вместо -1 к 1. В этом случае результат будет похож на вашу начальную ситуацию при более низких значениях частоты, но не будет отрицательных значений, что потенциально исключает щелчок. Отсутствие отрицательных значений сделает звук вашего конверта другим. – Howard

+0

круто спасибо, да, я полагаю, это тоже сработает! Интересно, что здесь есть несколько разных способов достижения желаемых результатов. – looshi

0

Ответ вас не устраивает, но это похоже на th в.

Щелчок происходит, когда звуковой сигнал падает слишком сильно. Возможно, у вас есть логическая ошибка в вашем LFO => Когда LFO опускается ниже 0, он начинает нажимать. Это довольно нормальное поведение. Посмотрите на моем сайте gtube.de и выберите в базе данных «dubstep like 2», и вы также можете услышать щелчок, если затем уменьшить сумму с «GAIN 2», которая действует как усилитель на 1999 год, вы не пересекаете границу 0 фильтра, и он не будет нажимать.

=> Если вы хотите услышать, что примеры midi не работают правильно в данный момент.

+0

спасибо. Я уточнил свой ответ, чтобы быть более точным.Знаете ли вы, как управлять LFO, чтобы он не опускался ниже нуля или выше текущего значения частоты во время применения конверта? – looshi

0

Если я изменить свой codepen пример кода из:

lfoGain.connect(filter.frequency);

к:

lfoGain.connect(filter.detune);

Звуковой щелчок ушел, и синтезаторные звуки, как я намерен его.

Если кто-нибудь может объяснить, почему это работает, это было бы полезно, и я помету ваш ответ как принятый.

0

Если я изменяю

lfoGain.connect(filter.detune); 

Звук сам пошел за мной. Я не мог воспроизвести его.

Если вы хотите, чтобы сделать щелчок прочь я уменьшить количество усиления до

lfoGain.gain.value = 2000; 

Тогда не щелкает и у вас есть этот хороший «wable» эффект.

Или вы просто не хотите, чтобы этот полезный эффект?

Также Вы можете уменьшить количество времени, которое требуется, чтобы wable:

lfo.frequency.value = 1; 

поэтому не щелкает. Щелчок происходит, если звук слишком быстро падает. Если кривая падает слишком быстро, чем нажимает. Везде на каждом синтезаторе всегда! И это правильный ответ :)

+0

После того, как вы отредактируете код как 'lfoGain.connect (filter.detune)' Нажмите на визуализированную страницу, где говорится «Мышь здесь, чтобы начать конверт фильтра». Когда вы наведите указатель мыши, вы услышите начало фильтра, и LFO не будет превышать текущую частоту фильтра - это мое желаемое поведение. – looshi