| Author |
Message |
Frostburn

Joined: Dec 12, 2007 Posts: 211 Location: Finland
Audio files: 7
|
Posted: Wed Dec 12, 2007 6:39 am Post subject:
Cubic Splines Subject description: What's the best way to get smooth transitions? |
 |
|
A Wikipedia article on Cubic Hermite splines:
http://en.wikipedia.org/wiki/Cubic_Hermite_spline
I'm very new to ChucK (I tried it today for the first time) and I'm wondering how to implement Cubic Splines in ChucK. I want my filters, pitch-bends and volumes slide smoothly and under precise control. |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 6244 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Dec 12, 2007 9:36 am Post subject:
|
 |
|
Basically what you need would be formulas h00 and h01 (which are kinda the same, except upside down). We'd need to scale those in both time and amplitude but that wouldn't be too hard.
Sounds like a very useful idea to me, I think I'll try to make a simple ChucK implementation and post it later tonight (my time, Western Europe).
You may also get some use out of the new GenX Ugens (see /examples/special/ ) but I haven't gotten too deeply into those myself yet. _________________ while(!machine.crash() ) <<<"all is well">>>; |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 6244 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Dec 12, 2007 5:19 pm Post subject:
|
 |
|
Ok, here's what I came up with. Not truly splines but the aspect of splines that works for gliding from frequency to frequency. Sounds quite good to me so far.
I realise this is advanced code if you are new to ChucK, however it's a tricky issue, for example; what do we do if the sliding hasn't finished yet at the moment a new command comes in? I tried to keep it clean and commented but likely it's still hard to read, mostly because it's quite a ambitious issue as a first question.
I had fun, hope you have fun with it too!
| Code: |
//example usage
SlideOsc s;
s.io => dac;
second => s.glideTime;
second => now;
1000 => s.glide;
2::second => now;
.5::second => s.glideTime;
500 => s.glide;
2::second => now;
//example gliding oscilator using a function I stole
//from the WiKipedia page on splines
class SlideOsc
{
//named io as it's the in and output for sound
SinOsc io => dac;
//sets the time a glide takes
.5::second => dur glideTime;
//sets the "controll rate"
//shorter durations are nicer for your ears, less nice for the CPU
10::ms => dur K_rate;
//don't call the next block from outside of the Class
//or there will be trouble
//the change in frequency
float delta;
//our starting freq
float offset;
//used in the spline calculation, defined here to avoid garbage
float x;
//to keep track of how far along the spline we are
int index;
time glideEnd;
//used to make sure we only have one modulation source going at a time
int sporkee;
//this is the intresting bit to call from outside.
//see usage above
fun void glide(float target)
{
io.freq() => offset;
target - offset => delta;
//make sure only one slider is going at a time
Machine.remove(sporkee);
//start spline so it can run on it's own
spork~slider(glideTime, K_rate, delta, offset);
}
//don't touch this from outside of the class, meant to be called by "glide"
fun void slider( dur T, dur rate, float delt, float offs )
{
me.id() => sporkee;
0 => index;
now + T => glideEnd;
while((now<glideEnd) && (index * rate < T))
{
(index * rate) / T => x;
offs + (delt * ( (-2 * Math.pow(x, 3) ) + (3 * Math.pow(x, 2) ) )) => io.freq;
index++;
rate => now;
}
//cover up round errors once we are done
offs + delt => io.freq;
me.exit();
}
}
|
_________________ while(!machine.crash() ) <<<"all is well">>>; |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 452 Location: bangkok, thailand
Audio files: 2
|
Posted: Thu Dec 13, 2007 10:47 pm Post subject:
|
 |
|
I haven't programmed any interpolation algorithms myself..
(except for a simple "moving average")
but sometimes I work that out with minimum code with a LPF
it wouldn't be a standard spline,
but a quick way to code and do the smoothing.
| Code: | Step freq => LPF freq_smooth => TriOsc s => SinOsc overdrive => dac;
freq_smooth.set(50, .2); // set smoothing speed: lower freq, smoother result
// lower Q, lower ripples
s.gain(0.5);
overdrive.sync(1);
int i;
while(true)
{
40 + ((i * 5) % 8 + (i * 5) % 12) * 20 => freq.next;
i++;
minute/120 * .25 => now;
} |
^_^" |
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 211 Location: Finland
Audio files: 7
|
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 6244 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Dec 16, 2007 7:27 am Post subject:
|
 |
|
Ah, ok. I had no idea about what you were after or your level of understanding, I aimed my example at somebody new to programming itself so I went for the most simple yet still usefull system I could come up with and over-commented.
That's quite the structure :¬). Are you sure you want to do the advancing of time outside of the class? My example is structured around keeping it inside of the class to avoid having to deal with that in the controlling structure as it could get quite inconvenient if you would like to sequence multiple instruments that may use overlapping sliding notes.
Perhaps you could merge my sporked (and killed) controlling shred structure with your own more elaborate way of doing the actual splines?
One thing that bothered my about my own version is that if we would start a slide, then halfway into it change it there would still be a breakpoint in the envelope. I don't think there is any way around that so splines may be more suitable for planed out compositions and less so for realtime systems.
For realtime systems a mass-spring system with changing forces may be more suitable. I'm not sure if you -Kijjaz- knew, but a resonant multi-mode filter actually works as mathematical model of a weight attached to a idealised spring. _________________ while(!machine.crash() ) <<<"all is well">>>; |
|
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 211 Location: Finland
Audio files: 7
|
Posted: Sun Dec 16, 2007 2:09 pm Post subject:
|
 |
|
Thanks for the input Kassen.
| Quote: | | Ah, ok. I had no idea about what you were after or your level of understanding, I aimed my example at somebody new to programming itself so I went for the most simple yet still usefull system I could come up with and over-commented. |
I've programmed quite a bit in the past myself but it's always nice to have informative examples. I learned a lot from that piece of code of yours and got some feel of the way things are done with ChucK.
I'm more of a mathematician than a coder so I tend to worry more about abstract stuff than threads and realtime. That's why I implemented the spline as a float function instead of an independent spork.
| Quote: | | One thing that bothered my about my own version is that if we would start a slide, then halfway into it change it there would still be a breakpoint in the envelope. I don't think there is any way around that so splines may be more suitable for planed out compositions and less so for realtime systems. |
You're right about that. Generally splines are used when all the data is already available. You'd have to deal with a lot of clipping issues if you wanted to use splines in a realtime system. And then you would also lose some of the power that splines possess. With planned out compositions you can let your program see the note-off coming and react to it more naturally.
In a live system you'd need some way to feed after-touch information to the program while playing the notes to get similar results... and of course you're far better off with wild filters or incremental differential equations than with mathematically well defined splines to do your slides.
I plan to use ChucK for stand alone compositions. And for them I choose quality and control over realtime madness. That's why I use splines.
But the realtime capabilities of ChucK are impressive and it is one of the reasons that I chose it for my platform. Playing with your instruments on a midi piano is a good way to fine tune their parameters. And of course there's nothing like a live improvisation piece played over a well planned background. I'm still far from the level of skill that I could pull off a quality live performance but it's nice to know that with ChucK it could be done. |
|
|
Back to top
|
|
 |
|