I'm trying to translate CSound code from the FLOSS manuals for a van der Pol oscillator to make a Pd external. The CSound code is here http://en.flossmanuals.net/csound/g-physical-modelling/ (you have to scroll down till you reach the van der Pol section). I think I get what's going on there, but the results I get when writing the output to an array, are not the same as the ones provided in th FLOSS manuals.
Here's my perform routine: t_int *vanDerPol_perform(t_int *w) { // Copy the object pointer t_vanDerPol *x = (t_vanDerPol *) (w[1]);
// Copy signal vector pointers t_float *frequency = (t_float *) (w[2]); t_float *factor = (t_float*) (w[3]); t_float *excitor_freq = (t_float*) (w[4]); t_float *excitor_amp = (t_float*) (w[5]); t_float *output = (t_float *) (w[6]);
// Copy the signal vector size t_int n = w[7];
// Dereference components from the object structure float twopi = x->x_twopi; float sr = x->x_sr; float si = x->x_si; float si_factor = x->x_sifactor; float phase = x->x_phase; float step = (float) EXCITOR_STEPSIZE;
// Local variables float phase_local; float drive_sine; // sinewave to excite the oscillator // van der Pol samples float aa; float av = 0; float ax = 0; // damping factor float c;
// Perform the DSP loop while(n--){ // excitor code si = *excitor_freq++ * si_factor; phase_local = phase / step; drive_sine = cos(phase_local * twopi) * *excitor_amp++;
// van der Pol code c = 2 - 2 * cos(*frequency++ * twopi / sr); aa = (-c) * ax + *factor++ * (1 - ax * ax) * av; av += aa; ax = ax + av + drive_sine; *output++ = av;
// update phase phase += si; while(phase > step) phase -= step; while(phase < 0) phase += step; }
// Update object's variables x->x_phase = phase; x->x_si = si;
// Return the next address in the DSP chain return w + 8; }
In the FLOSS manuals it says that it is excited by a sine wave oscillator, so this is what I do in the code above, but I don't know what I'm doing wrong. Are there specific values I should set for frequency, excitation frequency, excitation amplitude and damping? The math is over my head to be honest, so I'm trying to copy an applied example and this code looks much like the CSound's code...Can someone give some insight?
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 2014-08-19 22:09, Alexandros Drymonitis wrote:
Here's my perform routine: t_int *vanDerPol_perform(t_int *w) { // Copy the object pointer t_vanDerPol *x = (t_vanDerPol *) (w[1]);
// Copy signal vector pointers t_float *frequency = (t_float *) (w[2]); t_float *factor = (t_float*) (w[3]); t_float *excitor_freq = (t_float*) (w[4]); t_float *excitor_amp = (t_float*) (w[5]); t_float *output = (t_float *) (w[6]);
the scalar type for signals is really *t_sample*. you should NOT use *t_float* for these kind of things (though in practice they two might always be the same). if you are following a tutorial that suggests to use t_float, then report a bug to the author of the tutorial.
// Copy the signal vector size t_int n = w[7];
// Dereference components from the object structure float twopi = x->x_twopi;
now that looks very much like a constant, which you don't need to modify per-object...
// excitor code si = *excitor_freq++ * si_factor; phase_local = phase / step; drive_sine = cos(phase_local * twopi) * *excitor_amp++;
i guess you are copying the CSound code here. however, i really think it would be much better to use an "external" excitor, that is: instead of having an input for the frequency and another input for the amplitude of the internal sine oscillator, you might want to have a single input for an in-patch sine-oscillator.
so your patch would look like: | [osc~ 666] | [*~ 0.42] | [vanderpol~] |
(it might make sense to make the excitor input the first one, so you can use it
this has two huge advantages: #1 Pd's oscillator is known to work; if it ever breaks, it will be fixed immediately. thus you don't need to re-code existing functionality, possibly introducing bugs.
#2 you might want to use another exciter waveform, and get results unheard of. without any additional coding effort! for free!!
// van der Pol code c = 2 - 2 * cos(*frequency++ * twopi / sr);
again, it might be better to use an external signal to drive this oscillator.
aa = (-c) * ax + *factor++ * (1 - ax * ax) * av; av += aa; ax = ax
- av + drive_sine; *output++ = av;
hmm. you are resetting "av" and "ax" to 0 for each DSP-block. most likely this is not what you want, as the srtucture looks like a feedback filter (IIR), so you need to store ax&av between DSP-blocks.
fgmsdar IOhannes
On Wed, Aug 20, 2014 at 10:30 AM, IOhannes m zmoelnig zmoelnig@iem.at wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 2014-08-19 22:09, Alexandros Drymonitis wrote:
Here's my perform routine: t_int *vanDerPol_perform(t_int *w) { // Copy the object pointer t_vanDerPol *x = (t_vanDerPol *) (w[1]);
// Copy signal vector pointers t_float *frequency = (t_float *) (w[2]); t_float *factor = (t_float*) (w[3]); t_float *excitor_freq = (t_float*) (w[4]); t_float *excitor_amp = (t_float*) (w[5]); t_float *output = (t_float *) (w[6]);
the scalar type for signals is really *t_sample*. you should NOT use *t_float* for these kind of things (though in practice they two might always be the same). if you are following a tutorial that suggests to use t_float, then report a bug to the author of the tutorial.
OK, changed it.
// Copy the signal vector size t_int n = w[7];
// Dereference components from the object structure float twopi = x->x_twopi;
now that looks very much like a constant, which you don't need to modify per-object...
I'm setting its value in the new instance routine by multiplying atan(1.0) by 8, instead of writing it as a macro.
// excitor code si = *excitor_freq++ * si_factor; phase_local = phase / step; drive_sine = cos(phase_local * twopi) * *excitor_amp++;
i guess you are copying the CSound code here. however, i really think it would be much better to use an "external" excitor, that is: instead of having an input for the frequency and another input for the amplitude of the internal sine oscillator, you might want to have a single input for an in-patch sine-oscillator.
so your patch would look like: | [osc~ 666] | [*~ 0.42] | [vanderpol~] |
(it might make sense to make the excitor input the first one, so you can use it
this has two huge advantages: #1 Pd's oscillator is known to work; if it ever breaks, it will be fixed immediately. thus you don't need to re-code existing functionality, possibly introducing bugs.
#2 you might want to use another exciter waveform, and get results unheard of. without any additional coding effort! for free!!
Did that as well.
// van der Pol code c = 2 - 2 * cos(*frequency++ * twopi / sr);
again, it might be better to use an external signal to drive this oscillator.
How? Can you provide a patch example? Or should I just translate this in an abstraction?
aa = (-c) * ax + *factor++ * (1 - ax * ax) * av; av += aa; ax = ax
- av + drive_sine; *output++ = av;
hmm. you are resetting "av" and "ax" to 0 for each DSP-block. most likely this is not what you want, as the srtucture looks like a feedback filter (IIR), so you need to store ax&av between DSP-blocks.
Fixed that too and the result is indeed much better. I don't think though that this implementation is good. The output doesn't really look like the example one finds online. I've attached the .c file if anyone wants to take a look.
fgmsdar IOhannes
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1
iQIbBAEBCAAGBQJT9E58AAoJELZQGcR/ejb4BOIP+PL3nuKFhAMbv3uJDOn6QElf ykV7IpVJ9eWfO8dYUguT/afrUjKbEytWoq0rgC5mKPvKXvWK3OZaIxgQh6D2uqEr /ar1DyCu0daZh8V5ic2PC3QMdF/3eumRyLKyZJ4iWURhSsIrnamwVNONSc00wKPa ck3jQx05Z7v9vgCBFiXpgj1SuyihJSpgCPNU5DYpRmwmvGNt3BgyJv9xKjQFhLvO un3bSjeStijmRftz9g2SwoXQkLrHU2ieHvqBlE4iSj+V9dalxx4SIvH5Bzn74u+X MQMS/ndF8YIvlmnP91F0GXKuVNS8YqbgJsNY+69JEbgLvcZzsCTUUv1MDKyxQrMy 7jr/JGslJcj/DlG9P2xWJ2OeuT7uCv6uhYgGTW2VXYC266hmBQ8BVezl9BmW9PFU yD9UeBie94sNV7R38G48FVdb9hztFVel58hJG3jJjDpVir5zRYITfcv2DMf1xbNb rsrwbkNxxeCY8euhZiaTe03qgOkTYXigwJgfl3D7gY3fPGRd/NFw45sKk7VmmTd1 LLn8DEDOCAUMGG+Nbl/sACy+iJSEy/MmsaNVe0t58W6sYYSmRm37xYm4MtIdwGRP N+PdS3gpUwFPKgzQA+1FMdByh78M9KZu9eqIUoCKxvrU43QFmqT4+wehZx2yNF3/ NhVFjIZx8D6+719+VKA= =mfTs -----END PGP SIGNATURE-----
Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev