I am attempting a merge of the PDa integer code with Pd-vanilla 0.43. Vanilla now mostly had the t_sample/t_float stuff ironed out, but there are a few minor differences between the two that I am not sure of. Here's the first that is in a bunch of places, including in d_arithmetic.c:
vanilla: t_float g = *(t_float *)(w[2]);
PDa: t_sample g = ftofix(*(t_float *)(w[2]));
It seems to me that 'g' should be t_sample, not t_float. Any ideas?
.hc
----------------------------------------------------------------------------
I have the audacity to believe that peoples everywhere can have three meals a day for their bodies, education and culture for their minds, and dignity, equality and freedom for their spirits. - Martin Luther King, Jr.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
I am attempting a merge of the PDa integer code with Pd-vanilla 0.43. Vanilla now mostly had the t_sample/t_float stuff ironed out, but there are a few minor differences between the two that I am not sure of. Here's the first that is in a bunch of places, including in d_arithmetic.c:
vanilla: t_float g = *(t_float *)(w[2]);
PDa: t_sample g = ftofix(*(t_float *)(w[2]));
It seems to me that 'g' should be t_sample, not t_float. Any ideas?
g is the scalar argument given to the object (or set via a message).
when i tried to clean up the t_sample / t_float code, the decisions i made where based on where the values come from: - - a sample within a signal vector is always t_sample - - a number in a message is always t_float - - a number in an object's argument should always be t_floatarg.
the idea is, that that the signal and the messages might have different numeric types (as is the case in PdA)
now t_float and t_floatarg are certainly mixed up often. but i tried to get the line between t_sample (signal) and t_float (not signal) right.
therefore "g" is t_float and not t_sample in the first place. it should _then_ be converted into a t_sample, before the actual arithmetic is being done on the incoming signal (of t_samples). this could be done in one line, but it probably should not, for readability's sake.
fgasmr IOhannes
On Jan 1, 2010, at 2:47 PM, IOhannes m zmölnig wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
I am attempting a merge of the PDa integer code with Pd-vanilla 0.43. Vanilla now mostly had the t_sample/t_float stuff ironed out, but there are a few minor differences between the two that I am not sure of. Here's the first that is in a bunch of places, including in d_arithmetic.c:
vanilla: t_float g = *(t_float *)(w[2]);
PDa: t_sample g = ftofix(*(t_float *)(w[2]));
It seems to me that 'g' should be t_sample, not t_float. Any ideas?
g is the scalar argument given to the object (or set via a message).
when i tried to clean up the t_sample / t_float code, the decisions i made where based on where the values come from:
- a sample within a signal vector is always t_sample
- a number in a message is always t_float
- a number in an object's argument should always be t_floatarg.
the idea is, that that the signal and the messages might have different numeric types (as is the case in PdA)
now t_float and t_floatarg are certainly mixed up often. but i tried to get the line between t_sample (signal) and t_float (not signal) right.
therefore "g" is t_float and not t_sample in the first place. it should _then_ be converted into a t_sample, before the actual arithmetic is being done on the incoming signal (of t_samples). this could be done in one line, but it probably should not, for readability's sake.
fgasmr IOhannes
Here's the code in question, from PDa:
#define ftofix(a) ((t_sample)( (a) *(double)fixfac + 0.5))
t_int *scalarplus_perf8(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_sample g = ftofix(*(t_float *)(w[2])); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); for (; n; n -= 8, in += 8, out += 8) { t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3]; t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
out[0] = f0 + g; out[1] = f1 + g; out[2] = f2 + g; out[3] = f3 + g; out[4] = f4 + g; out[5] = f5 + g; out[6] = f6 + g; out[7] = f7 + g; } return (w+5); }
So based on your comments, it would go something like this, which seems needlessly verbose and wasteful of CPU cycles:
#define ftofix(a) ((t_sample)( (a) *(double)fixfac + 0.5))
t_int *scalarplus_perf8(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_float g = *(t_float *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); for (; n; n -= 8, in += 8, out += 8) { t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3]; t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
out[0] = f0 + ftofix(g); out[1] = f1 + ftofix(g); out[2] = f2 + ftofix(g); out[3] = f3 + ftofix(g); out[4] = f4 + ftofix(g); out[5] = f5 + ftofix(g); out[6] = f6 + ftofix(g); out[7] = f7 + ftofix(g); } return (w+5); }
.hc
----------------------------------------------------------------------------
Computer science is no more related to the computer than astronomy is related to the telescope. -Edsger Dykstra
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
Here's the code in question, from PDa:
ah which reminds me of the thing i forgot in my last email: please add line numbers when you refer to a sepcific line in a file. <snip> d_arithhmetic.c: t_float g = *(t_float *)(w[2]); </snip> is a bit vague for my taste (ever tried to grep for "int i" :-))
So based on your comments, it would go something like this, which seems needlessly verbose and wasteful of CPU cycles:
[...]
out[0] = f0 + ftofix(g); out[1] = f1 + ftofix(g); out[2] = f2 +
ftofix(g); out[3] = f3 + ftofix(g);
i guess you are not trying to be nasty on purpose :-) i can't see how your interpretation makes the code more readable.
i was trying to say something along: <code>
t_int *scalarplus_perf8(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_float g_f = *(t_float *)(w[2]); t_sample g = ftofix(g_f); [...] out[0] = f0+g; out[1] = f1+g; out[2] = f2+g; out[3] = f3+g; </code>
this would take as much cycles as t_sample g = ftofix(*(t_float *)(w[2])); but separate the code for getting the value and making it a sample.
fgasdmr IOhannes
On Jan 1, 2010, at 3:21 PM, IOhannes m zmölnig wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
Here's the code in question, from PDa:
ah which reminds me of the thing i forgot in my last email: please add line numbers when you refer to a sepcific line in a file.
<snip> d_arithhmetic.c: t_float g = *(t_float *)(w[2]); </snip> is a bit vague for my taste (ever tried to grep for "int i" :-))
So based on your comments, it would go something like this, which seems needlessly verbose and wasteful of CPU cycles:
[...]
out[0] = f0 + ftofix(g); out[1] = f1 + ftofix(g); out[2] =
f2 + ftofix(g); out[3] = f3 + ftofix(g);
i guess you are not trying to be nasty on purpose :-) i can't see how your interpretation makes the code more readable.
i was trying to say something along:
<code>
t_int *scalarplus_perf8(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_float g_f = *(t_float *)(w[2]); t_sample g = ftofix(g_f); [...] out[0] = f0+g; out[1] = f1+g; out[2] = f2+g; out[3] = f3+g;
</code>
this would take as much cycles as t_sample g = ftofix(*(t_float *)(w[2])); but separate the code for getting the value and making it a sample.
This would obviously work better that my code, but I still don't see the point of using a t_float there. All three lines are casting t_ints from w into values that then get added together to be a t_sample so why use anything the middle? On PDa that means casting a t_int to a t_float then to an int (i.e. t_sample) for no reason.
.hc
----------------------------------------------------------------------------
Mistrust authority - promote decentralization. - the hacker ethic
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
This would obviously work better that my code, but I still don't see the point of using a t_float there. All three lines are casting t_ints from w into values that then get added together to be a t_sample so why use anything the middle? On PDa that means casting a t_int to a t_float then to an int (i.e. t_sample) for no reason.
w[2] is t_int* to be something pointable. you cast it to t_float because the value really is a t_float. then you convert it to a t_sample, because this is what you need. on PDa it is the same;
you can never get around these three casts, if you want it to work correctly. you can do "magic" if you believe that this will make the compiled code faster (in most cases it won't) and you don't care for readability and maintainability.
mfgasdr IOhannes
On Jan 1, 2010, at 4:22 PM, IOhannes m zmölnig wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hans-Christoph Steiner wrote:
This would obviously work better that my code, but I still don't see the point of using a t_float there. All three lines are casting t_ints from w into values that then get added together to be a t_sample so why use anything the middle? On PDa that means casting a t_int to a t_float then to an int (i.e. t_sample) for no reason.
w[2] is t_int* to be something pointable. you cast it to t_float because the value really is a t_float. then you convert it to a t_sample, because this is what you need. on PDa it is the same;
you can never get around these three casts, if you want it to work correctly. you can do "magic" if you believe that this will make the compiled code faster (in most cases it won't) and you don't care for readability and maintainability.
Ok, that makes sense. I'm curious why its not a t_sample* or void* instead of a t_int*. That certainly makes things less readable.
.hc
----------------------------------------------------------------------------
kill your television