Hello everybody!
I’m diving into GEN routine development to learn some C and for a university class.
Over the past few days, I’ve written a GEN routine based on the Lorenz attractor to generate control data. My C code compiles and runs inside Csound, but I’m confused about the output of the GEN routine.
I’ve implemented a scaling function to map the values in the table to a specified range (e.g., between a minimum and maximum), but the results aren’t as expected. To debug, I’ve added printf statements in the C code to check the intermediate values, and everything seems fine there.
However, when I use ftprint in Csound, the table values don’t match what the C code prints. For example, if I scale the values to the range [3, 10], I end up with values in Csound between 0.3 and 1.0. The scaling logic in the C code seems correct, so I’m unsure why the output is wrong.
Here are some thoughts on what might be causing the issue:
• Csound might be normalizing the table values to fit within the range [-1, 1], and values outside this range might not be allowed.
• I could be compiling my GEN routine incorrectly.
Below is my C code and my compile command — maybe there’s an error I’ve overlooked. Any help would be greatly appreciated!
Thank you!
—Philipp
gcc -shared -o lorenz-gen.dylib -I/Library/Frameworks/CsoundLib64.framework/Versions/6.0/Headers/ lorenz-gen.c
\#include "csdl\.h"
\#include "csoundCore\.h"
/\*
p3 = size
p4 = GEN routine
p5 = choose axis to write; 0 = x, 1 = y, 2 = z
p6 = min output
p7 = max output
p8 = stepsize
p9 = x start
p10 = y start
p11 = z start
f1 0 4096 "lorenz" "x" \-1 1 5
\*/
void scale\_array\(MYFLT \*fp, MYFLT min\_out, MYFLT max\_out, int32\_t size\)
\{
MYFLT min\_in = fp\[0\];
MYFLT max\_in = fp\[0\];
for\(int i = 1; i < size; i\+\+\)\{
if\(fp\[i\] < min\_in\)
min\_in = fp\[i\];
if\(fp\[i\] > max\_in\)
max\_in = fp\[i\];
\}
MYFLT old\_value;
for\(int j = 0; j < size; j\+\+\)\{
old\_value = fp\[j\];
printf\("old value: %f\\n", old\_value\);
fp\[j\] = min\_out \+ \(\(old\_value \- min\_in\) / \(max\_in \- min\_in\)\)
\* \(max\_out \- min\_out\);
printf\("new value: %f\\ns",fp\[j\]\);
printf\("sohuld value: %f\\n", \(min\_out \+ \(\(old\_value \- min\_in\) / \(max\_in \- min\_in\)\)
\* \(max\_out \- min\_out\)\)\);
\}
\}
static int32\_t lorenztable\(FGDATA \*ff, FUNC \*ftp\)
\{
/\* function table \*/
MYFLT \*fp = ftp\->ftable;
/\* default arguments \*/
MYFLT sigma = 10;
MYFLT rho = 28;
MYFLT beta = 8\.0/3\.0;
MYFLT time = 0\.001;
/\* p\-field arguments \*/
int32\_t ft\_size = ftp\->flen;
MYFLT min\_out = ff\->e\.p\[6\];
MYFLT max\_out = ff\->e\.p\[7\];
MYFLT step\_size = ff\->e\.p\[8\];
MYFLT x = ff\->e\.p\[9\];
MYFLT y = ff\->e\.p\[10\];
MYFLT z = ff\->e\.p\[11\];
/\* write raw data to ft \*/
for \(int i = 0; i < ft\_size; i\+\+\)
\{
if \(ff\->e\.p\[5\] == 0\)\{
fp\[i\] = x;
\} else if \(ff\->e\.p\[5\] == 1\)\{
fp\[i\] = y;
\} else if \(ff\->e\.p\[5\] == 2\)\{
fp\[i\] = z;
\}
for \(int j = 0; j < step\_size; j\+\+\)\{
x \+= \(sigma \* \(y \- z\)\) \* time;
y \+= \(x \* \(rho \- z\) \- y\) \* time;
z \+= \(\(x \* y\) \- \(beta \* z\)\) \* time;
\}
\}
/\* scale data of ft \*/
scale\_array\(fp, min\_out, max\_out, ft\_size\);
return OK;
\}
static NGFENS localfgens\[\] = \{
\{ "lorenz", lorenztable\},
\{ NULL, NULL\}
\};
FLINKAGE\_BUILTIN\(localfgens\)
\`\`\`
Csound mailing list
Csound@listserv\.heanet\.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here