You should check
- the spectrum of the source and filter, and
- the bandwidth of the filter.
1. Does Saw.ar(333) contain 111 Hz, 222 Hz, 444 Hz and 555 Hz?
Let’s evaluate the following code to see the spectrum of the output signal:
FreqScope.new(400, 200, 0, server: s);
Then evaluate the following code to listen to the sound and see its spectrum:
{ Saw.ar(333) * 0.01 }.play
Stop the sound by pressing ‘cmd + .’ or ‘ctrl + .’
Then evaluate the following code to hear the sound and see its spectrum:
{ Saw.ar(111) * 0.01 }.play
You can see the result in the following picture:
So you should change the frequency of Saw.ar
into 111, otherwise the frequency array of the BPF into 333 * (1..5)
:
Evaluating 333 * (1..5)
returns [333, 666, 999, 1332, 1665]
You will then get one of the following codes:
{ Mix.new(BPF.ar(Saw.ar(333), 333 * (1..5))) ! 2 * 0.01 }.play
or the following code:
{ Mix.new(BPF.ar(Saw.ar(111), 111 * (1..5))) ! 2 * 0.01 }.play
These codes can be reconstructed as follows:
x = { |freq = 111| Mix.new(BPF.ar(Saw.ar(freq), freq * (1..5))) ! 2 * 0.01 }
You could use .sum
instead of Mix.new
in this case:
x = { |freq = 111| BPF.ar(Saw.ar(freq), freq * (1..5)).sum ! 2 * 0.01 }
After evaluating the above code, you can hear the sound by evaluating the following code::
y = x.play(args: [freq: 440]);
y.free
y = x.play(args: [freq: 111]);
y.free
y = x.play(args: [freq: 333]);
y.free
2. The bandwidth
BPF
uses the reciprocal of Q. The narrower the bandwidth, the lower the RQ!
However, the lower the RQ, the quieter the sound!
To test this, rewrite the above function as follows
x = { |freq = 111, rq = 1, mul=1| BPF.ar(Saw.ar(freq), freq * (1..5), rq, mul).sum ! 2 }
y = x.play(args: [freq: 333, rq: 1, mul: 0.01]);
y.free
y = x.play(args: [freq: 333, rq: 0.1, mul: 0.05]);
y.free
y = x.play(args: [freq: 333, rq: 0.01, mul: 0.1]);
y.free
y = x.play(args: [freq: 333, rq: 0.0001, mul: 0.1]);
// <- Extremely narrow bandwidth and a static (unchanging) signal will cause some feedback! The sound gets louder for a while!
y.free
To avoid the feedback of the last code, you should use the daisy chain BPF as follows:
(
x = { |freq = 111, rq = 1, mul=1|
var bpf = { |source|
{ BPF.ar(source, freq * (1..5), rq, mul).sum } ! 2
};
bpf = bpf.(Saw.ar(freq));
bpf = bpf.(bpf);
bpf = bpf.(bpf);
bpf = bpf.(bpf);
bpf = bpf.(bpf)
}
)
y = x.play(args: [freq: 444, rq: 0.05, mul: 0.05]);
y.free
y = x.play(args: [freq: 333, rq: 0.05, mul: 0.05]);
y.free
y = x.play(args: [freq: 111, rq: 0.05, mul: 0.05]);
y.free
I think white noise or blip would be convenient to hear each filtered frequency:
{ BPF.ar(WhiteNoise.ar, 333 * [1, 3], 0.0001, 10 ).sum ! 2 }.play
// <- left sound = right sound
{ { BPF.ar(WhiteNoise.ar, 333 * [1, 3], 0.0001, 10 ).sum } ! 2 }.play
// stereo!
{ Blip.ar(222) * 0.5 ! 2 }.play
{ { BPF.ar(Blip.ar(222), 222, 0.01) } ! 2 }.play
{ { BPF.ar(Blip.ar(222), 222 * (1..2), 0.01).sum } ! 2 }.play
{ { BPF.ar(Blip.ar(222), 222 * (1..3), 0.01).sum } ! 2 }.play