From cc2aef7d71eac5d76a849df11e4da1f71ce5f913 Mon Sep 17 00:00:00 2001 From: Ge Wang Date: Thu, 21 Nov 2024 00:37:31 -0800 Subject: [PATCH] add support for runtime sample rate update --- src/core/chuck.cpp | 12 ++++ src/core/chuck_dl.cpp | 11 ++++ src/core/chuck_dl.h | 14 +++-- src/core/chuck_type.cpp | 119 ++++++++++++++++++++++++++++++-------- src/core/chuck_vm.cpp | 68 +++++++++++++++++++++- src/core/chuck_vm.h | 37 +++++++++++- src/core/uana_extract.cpp | 18 ++++-- src/core/ugen_filter.cpp | 8 +++ src/core/ugen_osc.cpp | 12 ++++ src/core/ugen_stk.cpp | 7 +++ src/core/ugen_xxx.cpp | 9 +++ 11 files changed, 279 insertions(+), 36 deletions(-) diff --git a/src/core/chuck.cpp b/src/core/chuck.cpp index 5e5c8a2d3..06661dba1 100644 --- a/src/core/chuck.cpp +++ b/src/core/chuck.cpp @@ -273,6 +273,18 @@ t_CKBOOL ChucK::matchParam( const std::string & lhs, const std::string & rhs ) void ChucK::enactParam( const std::string & name, t_CKINT value ) { // check and set + if( matchParam(name,CHUCK_PARAM_SAMPLE_RATE) ) + { + // check + if( value <= 0 ) + { + EM_error2( 0, "(warning) attempt to set CHUCK_PARAM_SAMPLE_RATE to invalid value '%d'; sample rate unchanged...", value ); + return; + } + // update VM to new sample rate + // (NOTE: this could be pre-initialization, so need to check VM pointer) + if( vm() ) vm()->update_srate( value ); + } if( matchParam(name,CHUCK_PARAM_TTY_COLOR) ) { // set the global override switch diff --git a/src/core/chuck_dl.cpp b/src/core/chuck_dl.cpp index 417168e4d..5bc2800cc 100644 --- a/src/core/chuck_dl.cpp +++ b/src/core/chuck_dl.cpp @@ -859,6 +859,16 @@ void CK_DLL_CALL ck_register_callback_on_shutdown( Chuck_DL_Query * query, f_cal query->vm()->register_callback_on_shutdown( cb, bindle ); } +//----------------------------------------------------------------------------- +// name: ck_register_callback_on_srate_update() | 1.5.4.2 (ge) added +// desc: register a callback function to be called on sample rate change +//----------------------------------------------------------------------------- +void CK_DLL_CALL ck_register_callback_on_srate_update( Chuck_DL_Query * query, f_callback_on_srate_update cb, void * bindle ) +{ + // register + query->vm()->register_callback_on_srate_update( cb, bindle ); +} + //----------------------------------------------------------------------------- // name: ck_register_shreds_watcher() // desc: register a callback function to receive notifications @@ -1435,6 +1445,7 @@ Chuck_DL_Query::Chuck_DL_Query( Chuck_Carrier * carrier, Chuck_DLL * dll ) register_shreds_watcher = ck_register_shreds_watcher; // 1.5.1.5 (ge & andrew) unregister_shreds_watcher = ck_unregister_shreds_watcher; // 1.5.1.5 (ge & andrew) register_callback_on_shutdown = ck_register_callback_on_shutdown; // 1.5.2.5 (ge) + register_callback_on_srate_update = ck_register_callback_on_srate_update; // 1.5.4.2 (ge) m_carrier = carrier; dll_ref = dll; // 1.5.1.3 (ge) added diff --git a/src/core/chuck_dl.h b/src/core/chuck_dl.h index 3a50fe610..983e5ae70 100644 --- a/src/core/chuck_dl.h +++ b/src/core/chuck_dl.h @@ -348,12 +348,12 @@ typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadhook)( void * bindle ); typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadquit)( void * bindle ); // callback function, called on host shutdown typedef void (CK_DLL_CALL * f_callback_on_shutdown)( void * bindle ); +// sample rate update callback | 1.5.4.2 (ge) added +typedef void (CK_DLL_CALL * f_callback_on_srate_update)( t_CKUINT srate, void * bindle ); // shreds watcher callback typedef void (CK_DLL_CALL * f_shreds_watcher)( Chuck_VM_Shred * SHRED, t_CKINT CODE, t_CKINT PARAM, Chuck_VM * VM, void * BINDLE ); // type instantiation callback typedef void (CK_DLL_CALL * f_callback_on_instantiate)( Chuck_Object * OBJECT, Chuck_Type * TYPE, Chuck_VM_Shred * originShred, Chuck_VM * VM ); -// sample rate update callback | 1.5.4.2 (ge) added -typedef void (* ck_f_srate_cb)( t_CKUINT srate, void * userData ); } @@ -426,6 +426,8 @@ typedef t_CKBOOL (CK_DLL_CALL * f_end_class)( Chuck_DL_Query * query ); typedef Chuck_DL_MainThreadHook * (CK_DLL_CALL * f_create_main_thread_hook)( Chuck_DL_Query * query, f_mainthreadhook hook, f_mainthreadquit quit, void * bindle ); // register a callback to be called on host shutdown, e.g., for chugin cleanup typedef void (CK_DLL_CALL * f_register_callback_on_shutdown)( Chuck_DL_Query * query, f_callback_on_shutdown cb, void * bindle ); +// register a callback to be called on sample rate change +typedef void (CK_DLL_CALL * f_register_callback_on_srate_update)( Chuck_DL_Query * query, f_callback_on_srate_update cb, void * bindle ); // register a callback function to receive notification from the VM about shreds (add, remove, etc.) typedef void (CK_DLL_CALL * f_register_shreds_watcher)( Chuck_DL_Query * query, f_shreds_watcher cb, t_CKUINT options, void * bindle ); // unregister a shreds notification callback @@ -622,11 +624,11 @@ struct Chuck_DL_Query public: // ------------- - // register callback to be invoked by chuck host when sample rate changes - // | 1.5.4.2 (ge) added + // register callback to be invoked by chuck host on + // sample rate changes | 1.5.4.2 (ge) added // ------------- - // register sample rate notification - // f_register_srate_change register_srate_change; + f_register_callback_on_srate_update register_callback_on_srate_update; + diff --git a/src/core/chuck_type.cpp b/src/core/chuck_type.cpp index 3917892b1..a14ded583 100644 --- a/src/core/chuck_type.cpp +++ b/src/core/chuck_type.cpp @@ -102,6 +102,8 @@ t_CKBOOL type_engine_check_class_def( Chuck_Env * env, a_Class_Def class_def ); // helpers void type_engine_init_op_overload_builtin( Chuck_Env * env ); +// update builtin durs according to sample rate +t_CKBOOL type_engine_update_builtin_durs( Chuck_Env * env, t_CKUINT srate ); // check for const Chuck_Value * type_engine_check_const( Chuck_Env * env, a_Exp exp ); // convert dot member expression to string for printing @@ -488,6 +490,86 @@ t_CKBOOL type_engine_init_special( Chuck_Env * env, Chuck_Type * objT ) +//----------------------------------------------------------------------------- +// name: type_engine_update_builtin_dur() +// desc: update a specific base duration value +//----------------------------------------------------------------------------- +t_CKBOOL type_engine_update_builtin_dur( Chuck_Env * env, + const string & name, t_CKDUR value ) +{ + // lookup the value + Chuck_Value * v = env->global()->value.lookup( name ); + // check if we found a value + if( !v ) + { + EM_error2( 0, "(internal error) cannot find base dur value '%s' in update_builtin_dur()", name.c_str() ); + return FALSE; + } + // check if the value is a dur + if( !equals( v->type, env->ckt_dur ) ) + { + EM_error2( 0, "(internal error) type mismatch for '%s' in update_builtin_dur()", name.c_str() ); + return FALSE; + } + // cast out the dur + t_CKDUR * pDur = (t_CKDUR *)v->addr; + // check the addr + if( pDur == NULL ) + { + EM_error2( 0, "(internal error) NULL address for '%s' in update_builtin_dur()", name.c_str() ); + return FALSE; + } + // update it to the new value + *pDur = value; + // done + return TRUE; +} + + + + +//----------------------------------------------------------------------------- +// callback from VM +//----------------------------------------------------------------------------- +void type_engine_on_srate_update_cb( t_CKUINT srate, void * userdata ) +{ type_engine_update_builtin_durs( (Chuck_Env *)userdata, srate ); } +//----------------------------------------------------------------------------- +// name: type_engine_update_builtin_durs() +// desc: update built-in durations, given a sample rate +// NOTE: this should be called whenever the system sample rate changes +//----------------------------------------------------------------------------- +t_CKBOOL type_engine_update_builtin_durs( Chuck_Env * env, t_CKUINT srate ) +{ + // dur value + t_CKDUR samp = 1.0; + // TODO: + t_CKDUR second = srate * samp; + // t_CKDUR second = 44100 * samp; + t_CKDUR ms = second / 1000.0; + t_CKDUR minute = second * 60.0; + t_CKDUR hour = minute * 60.0; + t_CKDUR day = hour * 24.0; + t_CKDUR week = day * 7.0; + // one billion years, a very long time + // length of a sidereal year; https://en.wikipedia.org/wiki/Year + t_CKDUR eon = day * 365.256363004 * 1000000000.0; + + // update + if( !type_engine_update_builtin_dur( env, "samp", samp ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "ms", ms ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "second", second ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "minute", minute ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "hour", hour ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "day", day ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "week", week ) ) return FALSE; + if( !type_engine_update_builtin_dur( env, "eon", eon ) ) return FALSE; + + // done + return TRUE; +} + + + //----------------------------------------------------------------------------- // name: type_engine_init() @@ -545,20 +627,6 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier ) env->global()->type.add( env->ckt_cherr->base_name, env->ckt_cherr ); env->ckt_cherr->lock(); // env->global()->type.add( env->ckt_thread->base_name, env->ckt_thread ); env->ckt_thread->lock(); - // dur value - t_CKDUR samp = 1.0; - // TODO: - t_CKDUR second = carrier->vm->srate() * samp; - // t_CKDUR second = 44100 * samp; - t_CKDUR ms = second / 1000.0; - t_CKDUR minute = second * 60.0; - t_CKDUR hour = minute * 60.0; - t_CKDUR day = hour * 24.0; - t_CKDUR week = day * 7.0; - // one billion years, a very long time - // length of a sidereal year; https://en.wikipedia.org/wiki/Year - t_CKDUR eon = day * 365.256363004 * 1000000000.0; - // add internal classes EM_log( CK_LOG_HERALD, "adding base classes..." ); EM_pushlog(); @@ -616,19 +684,19 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier ) // pop indent EM_poplog(); - // default global values + // default global values (except for the durs, which will be updated shortly hereafter) env->global()->value.add( "null", new Chuck_Value( env->ckt_null, "null", new void *(NULL), TRUE ) ); env->global()->value.add( "NULL", new Chuck_Value( env->ckt_null, "NULL", new void *(NULL), TRUE ) ); env->global()->value.add( "t_zero", new Chuck_Value( env->ckt_time, "time_zero", new t_CKDUR(0.0), TRUE ) ); env->global()->value.add( "d_zero", new Chuck_Value( env->ckt_dur, "dur_zero", new t_CKDUR(0.0), TRUE ) ); - env->global()->value.add( "samp", new Chuck_Value( env->ckt_dur, "samp", new t_CKDUR(samp), TRUE ) ); - env->global()->value.add( "ms", new Chuck_Value( env->ckt_dur, "ms", new t_CKDUR(ms), TRUE ) ); - env->global()->value.add( "second", new Chuck_Value( env->ckt_dur, "second", new t_CKDUR(second), TRUE ) ); - env->global()->value.add( "minute", new Chuck_Value( env->ckt_dur, "minute", new t_CKDUR(minute), TRUE ) ); - env->global()->value.add( "hour", new Chuck_Value( env->ckt_dur, "hour", new t_CKDUR(hour), TRUE ) ); - env->global()->value.add( "day", new Chuck_Value( env->ckt_dur, "day", new t_CKDUR(day), TRUE ) ); - env->global()->value.add( "week", new Chuck_Value( env->ckt_dur, "week", new t_CKDUR(week), TRUE ) ); - env->global()->value.add( "eon", new Chuck_Value( env->ckt_dur, "eon", new t_CKDUR(eon), TRUE ) ); + env->global()->value.add( "samp", new Chuck_Value( env->ckt_dur, "samp", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "ms", new Chuck_Value( env->ckt_dur, "ms", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "second", new Chuck_Value( env->ckt_dur, "second", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "minute", new Chuck_Value( env->ckt_dur, "minute", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "hour", new Chuck_Value( env->ckt_dur, "hour", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "day", new Chuck_Value( env->ckt_dur, "day", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "week", new Chuck_Value( env->ckt_dur, "week", new t_CKDUR(0.0), TRUE ) ); + env->global()->value.add( "eon", new Chuck_Value( env->ckt_dur, "eon", new t_CKDUR(0.0), TRUE ) ); env->global()->value.add( "true", new Chuck_Value( env->ckt_int, "true", new t_CKINT(1), TRUE ) ); env->global()->value.add( "false", new Chuck_Value( env->ckt_int, "false", new t_CKINT(0), TRUE ) ); env->global()->value.add( "maybe", new Chuck_Value( env->ckt_int, "maybe", new t_CKFLOAT(.5), FALSE ) ); @@ -637,6 +705,11 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier ) env->global()->value.add( "chout", new Chuck_Value( env->ckt_io, "chout", new Chuck_IO_Chout( carrier ), TRUE ) ); env->global()->value.add( "cherr", new Chuck_Value( env->ckt_io, "cherr", new Chuck_IO_Cherr( carrier ), TRUE ) ); + // update the base dur values, according to initial sample rate | 1.5.4.2 (ge) re-factored to support run-time sample rate updates + type_engine_update_builtin_durs( env, carrier->vm->srate() ); + // register a callback to be notified when sample rate changes | 1.5.4.2 (ge) added + carrier->vm->register_callback_on_srate_update( type_engine_on_srate_update_cb, env ); + // TODO: can't use the following now is local to shred // env->global()->value.add( "now", new Chuck_Value( env->ckt_time, "now", &(vm->shreduler()->now_system), TRUE ) ); diff --git a/src/core/chuck_vm.cpp b/src/core/chuck_vm.cpp index d2b7c19f9..c362d2713 100644 --- a/src/core/chuck_vm.cpp +++ b/src/core/chuck_vm.cpp @@ -379,9 +379,28 @@ t_CKBOOL Chuck_VM::initialize_synthesis() +//----------------------------------------------------------------------------- +// name: update_srate() | 1.5.4.2 (ge) added +// update sample rate (this will also trigger notifications for srate update) +//----------------------------------------------------------------------------- +t_CKBOOL Chuck_VM::update_srate( t_CKUINT srate ) +{ + // log + EM_log( CK_LOG_SYSTEM, "updating sample rate: '%d'...", srate ); + // set it + m_srate = srate; + // notify registered callbacks of the srate update + notify_callbacks_on_srate_update( srate ); + // done + return TRUE; +} + + + + //----------------------------------------------------------------------------- // name: shutdown() -// desc: ... +// desc: shut it down, VM-wise //----------------------------------------------------------------------------- t_CKBOOL Chuck_VM::shutdown() { @@ -1458,6 +1477,29 @@ void Chuck_VM::register_callback_on_shutdown( f_callback_on_shutdown cb, void * +//----------------------------------------------------------------------------- +// name: register_callback_on_srate_update() | 1.5.4.2 (ge) added +// cesc: register a callback to be called on system sample rate update +//----------------------------------------------------------------------------- +void Chuck_VM::register_callback_on_srate_update( f_callback_on_srate_update cb, void * bindle ) +{ + // check + if( !cb ) return; + + // ensure no duplicates + list::iterator it = std::find( m_callbacks_on_srate_update.begin(), + m_callbacks_on_srate_update.end(), cb ); + // add if not already preset + if( it == m_callbacks_on_srate_update.end() ) + { + // append + m_callbacks_on_srate_update.push_back( Chuck_VM_Callback_On_SampleRate_Update(cb, bindle) ); + } +} + + + + //----------------------------------------------------------------------------- // name: notify_callbacks_on_shutdown() // desc: notify callbacks on VM shutdown | 1.5.2.5 (ge) added @@ -1481,6 +1523,30 @@ void Chuck_VM::notify_callbacks_on_shutdown() +//----------------------------------------------------------------------------- +// name: notify_callbacks_on_srate_update() +// desc: notify callbacks on sample rate update | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void Chuck_VM::notify_callbacks_on_srate_update( t_CKUINT srate ) +{ + // the function to call eventually + f_callback_on_srate_update f = NULL; + // iterator + list::iterator it; + // iterate + for( it = m_callbacks_on_srate_update.begin(); + it != m_callbacks_on_srate_update.end(); it++ ) + { + // the function + f = (*it).cb; + // call it with the srate and user data + f( srate, (*it).userdata ); + } +} + + + + //----------------------------------------------------------------------------- // name: notify_watchers() // desc: notify watchers for a particular subscription | 1.5.1.5 diff --git a/src/core/chuck_vm.h b/src/core/chuck_vm.h index 2b9c848e9..e170e95e5 100644 --- a/src/core/chuck_vm.h +++ b/src/core/chuck_vm.h @@ -413,6 +413,33 @@ struct Chuck_VM_Status : public Chuck_Object +//----------------------------------------------------------------------------- +// name: struct Chuck_VM_Callback_On_SampleRate_Update | 1.5.4.2 (ge) added +// desc: an entry for a callback to be called when system sample rate changes +//----------------------------------------------------------------------------- +struct Chuck_VM_Callback_On_SampleRate_Update +{ + // function pointer to call + f_callback_on_srate_update cb; + // user data + void * userdata; + + // constructor + Chuck_VM_Callback_On_SampleRate_Update( f_callback_on_srate_update f = NULL, void * data = NULL ) + : cb(f), userdata(data) { } + + // copy constructor + Chuck_VM_Callback_On_SampleRate_Update( const Chuck_VM_Callback_On_SampleRate_Update & other ) + : cb(other.cb), userdata(other.userdata) { } + + // == + bool operator ==( const Chuck_VM_Callback_On_SampleRate_Update & other ) + { return this->cb == other.cb && this->userdata == other.userdata; } +}; + + + + //----------------------------------------------------------------------------- // name: struct Chuck_VM_Callback_On_Shutdown // desc: an entry for a callback to be called on VM shutdown @@ -434,7 +461,7 @@ struct Chuck_VM_Callback_On_Shutdown // == bool operator ==( const Chuck_VM_Callback_On_Shutdown & other ) - { return this->cb == other.cb; } + { return this->cb == other.cb && this->userdata == other.userdata; } }; @@ -594,6 +621,8 @@ struct Chuck_VM : public Chuck_Object t_CKBOOL shutdown(); // return whether VM is initialized t_CKBOOL has_init() { return m_init; } + // update sample rate (this will also trigger notifications for srate update) + t_CKBOOL update_srate( t_CKUINT srate ); public: // run state; 1.3.5.3 // run start @@ -688,10 +717,14 @@ struct Chuck_VM : public Chuck_Object public: // register a callback to be called on VM shutdown | 1.5.2.5 (ge) added void register_callback_on_shutdown( f_callback_on_shutdown cb, void * bindle ); + // register a callback to be called on system sample rate update | 1.5.4.2 (ge) added + void register_callback_on_srate_update( f_callback_on_srate_update cb, void * bindle ); protected: // notify callbacks on VM shutdown | 1.5.2.5 (ge) added void notify_callbacks_on_shutdown(); + // notify callbacks on sample rate update | 1.5.4.2 (ge) added + void notify_callbacks_on_srate_update( t_CKUINT srate ); //----------------------------------------------------------------------------- // data @@ -773,6 +806,8 @@ struct Chuck_VM : public Chuck_Object protected: // 1.5.2.5 (ge) on major VM events callbacks std::list m_callbacks_on_shutdown; + // 1.5.4.2 (ge) on system sample rate update + std::list m_callbacks_on_srate_update; }; diff --git a/src/core/uana_extract.cpp b/src/core/uana_extract.cpp index 156615c58..42c9558b7 100644 --- a/src/core/uana_extract.cpp +++ b/src/core/uana_extract.cpp @@ -193,7 +193,13 @@ void xcorr_fft( SAMPLE * f, t_CKINT fs, SAMPLE * g, t_CKINT gs, SAMPLE * buffer, void xcorr_normalize( SAMPLE * buffy, t_CKINT bs, SAMPLE * f, t_CKINT fs, SAMPLE * g, t_CKINT gs ); // 1.4.2.0 (ge) | local global sample rate variable (e.g., for MFCC) -static t_CKUINT g_srate = 0; +static t_CKUINT g_uana_srate = 0; + +//----------------------------------------------------------------------------- +// this is called for this module to know when sample rate changes | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void uana_srate_update_cb( t_CKUINT srate, void * userdata ) { g_uana_srate = srate; } + @@ -207,7 +213,9 @@ DLL_QUERY extract_query( Chuck_DL_Query * QUERY ) Chuck_DL_Func * func = NULL; // 1.4.2.0 (ge) | store sample rate - g_srate = QUERY->srate(); + g_uana_srate = QUERY->srate(); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, uana_srate_update_cb, NULL ); std::string doc; @@ -1212,7 +1220,7 @@ struct MFCC_Object MFCC_Object() { size = 1024; - sample_rate = g_srate; + sample_rate = g_uana_srate; num_filters = 10; num_coeffs = 40; curr_sample_rate = 0.0; @@ -1676,7 +1684,7 @@ struct SFM_Object SFM_Object() { size = 0; - sample_rate = g_srate; + sample_rate = g_uana_srate; nr_bands = 0; nr_valid_bands = 0; edge = NULL; @@ -1927,7 +1935,7 @@ struct Chroma_Object Chroma_Object() { size = 1024; - sample_rate = g_srate; + sample_rate = g_uana_srate; low_oct_num = 0; high_oct_num = 8; curr_sample_rate = 0; diff --git a/src/core/ugen_filter.cpp b/src/core/ugen_filter.cpp index e472dcc8f..ccf5b4f41 100644 --- a/src/core/ugen_filter.cpp +++ b/src/core/ugen_filter.cpp @@ -49,6 +49,11 @@ static t_CKUINT FilterBasic_offset_data = 0; static t_CKUINT Teabox_offset_data = 0; static t_CKUINT biquad_offset_data = 0; +//----------------------------------------------------------------------------- +// this is called for this module to know when sample rate changes | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void filter_srate_update_cb( t_CKUINT srate, void * userdata ) { g_srateFilter = srate; } + @@ -60,6 +65,9 @@ DLL_QUERY filter_query( Chuck_DL_Query * QUERY ) { // set srate g_srateFilter = QUERY->srate(); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, filter_srate_update_cb, NULL ); + // set radians per sample g_radians_per_sample = CK_TWO_PI / (t_CKFLOAT)g_srateFilter; diff --git a/src/core/ugen_osc.cpp b/src/core/ugen_osc.cpp index f42d8ea94..4872761ca 100644 --- a/src/core/ugen_osc.cpp +++ b/src/core/ugen_osc.cpp @@ -44,6 +44,13 @@ static t_CKUINT g_srateOsc = 0; // for member data offset static t_CKUINT osc_offset_data = 0; +//----------------------------------------------------------------------------- +// this is called for this module to know when sample rate changes | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void osc_srate_update_cb( t_CKUINT srate, void * userdata ) { g_srateOsc = srate; } + + + //----------------------------------------------------------------------------- // name: osc_query() @@ -53,6 +60,8 @@ DLL_QUERY osc_query( Chuck_DL_Query * QUERY ) { // srate g_srateOsc = QUERY->srate(); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, osc_srate_update_cb, NULL ); // get the env Chuck_Env * env = QUERY->env(); @@ -1068,6 +1077,9 @@ DLL_QUERY genX_query( Chuck_DL_Query * QUERY ) { // srate g_srateOsc = QUERY->srate(); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, osc_srate_update_cb, NULL ); + // get the env Chuck_Env * env = QUERY->env(); std::string doc; diff --git a/src/core/ugen_stk.cpp b/src/core/ugen_stk.cpp index 565a796ee..0b6c6c9d8 100644 --- a/src/core/ugen_stk.cpp +++ b/src/core/ugen_stk.cpp @@ -1302,6 +1302,11 @@ CK_DLL_MFUN( MidiFileIn_readTrack ); CK_DLL_MFUN( MidiFileIn_rewind ); CK_DLL_MFUN( MidiFileIn_rewindTrack ); +//----------------------------------------------------------------------------- +// this is called for this module to know when sample rate changes | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void stk_srate_update_cb( t_CKUINT srate, void * userdata ) { Stk::setSampleRate( srate ); } + @@ -1320,6 +1325,8 @@ DLL_QUERY stk_query( Chuck_DL_Query * QUERY ) // https://github.com/ccrma/chuck/issues/208 // set srate Stk::setSampleRate( QUERY->srate() ); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, stk_srate_update_cb, NULL ); // test for endian what w; w.x = 1; diff --git a/src/core/ugen_xxx.cpp b/src/core/ugen_xxx.cpp index 4157e417b..b851b8ce4 100644 --- a/src/core/ugen_xxx.cpp +++ b/src/core/ugen_xxx.cpp @@ -110,6 +110,11 @@ enum PanTypesEnum PAN_LINEAR // not supported }; +//----------------------------------------------------------------------------- +// this is called for this module to know when sample rate changes | 1.5.4.2 (ge) added +//----------------------------------------------------------------------------- +void xxx_srate_update_cb( t_CKUINT srate, void * userdata ) { g_srateXxx = srate; } + @@ -119,7 +124,11 @@ enum PanTypesEnum //----------------------------------------------------------------------------- DLL_QUERY xxx_query( Chuck_DL_Query * QUERY ) { + // set sample rate for this module g_srateXxx = QUERY->srate(); + // register callback to be notified if/when sample rate changes | 1.5.4.2 (ge) added + QUERY->register_callback_on_srate_update( QUERY, xxx_srate_update_cb, NULL ); + // get the env Chuck_Env * env = QUERY->env();