132 lines
2.3 KiB
Text
132 lines
2.3 KiB
Text
|
#lang scribble/manual
|
||
|
@(require (for-label racket))
|
||
|
|
||
|
@title{Rotate2}
|
||
|
Rotate a sound field.@section{related}
|
||
|
Classes/BiPanB2, Classes/DecodeB2, Classes/PanB, Classes/PanB2
|
||
|
@section{categories}
|
||
|
UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners
|
||
|
|
||
|
|
||
|
@section{description}
|
||
|
|
||
|
|
||
|
Rotate2 can be used for rotating an ambisonic B-format sound field around
|
||
|
an axis. Rotate2 does an equal power rotation so it also works well on
|
||
|
stereo sounds. It takes two audio inputs (x, y) and an angle control
|
||
|
(pos). It outputs two channels (x, y). It computes this:
|
||
|
|
||
|
|
||
|
@racketblock[
|
||
|
xout = cos(angle) * xin + sin(angle) * yin;
|
||
|
::
|
||
|
|
||
|
]
|
||
|
|
||
|
@racketblock[
|
||
|
yout = cos(angle) * yin - sin(angle) * xin;
|
||
|
::
|
||
|
|
||
|
where angle = pos * pi, so that -1 becomes -pi and +1 becomes +pi. This
|
||
|
allows you to use an LFSaw to do continuous rotation around a circle.
|
||
|
|
||
|
|
||
|
]
|
||
|
@section{classmethods}
|
||
|
|
||
|
|
||
|
@section{method}
|
||
|
ar, kr
|
||
|
|
||
|
@section{argument}
|
||
|
x
|
||
|
|
||
|
Input signal X.
|
||
|
|
||
|
|
||
|
@section{argument}
|
||
|
y
|
||
|
|
||
|
Input signal Y.
|
||
|
|
||
|
|
||
|
@section{argument}
|
||
|
pos
|
||
|
|
||
|
angle to rotate around the circle from -1 to +1. -1 is 180
|
||
|
degrees, -0.5 is left, 0 is forward, +0.5 is right, +1 is behind.
|
||
|
|
||
|
|
||
|
@section{Examples}
|
||
|
|
||
|
|
||
|
|
||
|
@racketblock[
|
||
|
|
||
|
(
|
||
|
{
|
||
|
var w, x, y, p, q, a, b, c, d;
|
||
|
|
||
|
p = WhiteNoise.ar(0.05); // source
|
||
|
q = LFSaw.ar(200,0,0.03)+LFSaw.ar(200.37,0,0.03)+LFSaw.ar(201,0,0.03);
|
||
|
|
||
|
// B-format encode 2 signals at opposite sides of the circle
|
||
|
#w, x, y = PanB2.ar(p, -0.5) + PanB2.ar(q, 0.5);
|
||
|
|
||
|
#x, y = Rotate2.ar(x, y, MouseX.kr(-1,1));
|
||
|
|
||
|
// B-format decode to quad
|
||
|
#a, b, c, d = DecodeB2.ar(4, w, x, y);
|
||
|
|
||
|
[a, b, d, c] // reorder to my speaker arrangement: Lf Rf Lr Rr
|
||
|
}.play;
|
||
|
)
|
||
|
|
||
|
|
||
|
|
||
|
// Rotation of stereo sound:
|
||
|
(
|
||
|
{
|
||
|
// rotation via lfo
|
||
|
var x, y;
|
||
|
x = PinkNoise.ar(0.4);
|
||
|
y = LFTri.ar(800) * LFPulse.kr(3,0,0.3,0.2);
|
||
|
#x, y = Rotate2.ar(x, y, LFSaw.kr(0.1));
|
||
|
[x,y]
|
||
|
}.play;
|
||
|
)
|
||
|
|
||
|
{
|
||
|
// rotation via mouse
|
||
|
var x, y;
|
||
|
x = Mix.fill(4, { LFSaw.ar(200 + 2.0.rand2, 0, 0.1) });
|
||
|
y = SinOsc.ar(900) * LFPulse.kr(3,0,0.3,0.2);
|
||
|
#x, y = Rotate2.ar(x, y, MouseX.kr(0,2));
|
||
|
[x,y]
|
||
|
}.play;
|
||
|
|
||
|
|
||
|
// Rotate B-format about Z axis:
|
||
|
|
||
|
wout = win;
|
||
|
zout = zin;
|
||
|
#xout, yout = Rotate2.ar(xin, yin, pos);
|
||
|
|
||
|
// Rotate B-format about Y axis:
|
||
|
|
||
|
wout = win;
|
||
|
yout = yin;
|
||
|
#xout, zout = Rotate2.ar(xin, zin, pos);
|
||
|
|
||
|
// Rotate B-format about X axis:
|
||
|
|
||
|
wout = win;
|
||
|
xout = xin;
|
||
|
#yout, zout = Rotate2.ar(yin, zin, pos);
|
||
|
|
||
|
::
|
||
|
|
||
|
]
|
||
|
|
||
|
|