[chuck-dev] wishlist and bugreport of hacking (from chuck list)

Ge Wang gewang at CS.Princeton.EDU
Fri Dec 10 00:31:19 EST 2004


>> They actually can, in a semi-hack way.  dur and time are passed as
>> double-precision floats (or t_CKDUR and t_CKTIME).  When defining
>> the prototype, you only need to specify "dur" or "time".  The semantic
>> of both is that they both count samples (or fractions thereof).  
>> There are
>> ways of converting samples to sample-rate independent time, the
>> most basic of which is to normalize by the system sample rate in 
>> Digitalio.
>>
>
> So, what would it look like? Say I want to build a freqtodelay tool 
> that takes a frequency and returns the dur corresponding to the 
> wavelength. (I know, it's silly, but I want to get a hang of it...)
>
> In my foobar_query function (registered in chuck_main, together with 
> the ulib_foo things)  I include
>   QUERY->add_export(QUERY, "dur", "freqtodelay", freqtodelay_impl, 
> TRUE);
>   QUERY->add_param(QUERY, "float", "frequency");
> ....
> and where does the time come in? Or is it impossible to -return- 
> durations too?

This should work just fine.  (just remember to return a float that is 
the number of samples (using Digitalio to go from seconds etc to 
samples))

>>> * The handling of parameter input to ulib functions is severely 
>>> flawed,
>>>   including lack of type security across platforms and probably not
>>>   64-bit secured:
>>
>> Um, yes - there are some egregious hacks in that area of the code.  We
>> have tried to alleviate the data width with consistent types across 
>> the
>> system (t_CKFLOAT, t_CKINT, etc), and hopefully a configure script 
>> would
>> be able to resolve that across platforms.
>>
>
> There are already some macros taking care of stepping through arcane 
> arrays (the GET_NEXT_FLOAT et.c. family) - why not make sure there are 
> similar for the argument reading? The hack we finally got working was 
> the following:
> char* name = GET_CK_STRING(ARGS); (char*)ARGS+=sizeof(char*);
> t_CKFLOAT foo = GET_CK_FLOAT(ARGS);
>
> with the (foo*)ARGS+=sizeof(foo*) being repeated for every nonfinal 
> argument to be read... All this should be easy to wrap in a macro so 
> that all we really need to do is
> char* name = GET_CK_STRING(ARGS);
> t_CKFLOAT foo = GET_CK_FLOAT(ARGS);
> with the GET_CK_FOO automatically incrementing as we go along...

Yes - foo is out of date for this...

the macros you mentioned are made for this purpose:

// param conversion
#define GET_CK_FLOAT(ptr)      (*(t_CKFLOAT *)ptr)
#define GET_CK_SINGLE(ptr)     (*(float *)ptr)
#define GET_CK_DOUBLE(ptr)     (*(double *)ptr)
#define GET_CK_INT(ptr)        (*(t_CKINT *)ptr)
#define GET_CK_UINT(ptr)       (*(t_CKUINT *)ptr)
#define GET_CK_TIME(ptr)       (*(t_CKTIME *)ptr)
#define GET_CK_DUR(ptr)        (*(t_CKDUR *)ptr)
#define GET_CK_STRING(ptr)     (*(char **)ptr)

// param conversion with pointer advance
#define GET_NEXT_FLOAT(ptr)    (*((t_CKFLOAT *&)ptr)++)
#define GET_NEXT_SINGLE(ptr)   (*((float *&)ptr)++)
#define GET_NEXT_DOUBLE(ptr)   (*((double *&)ptr)++)
#define GET_NEXT_INT(ptr)      (*((t_CKINT *&)ptr)++)
#define GET_NEXT_UINT(ptr)     (*((t_CKUINT *&)ptr)++)
#define GET_NEXT_TIME(ptr)     (*((t_CKTIME *&)ptr)++)
#define GET_NEXT_DUR(ptr)      (*((t_CKDUR *&)ptr)++)
#define GET_NEXT_STRING(ptr)   (*((char * *&)ptr)++)

there are set macros as well.

Ge!



More information about the chuck-dev mailing list