| Author |
Message |
Frostburn

Joined: Dec 12, 2007 Posts: 211 Location: Finland
Audio files: 7
|
Posted: Tue Mar 18, 2008 1:53 am Post subject:
General Oscillator Base Class Subject description: with phase, frequency, width and amplitude modulation |
 |
|
I thought about the issue of having a general base class for oscillators. I don't really see the need to have only one sync mode active at a time because they are not mutually exclusive.
I had to use a control loop ticking at samp intervals because phase modulation and frequency modulation are broken with Phasors and width modulation is non existant.
Anyway, here goes:
| Code: | class OscBase{
Gain PM => blackhole;
Gain FM => blackhole;
Impulse phaseWarper => Gain phasor;
Gain WM => blackhole;
Gain AM => Gain out;
3 => AM.op;
//This is bugged:
//FM => Phasor FMphasor => Phasor PMphasor => phasor;
//PM => PMphasor;
//2 => FMphasor.sync;
//1 => PMphasor.sync;
phasor => TriOsc triosc => SinOsc sinosc; 1 => sinosc.sync;
1 => triosc.sync;
phasor => PulseOsc pulseosc;
1 => pulseosc.sync;
220.0 => float freq_;
0.0 => float phase_;
0.5 => float width_;
samp/second => float delta;
Sin(); //Default SinOsc
spork~control_shred();
//Presets:
fun void Sin(){
disconnect();
0.25 => triosc.gain;
sinosc => AM;
}
fun void Tri(){
disconnect();
1.0 => triosc.gain;
triosc => AM;
}
fun void Pulse(){
disconnect();
pulseosc => AM;
}
fun void disconnect(){
sinosc =< AM;
triosc =< AM;
pulseosc =< AM;
}
fun void control_shred(){
while(samp => now){ //Note that this will advance time once before doing anything
(FM.last() + freq_)*delta +=> phase_;
phase_ + PM.last() - Math.floor( phase_ + PM.last() ) => phaseWarper.next;
width_ + WM.last() => triosc.width => pulseosc.width;
}
}
//UGen imitation:
fun float gain(){
return out.gain();
}
fun float gain(float _gain){
return _gain => out.gain;
}
fun float freq(){
return freq_;
}
fun float freq(float _freq){
return _freq => freq_;
}
fun float width(){
return width_;
}
fun float width(float _width){
return _width => width_;
}
fun float phase(){
return phase_;
}
fun float phase(float _phase){
return _phase => phase_;
}
}
//Plain sinewave:
OscBase sin;
sin.out => dac;
second => now;
sin.out =< dac;
second => now;
//Triangle wave FM modulated by a sinewave
OscBase tri;
tri.Tri(); //Call the preset
tri.out => dac;
sin.out => tri.FM; //Simple enough
300.0 => tri.freq;
tri.freq()*5.0 => sin.freq;
tri.freq()*3.0 => sin.gain;
second => now;
0.0 => tri.width; //Change it to a saw wave
second => now;
//Rape it with ringmodulation
OscBase sqr;
tri.freq()*0.25 => sqr.freq;
sqr.Pulse();
sqr.out => tri.AM;
second => now;
tri.out => Gain PM => tri.PM; //Self phase modulation
0.25 => PM.gain;
second => now;
//Let's try some of that width modulation
0.5 => tri.width; //Center at 0.5
SinOsc widthModulator => tri.WM;
0.5 => widthModulator.gain; //Modulate between 0.0 and 1.0
1.0 => widthModulator.freq; //Not too hastily though
3::second => now; |
_________________ To boldly go where no man has bothered to go before. |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 452 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Mar 18, 2008 7:32 am Post subject:
|
 |
|
Wow..! This is a very great idea.
I will become handy soon. I see it's gonna be more generalized than the original basic oscillators.
I'm gonna take some more time to investigate into the code also..
and I'll come up with some ideas ^_^"
for now I'm gonna start a "Sine Oscillator made from Gains" hahah
I got the idea from doing the Mass-Spring simulation. |
|
|
Back to top
|
|
 |
Inventor

Joined: Oct 13, 2007 Posts: 1166 Location: Florida, USA
Audio files: 50
|
Posted: Tue Mar 18, 2008 7:35 pm Post subject:
|
 |
|
That oscillator class looks like the perfect thing for Synth Lab. Though I need to understand it better before I can use it. I'll study the code more. I noticed, now that I have Synth Lab up and it is easy to switch oscillators, that modulation doesn't seem to work.
Maybe this is a ChucK bug or a Synth Lab bug, I dunno but if I have a ring of say 3 oscillators, all sine waves and I have them making some funky sound, then I change any of the oscillators the oscillation stops. I can muck around with the sliders all I want and still get no oscillation. Then when I click it around back to sinosc, my oscillation begins once more.
Is modulation broken in ChucK? Maybe this is on the known bug list and I'm just learning about it? |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 452 Location: bangkok, thailand
Audio files: 2
|
Posted: Tue Mar 18, 2008 7:57 pm Post subject:
|
 |
|
I'm thinking of a way to generalize this but with an existing UGens and very minimal connections:
Here's my idea
(but it's not as extensible as yours)
Step freq => Phasor p => WhateverBasicOscYouHave;
1 => WhateverBasicOscYouHave.sync;
1. set the center frequency by freq.next()
2. any FM.. chuck into p (so it adds to frequency automatically)
3. any PM.. chuck into WhateverBasicOscYouHave
4. if you need phase sync, set p.gain = 0 |
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 211 Location: Finland
Audio files: 7
|
Posted: Wed Mar 19, 2008 1:13 am Post subject:
|
 |
|
| Inventor wrote: | | Maybe this is a ChucK bug or a Synth Lab bug, I dunno but if I have a ring of say 3 oscillators, all sine waves and I have them making some funky sound, then I change any of the oscillators the oscillation stops. I can muck around with the sliders all I want and still get no oscillation. Then when I click it around back to sinosc, my oscillation begins once more. |
It's a ChucK bug.
If you give phase modulation outside of the [0.0,1.0] range it wont warp back to it. This breaks every oscillator except SinOsc.
If you do FM and the total frequency is negative it will break everything except SinOsc.
I took a look in to the source and all of the oscillators use the same code, SinOsc just uses Math.sin(...) and it doesn't care if the phase is outside the range.
| Code: | //Works fine:
SinOsc m => TriOsc c => dac;
2 => c.sync;
c.freq() - 1.0 => m.gain;
second => now;
//Busted!
c.freq() + 1.0 => m.gain;
second => now; |
That's why I have to keep the phase manually in the 0.0 to 1.0 range by invoking foo - Math.floor( foo ) => foo_with_a_bounded_phase.
| kijjaz wrote: |
Here's my idea
(but it's not as extensible as yours)
Step freq => Phasor p => WhateverBasicOscYouHave;
1 => WhateverBasicOscYouHave.sync;
1. set the center frequency by freq.next()
2. any FM.. chuck into p (so it adds to frequency automatically)
3. any PM.. chuck into WhateverBasicOscYouHave
4. if you need phase sync, set p.gain = 0 |
It's a good idea but Phasor is sync bugged too so that'll only work with small modulations. _________________ To boldly go where no man has bothered to go before. |
|
|
Back to top
|
|
 |
Inventor

Joined: Oct 13, 2007 Posts: 1166 Location: Florida, USA
Audio files: 50
|
Posted: Wed Mar 19, 2008 1:54 am Post subject:
|
 |
|
A ChucK bug???
| Code: | \
'-.__.-'
/oo |--.--,--,--.
\_.-'._i__i__i_.'
"""""""""
fsc |
Oh my! |
|
|
Back to top
|
|
 |
|