Как закодировать аудио конверт (время атаки, затухание) для объекта Sound?

Я сделал простой генератор тонов синусоидальной волны. Проблема в том, что при воспроизведении тона слышен сильный щелчок, и мне нужно реализовать быстрое усиление (время атаки), чтобы избежать этого.

Я попытался использовать анимацию движения (например, tweenmax), но это вызывает искажение звука (может быть, этапы анимации?). Я нашел несколько расплывчатых уроков по этому вопросу, но ничего не касалось времени атаки.

Как я могу это сделать?

1 ответ

Чтобы плавное звучание звучало плавно, его нужно увеличивать для каждого семпла внутри цикла синтеза. Механизм анимации может обновляться много раз в секунду, но ваше ухо все еще может слышать изменения в виде щелчка.

В вашем обработчике sampleData вам нужно будет умножить отдельные сэмплы на модификатор объема с диапазоном от 0 до 1, увеличиваясь для каждого сэмпла.

Чтобы быстро ослабить звук, начните с установки громкости на 0 и добавления к ней небольшого значения для каждого семпла, пока оно не достигнет 1,0. Позже вы можете расширить это в более сложный контроллер конвертов.

Это грубый пример того, что вы могли бы начать с:

for( i = 0; i < length; i++ ) {
    _count++;
    factor = _frequency * Math.PI * 2 / 4400;
    volume += 1.0 / 4400;
    if( volume > 1.0 ) volume = 1.0; //don't actually do it like this, ok?
    n = Math.sin( (_count) * factor ) * volume;
    _buffer.writeFloat(n); 
    _buffer.writeFloat(n); 
}

ПРИМЕЧАНИЕ. Я не проверял этот фрагмент и не рекомендовал бы использовать его для производства. Это просто, чтобы показать вам примерно то, что я имею в виду.

Другая техника, которая может работать для вас, - это увеличить громкость и задержку. Используйте переменную volumeEase, которая всегда "преследует" целевой объем с определенной скоростью. Это предотвратит щелчки при смене томов и может быть использовано для создания более длинных конвертов:

var volume:Number = 0; // the target volume
var volumeEase:Number = 1.0; // the value to use in the signal math
var volumeEaseSpeed:Number = 0.001; // tweak this to control responsiveness of ease

for( i = 0; i < length; i++ ) {
    _count++;

    // bring the volumeEase closer to the target:
    volumeEase += ( volume - volumeEase ) * volumeEaseSpeed;

    factor = _frequency * Math.PI * 2 / 4400;

    //use volumeEase in the maths, rather than 'volume':
    n = Math.sin( (_count) * factor ) * volumeEase;
    _buffer.writeFloat(n); 
    _buffer.writeFloat(n); 
}

Если вы хотите, вы можете просто использовать линейную интерполяцию и просто идти "к" цели с постоянной скоростью.

Еще раз, фрагмент не проверен, поэтому вам, возможно, придется настроить volumeEaseSpeed.

Другие вопросы по тегам