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