Just started using ChucK and greatly enjoying myself. Not much music (or even noise) as yet, just learning the language for now. Not understanding the various `sync' options, I was setting a SinOsc's phase explicitly and wasn't getting what I expected. On inspection of the source there was a minor typo in CK_DLL_CTRL(osc_ctrl_phase), which I fixed. While I was there I tidied up the range checking of input parameters (including those used via `sync', which I now understand *grin*), particularly so that negative frequencies are handled cleanly. The original code contained snippets like "if( d->num <= 1.0 ) d->num += floor( d->num )" that can't of been doing what anyone wanted them to do. The same sort of changes and range checking probably ought to be done elsewhere in the code too, such as in the sndbuf ugen, but that's a job for another day. I'm also not convinced that the code to adjust the phase in CK_DLL_CTRL(osc_ctrl_sync) can be correct. It certainly should only be done if ugen->m_num_src is non-zero; but even then, I imagine pld's comment there is correct. Again, for another day. Attached is a diff patch against the current CVS version. I can't imagine you'll need any form of assignment for so small a change, but please use the attached code in anyway you want for any purpose you see fit. It comes with no warranty, but it has been compiled and vaguely tested on x86 Windows XP (under Cygwin) and PPC Mac OS X 10.4 (with a recent copy of the developers tools). Now, back to making some noise. All the best and thanks for the great system, Conrad Index: ugen_osc.cpp =================================================================== RCS file: /cvs/chuck_dev/v2/ugen_osc.cpp,v retrieving revision 1.44 diff -c -3 -p -r1.44 ugen_osc.cpp *** ugen_osc.cpp 22 Mar 2007 00:49:51 -0000 1.44 --- ugen_osc.cpp 8 Jul 2007 23:38:50 -0000 *************** CK_DLL_TICK( osc_tick ) *** 303,317 **** d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // synch phase to input else if( d->sync == 1 ) { // set phase d->phase = in; // no update inc_phase = FALSE; } --- 303,318 ---- d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // synch phase to input else if( d->sync == 1 ) { // set phase d->phase = in; + // bound it (+0 <= d->phase < 1) + if( d->phase <= 0 || d->phase >= 1 ) d->phase -= floor( d->phase ); // no update inc_phase = FALSE; } *************** CK_DLL_TICK( osc_tick ) *** 322,330 **** t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync to now // else if( d->sync == 3 ) --- 323,330 ---- t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync to now // else if( d->sync == 3 ) *************** CK_DLL_TICK( osc_tick ) *** 337,349 **** // set output to current phase *out = (SAMPLE)d->phase; ! // check if( inc_phase ) { - // step the phase. d->phase += d->num; ! // keep the phase between 0 and 1 ! if( d->phase > 1.0 ) d->phase -= 1.0; } return TRUE; --- 337,349 ---- // set output to current phase *out = (SAMPLE)d->phase; ! // advance internal phase if( inc_phase ) { d->phase += d->num; ! // bound it (+0 <= d->phase <= 1) ! if( d->phase < 0 ) d->phase += 1; ! else if( d->phase >= 1 ) d->phase -= 1; } return TRUE; *************** CK_DLL_TICK( sinosc_tick ) *** 373,387 **** d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; inc_phase = FALSE; } // FM synthesis --- 373,389 ---- d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; + // bound it (+0 <= d->phase < 1) + if( d->phase <= 0 || d->phase >= 1 ) d->phase -= floor( d->phase ); + // no update inc_phase = FALSE; } // FM synthesis *************** CK_DLL_TICK( sinosc_tick ) *** 391,399 **** t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync phase to now // else if( d->sync == 3 ) --- 393,400 ---- t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync phase to now // else if( d->sync == 3 ) *************** CK_DLL_TICK( sinosc_tick ) *** 406,417 **** // set output *out = (SAMPLE) ::sin( d->phase * TWO_PI ); if( inc_phase ) { - // next phase d->phase += d->num; ! // keep the phase between 0 and 1 ! if( d->phase > 1.0 ) d->phase -= 1.0; } return TRUE; --- 407,419 ---- // set output *out = (SAMPLE) ::sin( d->phase * TWO_PI ); + // advance internal phase if( inc_phase ) { d->phase += d->num; ! // bound it (+0 <= d->phase <= 1) ! if( d->phase < 0 ) d->phase += 1; ! else if( d->phase >= 1 ) d->phase -= 1; } return TRUE; *************** CK_DLL_TICK( triosc_tick ) *** 441,455 **** d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; inc_phase = FALSE; } // FM synthesis --- 443,459 ---- d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; + // bound it (+0 <= d->phase < 1) + if( d->phase <= 0 || d->phase >= 1 ) d->phase -= floor( d->phase ); + // no update inc_phase = FALSE; } // FM synthesis *************** CK_DLL_TICK( triosc_tick ) *** 459,467 **** t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync to now // if( d->sync == 3 ) --- 463,470 ---- t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync to now // if( d->sync == 3 ) *************** CK_DLL_TICK( triosc_tick ) *** 480,487 **** if( inc_phase ) { d->phase += d->num; ! // keep the phase between 0 and 1 ! if( d->phase > 1.0 ) d->phase -= 1.0; } return TRUE; --- 483,491 ---- if( inc_phase ) { d->phase += d->num; ! // bound it (+0 <= d->phase <= 1) ! if( d->phase < 0 ) d->phase += 1; ! else if( d->phase >= 1 ) d->phase -= 1; } return TRUE; *************** CK_DLL_TICK( pulseosc_tick ) *** 512,526 **** d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; inc_phase = FALSE; } // FM synthesis --- 516,532 ---- d->freq = in; // phase increment d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync phase to input else if( d->sync == 1 ) { // set freq d->phase = in; + // bound it (+0 <= d->phase < 1) + if( d->phase <= 0 || d->phase >= 1 ) d->phase -= floor( d->phase ); + // no update inc_phase = FALSE; } // FM synthesis *************** CK_DLL_TICK( pulseosc_tick ) *** 530,538 **** t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= floor( d->num ); ! else if( d->num <= 1.0 ) d->num += floor( d->num ); } // sync to now // if( d->sync == 3 ) --- 536,543 ---- t_CKFLOAT freq = d->freq + in; // phase increment d->num = freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); } // sync to now // if( d->sync == 3 ) *************** CK_DLL_TICK( pulseosc_tick ) *** 545,556 **** // compute *out = (SAMPLE) (d->phase < d->width) ? 1.0 : -1.0; ! // move phase if( inc_phase ) { d->phase += d->num; ! // keep the phase between 0 and 1 ! if( d->phase > 1.0 ) d->phase -= 1.0; } return TRUE; --- 550,562 ---- // compute *out = (SAMPLE) (d->phase < d->width) ? 1.0 : -1.0; ! // advance internal phase if( inc_phase ) { d->phase += d->num; ! // bound it (+0 <= d->phase <= 1) ! if( d->phase < 0 ) d->phase += 1; ! else if( d->phase >= 1 ) d->phase -= 1; } return TRUE; *************** CK_DLL_CTRL( osc_ctrl_freq ) *** 572,579 **** d->freq = GET_CK_FLOAT(ARGS); // phase increment d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= ::floor( d->num ); // return RETURN->v_float = (t_CKFLOAT)d->freq; } --- 578,585 ---- d->freq = GET_CK_FLOAT(ARGS); // phase increment d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); // return RETURN->v_float = (t_CKFLOAT)d->freq; } *************** CK_DLL_CTRL( osc_ctrl_period ) *** 610,617 **** // set freq else d->freq = 1 / (period / d->srate); d->num = d->freq / d->srate; ! // bound it ! if( d->num >= 1.0 ) d->num -= ::floor( d->num ); // return RETURN->v_dur = period; } --- 616,623 ---- // set freq else d->freq = 1 / (period / d->srate); d->num = d->freq / d->srate; ! // bound it (-1 < d->num < 1) ! if( d->num <= -1 || d->num >= 1 ) d->num -= int(d->num); // return RETURN->v_dur = period; } *************** CK_DLL_CTRL( osc_ctrl_phase ) *** 649,656 **** Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->phase = GET_CK_FLOAT(ARGS); ! //bound ( this could be set arbitrarily high or low ) ! if ( d->phase >= 1.0 || d->phase < 0.0 ) d->phase -= floor( d->num ); // return RETURN->v_float = (t_CKFLOAT)d->phase; } --- 655,662 ---- Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->phase = GET_CK_FLOAT(ARGS); ! // bound it (+0 <= d->phase < 1) ! if( d->phase <= 0 || d->phase >= 1 ) d->phase -= floor( d->phase ); // return RETURN->v_float = (t_CKFLOAT)d->phase; } *************** CK_DLL_CTRL( osc_ctrl_width ) *** 683,689 **** Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->width = GET_CK_FLOAT(ARGS); ! //bound ( this could be set arbitrarily high or low ) d->width = ck_max( 0.0, ck_min( 1.0, d->width ) ); // return RETURN->v_float = (t_CKFLOAT)d->width; --- 689,695 ---- Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->width = GET_CK_FLOAT(ARGS); ! // bound ( this could be set arbitrarily high or low ) d->width = ck_max( 0.0, ck_min( 1.0, d->width ) ); // return RETURN->v_float = (t_CKFLOAT)d->width; *************** CK_DLL_CTRL( sawosc_ctrl_width ) *** 762,768 **** Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->width = GET_CK_FLOAT(ARGS); ! //bound ( this could be set arbitrarily high or low ) d->width = ( d->width < 0.5 ) ? 0.0 : 1.0; //rising or falling // return RETURN->v_float = (t_CKFLOAT)d->width; --- 768,774 ---- Osc_Data * d = (Osc_Data *)OBJ_MEMBER_UINT(SELF, osc_offset_data ); // set freq d->width = GET_CK_FLOAT(ARGS); ! // bound ( this could be set arbitrarily high or low ) d->width = ( d->width < 0.5 ) ? 0.0 : 1.0; //rising or falling // return RETURN->v_float = (t_CKFLOAT)d->width; *************** CK_DLL_CTRL( osc_ctrl_sync ) *** 793,800 **** // we need to pre-advance the phase... // this is probably stupid. -pld d->phase += d->num; ! // keep the phase between 0 and 1 ! if( d->phase > 1.0 ) d->phase -= 1.0; } // return RETURN->v_int = (t_CKINT)d->sync; --- 799,807 ---- // we need to pre-advance the phase... // this is probably stupid. -pld d->phase += d->num; ! // bound it (0 <= phase < 1) ! if( d->phase < 0 ) d->phase += 1; ! else if( d->phase >= 1 ) d->phase -= 1; } // return RETURN->v_int = (t_CKINT)d->sync;
participants (1)
-
Conrad Scott