Pattr

Питчшифтинг в PureData

Pitchshifting - это изменение частоты звука. Его можно встретить в реальном мире, когда источник звука приближается/удаляется от слушателя: наверное, каждый замечал, как меняется звук «гудка» прибывающего поезда. Это явление называется эффектом Доплера. Чтобы понять, в чем он заключается, взгляните на картинку:

В ней машина движется к наблюдател B. Для этого наблюдателя частота сирены будет выше, потому что машина как бы «догоняет» волны. Соответственно для наблюдателя А частота будет ниже, так как машина удаляется от своих волн. И как же можно применить эти знания на практике? Очень просто: динамично меняя задержку. То есть, постоянно увеличивая задержку, мы эмулируем отдаление источника звука, и наоборот, бесконечно уменьшая задержку, мы эмулируем приближение.

Реализация в PureData

Итак, с теорией разобрались, перейдем к практике. Задержка в пд реализуется с помощью объектов delwrite~ и vd~. Первый из них записывает сигнал в буфер, а второй считывает его. Эти объекты имеют два аргумента: имя буфера и время задержки. Соответственно, чтобы объект vd~ считывал сигнал из определенного буфера delwrite~, нужно дать объектам одинаковые имена. Плюс ко всему, объекту delwrite~ нужно обязательно задать второй аргумент, который определяет размер буфера задержки. В vd~ время задержки указывать не надо, так как мы будем изменять ее с помощью другого сигнала.

Создаём [delwrite~ pitch 5000] и [vd~ pitch]. В delwrite~ будет поступать сигнал, высоту тона которого требуется изменить, а из vd~ будет выходить уже измененный сигнал. Время задержки мы будем постоянно менять при помощи уже знакомого по статье о гранулярном синтезе объекта phasor~.

Перед тем как продолжить, давайте еще раз представим реальную машину; она приближается к нам и, проехав мимо, едет дальше. То есть питч сначала растёт, а потом падает. Попробуем симулировать ситуацию, когда машина всё время движется от нас. Допустим, мы услышали вой сирены, когда машина была рядом с нами, затем она переместилась расстояние 33 метра (эта цифра взята не с потолка, так удобнее считать, учитывая, что скорость распространения звука равна 330 м/с; получается, задержка равна 0.1 с = 100 мс, а сто — число круглое). Вот она, рядом с нами, затем удаляется, но нельзя допустить, чтобы она удалялась бесконечно, нужно чтобы она мгновенно переместилась к нам, затем снова отдалилась, и так до бесконечности.

Вот здесь-то нам и нужен phasor~. Зададим ему частоту, например, 1Hz, умножим выход фазора на 100 и присоединим полученное к [vd~ pitch]. Что получается? Напомним, что сигнал phasor~ - это пилообразное колебание 0…1, значит, умножив его на 100, получаем диапазон 0…100. В результате задержка меняется от 0 до 100 мс за интервал времени, равный 1 секунде. Это означает, что машина от нас удаляется со скоростью 33 м/1 с = 33 м/с. Питч понижается. Увеличивая частоту фазора до 4 hz, мы увеличиваем скорость воображаемой машины в четыре раза: 33 м/0.25 с = 132 м/с. Питч ещё сильнее понизился. Для того чтоб “машина” приближалась (и соответственно тон повысился), Нужно задать фазору отрицательную частоту, в этом случае, он будет генерировать нисходящую пилу диапазоном 1…0. На следующей картинке роль источника звука выполняет [osc~ 220], синусоида 200 Hz.

Примечание: слайдер, регулирующий питч умножается на -1. Это необязательно, просто так удобнее, когда границы слайдера установлены -10…10. Получается, когда задаётся отрицательное значение (слайдер влево), то -10 * -1 = 10, значит в phasor~ будет положительное значение частоты, что будет понижать питч; грубо говоря, слайдер влево — питч понизился, слайдер вправо — повысился.

Однако, и тут будут возникать те же проблемы, что и в гранулярном синтезаторе. Имеется в виду треск, возникающий при резком скачке сигнала фазора. Для устранения этой проблемы делаем также, как и в прошлом случае: пропускаем сигнал фазора через цепочку преобразований [phasor~] => [-~ 0.5] => [ *~ 0.5] => [cos~]. Полученное используем, как огибающую громкости. Теперь, для заполнения пустых мест, создаём второй [vd~ pitch] задержкой которого будет рулить та же пила, только смещенная на пол фазы. Аналогично, как и в гранулярном синте.

Итоговый результат выглядит так:

Вот и все. Добавим лишь только немного более удобный контроль, чтобы можно было бы изменять питч в полутонах. Вычислить его можно по следующей формуле:

В ней P – изменение высоты звука в полутонах; sr – частота дискретизации; win – размер окна в миллисекундах.

Эта же формула, только собранная в Pd:

Выход регулирует частоту phasor~.

На этом всё. Happy patching! :)

16 Jul 2011  Bruce Lee, OSCII