[chuck-users] Solved: stereo ugens yet once more
Lukas Degener
degenerl at cs.uni-bonn.de
Tue Apr 24 19:25:06 EDT 2007
Lukas Degener schrieb:
> hi again,
>
> could you tell me what's the current state of affairs concerning stereo
> (multi-channel) ugens?
>
> I'm looking through the code and I can see that there is somthing going
> on, but I was not yet able to completely grasp the idea. :-)
>
> I see I can specify in and outs in type_engine_import_ugen_begin(...),
> Further it seems that for each channel, a "sub"-ugen is generated for
> me, everything basically looks put in place allready...so...
>
> How do I control how those "sub-ugens" are ticked? Would it be wise to
> just set their tick function pointer directly?
I just tried exactly that. And, yes, it does works.
Here's a summary:
1) In the DLL_QUERY function, I make sure my ugen inherits UGen_Stereo.
(...)
if( !type_engine_import_ugen_begin( env, "Knarzomat", "UGen_Stereo",
env->global(),
knarzomat_ctor, knarzomat_dtor,
knarzomat_tick, NULL ) )
(...)
2) I used the "constructor" of my custom ugen to rewire the tick
callbacks of the left and right channel.
CK_DLL_CTOR( knarzomat_ctor ){
Knarzomat * d = new Knarzomat();
OBJ_MEMBER_UINT(SELF, knarzomat_offset_data) = (t_CKUINT)d;
/* don't try this at home :-) */
Chuck_UGen * me = ((Chuck_UGen *)SELF);
me->m_multi_chan[0]->tick = knarzomat_tick_left;
me->m_multi_chan[1]->tick = knarzomat_tick_right;
}
3) Finally, my tick callbacks look like this:
Knarzomat::tick(double) causes the ugen to calculate a sample for both
channels.
The result is stored in Knarzomat::leftOut and Knarzomat::rightOut.
The argument of the tick method is used to avoid redundant calculations.
CK_DLL_TICK(knarzomat_tick){
t_CKDOUBLE t = ((Chuck_UGen *)SELF)->m_time;
Knarzomat * d =(Knarzomat *)OBJ_MEMBER_UINT(SELF,
knarzomat_offset_data );
d->tick(t);
*out = d->leftOut+d->rightOut;
return TRUE;
}
CK_DLL_TICK(knarzomat_tick_left){
t_CKDOUBLE t = ((Chuck_UGen *)SELF)->m_time;
Chuck_UGen * owner = ((Chuck_UGen *)SELF)->owner;
Knarzomat * d =(Knarzomat *)OBJ_MEMBER_UINT(owner,
knarzomat_offset_data );
d->tick(t);
*out = d->leftOut;
return TRUE;
}
CK_DLL_TICK(knarzomat_tick_right){
t_CKDOUBLE t = ((Chuck_UGen *)SELF)->m_time;
Chuck_UGen * owner = ((Chuck_UGen *)SELF)->owner;
Knarzomat * d =(Knarzomat *)OBJ_MEMBER_UINT(owner,
knarzomat_offset_data );
d->tick(t);
*out = d->rightOut;
return TRUE;
}
That's it. Works right away.
Probably not the most elegant solution, though. Please let me know if I
did anything particulary stupid. :-)
Best Regards,
--lu
More information about the chuck-users
mailing list