Как закодировать аудио конверт (время атаки, затухание) для объекта 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.