[PD-dev] t_sample vs t_float in PDa vs vanilla

Hans-Christoph Steiner hans at at.or.at
Fri Jan 1 21:08:05 CET 2010


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






More information about the Pd-dev mailing list