| Author |
Message |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Feb 12, 2008 4:12 pm Post subject:
Preparing a Self-Phase-Modulating Oscillator Subject description: a quest to improve/extend ways to do FM synth |
 |
|
I'm quite new in the synthesis theory, but trying to examine this by trial and error..
(hmm.. although it's not very 'error' to me hahhahah i like da noises! bring them in!)
I've been playing around with simple.. classic FM synth method in ChucK..
by using .sync(2) of the fundamental oscillator types.
There have been problems with controlling the pitch of a self-FM oscillator (As usual and as it should be)
I known for some time about phase modulation, but haven't got my hands dirty yet, so now i'm gonna start.
let's here this out first:
| Code: | // phasor to drive the main frequency of the SinOsc
Phasor s1_phase => SinOsc s1 => dac;
// feed the result back to its phase
s1 => Gain s1_fb => s1;
// set main osc's center frequency
s1_phase.freq(220);
// make the SinOsc syncing input to phase
s1.sync(1);
// set the Gain FB to be able to be adjust by external source
s1_fb.op(3);
// feedback gain
s1_fb.gain(.25);
// use a sine LFO to modify feedback gain
SinOsc lfo => s1_fb;
lfo.freq(.1);
20::second => now; |
Or simply: a phasor runs a SinOsc at 220hz
and the output of the SinOsc is gonna be added to its phase at the next sample calculation.
We can adjust s1_fb.gain(.25); to see different feedback amount and the result.
One thing I wanna ask:
If I set feedback more than around .3 something..
the result'd produce a kind of.. hmm
becoming-more-chaotic kind of behavior, with frequency as high as nyquist..
(and with higher feedback, it looks much more chaotic)
It seems that it doesn't depend on Sample Rate or Main Oscillator Frequency..
so what is this .3 number about?
Is it something related to bifurcation in the chaos theory?
- - -
I like the sound of this kind of self-PM (phase-modulation).
The pitch is also 100% stable.
I'll report more about the result.
I'll try to limit (by using overdrive) to the feedback signal.
That should help preventing the chaotic behavior (which sounds very much un-analog) |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Feb 12, 2008 5:05 pm Post subject:
|
 |
|
More report after using x/(1+|x|) overdrive to limit the feedback tone:
| Code: | // phasor to drive the main frequency of the SinOsc
Phasor s1_phase => SinOsc s1 => dac;
// feed the result back to its phase
Step s1_od => Gain s1_fb => s1;
// set main osc's center frequency
s1_phase.freq(220);
// make the SinOsc syncing input to phase
s1.sync(1);
// set the Gain FB to be able to be adjust by external source
s1_fb.op(3);
// feedback gain
s1_fb.gain(.25);
// use a sine LFO to modify feedback gain
SinOsc lfo => s1_fb;
lfo.freq(.1);
1.0 => float driveAmount;
fun void overdrive1()
{
float x;
do
{
s1.last() * driveAmount => x;
x / (1 + Math.fabs(x)) => s1_od.next;
samp => now;
}
while(true);
}
spork ~ overdrive1();
20::second => now; |
By this method (and let's try to change driveAmount to larger values..
like 10.0, to 100.0 ..)
It surely sounds smoother.
the part that once was going more chaotic was gone,
but it still produce that nyquist-frequency peaks.
After reducing s1_fb.gain from 2.5 to 2.0 to 1.0,
I can still see the bifurcation,
so maybe it's really the behaviour of the system.
the overall sound is okay, so I might choose to filter it out for now, for convenience.
i tried to increase sample rate.
It helps make the overall audible sounds very smoother.
So upsampling surely helps it sound smoother. |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Feb 12, 2008 10:46 pm Post subject:
|
 |
|
This is what I doubt if it's bifurcation (it looks like one I've seen)
http://electro-music.com/forum/gallery2.php?g2_itemId=6437
This is from a waveform generated from the above method.
But setting the feedback as high as 10 to see more of the the chaos.
I'm interested in it, but also trying to reduce the thing without effecting too much to the audible sound to make it sounds more like a classic analog FM. |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Feb 12, 2008 11:13 pm Post subject:
|
 |
|
| Code: | // phasor to drive the main frequency of the SinOsc
Phasor s1_phase => SinOsc s1 => dac;
// feed the result back to its phase
Step s1_od => LPF s1_od_f => Gain s1_fb => s1;
// set main osc's center frequency
s1_phase.freq(220);
// make the SinOsc syncing input to phase
s1.sync(1);
// set the Gain FB to be able to be adjust by external source
s1_fb.op(3);
// feedback gain
s1_fb.gain(3);
// lowpass filtered the feedback
s1_od_f.set(10000, .5);
// use a sine LFO to modify feedback gain
SinOsc lfo => s1_fb;
lfo.freq(.1);
1.0 => float driveAmount;
fun void overdrive1()
{
float x;
do
{
s1.last() * driveAmount => x;
x / (1 + Math.fabs(x)) => s1_od.next;
samp => now;
}
while(true);
}
spork ~ overdrive1();
10::second => now; |
So I decided to lowpass-filter the feedback.
after trying from 5khz to 10khz, I notice it really helps stopping the chaos to start.
After increasing feedback value to 2-3, it still gives a very satisfactory sound, more analog.
(but it improves a lot more after increasing Sample Rate)
This method is quite cool and easy to implement.
It seems to produce a small ripple in the waveform instead of the high-frequency chaos:
http://electro-music.com/forum/gallery2.php?g2_itemId=6439
It produces a slight DC offset and it sounds a little flat..
but this is produced by a lot of feedback, so this slight distortion is acceptable for me. |
|
|
Back to top
|
|
 |
Inventor

Joined: Oct 13, 2007 Posts: 1344 Location: Florida, USA
Audio files: 53
|
Posted: Wed Feb 13, 2008 3:53 am Post subject:
|
 |
|
| hi kijjaz, nice sound effect you have there, interesting. |
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 232 Location: Finland
Audio files: 7
|
Posted: Wed Feb 13, 2008 8:30 am Post subject:
|
 |
|
| Quote: | It seems that it doesn't depend on Sample Rate or Main Oscillator Frequency..
so what is this .3 number about?
Is it something related to bifurcation in the chaos theory? |
I think you hit the target with that guess because if you lower the driving frequency you'll get approximately on a sample-by-sample basis: | Code: | | next_sample = p + (s1_fb)*sin(2.0*pi*previous_sample); | Where p (current phase from the phasor) is approximately constant. That equation will become chaotic once s1_fb is raised to a sufficient level. I haven't worked out the full math for this because the changing p would throw things off in the end anyway...
I'm busy with my class UnitGen and Instrument schemes but self modulation is so much fun that I'm sure to look more deeply in to it in the future. Self frequency modulation is very nice and warm but so numerically unstable...
Good luck with your PM experiments kijjaz! _________________ To boldly go where no man has bothered to go before. |
|
|
Back to top
|
|
 |
Inventor

Joined: Oct 13, 2007 Posts: 1344 Location: Florida, USA
Audio files: 53
|
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Wed Feb 13, 2008 1:43 pm Post subject:
|
 |
|
Inventor: Yes! That's one toy I love to play with .. SinOsc and SinOsc FMing eachother.
It's quite unstable if each freq is set higher..
(and usually go very out-of-tune)
But there's one interesting sound (sounds quite commercial!) that I produced by that kind of patch:
Setting the frequency to a similar value..
for example 300 and 300, 400 and 400.. and so on..
it'd produce a 'drop' .. hmm it'd sound like an analog bass drum in the dance / hiphop electronic music hahah. that kinda thing.
The higher the value, the faster it'd drop I noticed.
- - -
Thanks for all the people here, I'll try to work on more improvements.
This is one simple patch (very few lines of code)
and it worth playing around, it'd be useful for further implementation..
especially when I need to spare CPU power or type less for livecoding. |
|
|
Back to top
|
|
 |
Inventor

Joined: Oct 13, 2007 Posts: 1344 Location: Florida, USA
Audio files: 53
|
Posted: Wed Feb 13, 2008 4:59 pm Post subject:
|
 |
|
| Haha, I should have known you were already into that one. Similarly, I find that if you put harmonic values in, like f2=n*f1 where n is an integer, it makes a "wow" sound as the frequenc(ies) adjust and then settles in on a single waveform that continues. Sometimes by using non-harmonic frequencies I got interesting sounds too. Fun little toy, I wonder what would happen if you built a ring of them or a mesh or volume or something, what that would do? |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 471 Location: bangkok, thailand
Audio files: 2
|
Posted: Fri Feb 15, 2008 1:11 pm Post subject:
|
 |
|
After finding a way to tame its chaotic behavior I see above, this is a test patch to see how the oscillator work for analog-synth kind of setting.
I feel (and see in the waveform) that..
this method kinda make the SinOsc sounds closer to the analog Saw Wave or one that's been somewhat lowpassed.
I'm satisfied with the result. This sounds nice and warm. It also doesn't goes crazy with the gliding frequency.
| Code: | // - - - testing of a way to tame a Sine Osc with Self-Phase-Modulation
// let's hear out C aug in 7/8 meter! hahah -_-"
// copyright: kijjasak triyanond
// feel free to use, modify, and share
140.0 => float BPM;
minute / BPM => dur beat;
// - - - head - - -
Step s1_main_freq => Gain s1_freq => LPF s1_freq_f => Phasor p1 => SinOsc s1;
s1_freq_f.set(40.0, .5);
s1 => Gain s1_g => dac;
s1 => LPF s1_fb_f => Gain s1_fb_g => s1;
s1.sync(1);
s1_fb_f.set(8000.0, .5); // <-- this limit the high freq chaotic occuring from PM
s1_fb_g.op(3);
s1_fb_g.gain(.25); // <-- try changing this to control PM amount
// .25 seems to be quite a 'middle' value
Impulse i1 => Gain i1_g => Gain i1_fb => i1_g;
i1_g => Gain freq_env => s1_freq;
i1_g => s1_fb_g;
// - - - body - - -
s1_main_freq.next(110);
freq_env.gain(0);
i1_fb.gain(1.0 - 1.0/5000); // <-- try changing this to adjust delay of the PM
int i;
while(true)
{
if (i % 8 == 0) i1.next(2); else i1.next(1);
Std.mtof((i * 7) % 16 + (i * 5) % 8 + 36) => s1_main_freq.next;
if ((i) % 8 < 2) beat/1 => now; else beat/4 => now;
i++;
}
|
|
|
|
Back to top
|
|
 |
|