| Thanks Istvan, I will try a new build of csound and see how that goes.
Could you tell me if you have time why the changes are made? And why do
I need to use csound thread and mutex functions for threads that are not
to do with csound? What specifically prevents use of pthreads and
pthread mutex's, or how are the csound ones better? Also, why are the
return types changed to uintptr_t?
Thanks so much for your time on this
Iain
Istvan Varga wrote:
> After a few minor changes to make it compile with the latest CVS
> version of Csound, I could not reproduce the problem. The attached
> file (requires an up to date Csound library) works OK, but again,
> I had no problems - other than the compile errors - with the original
> either.
>
>
> ------------------------------------------------------------------------
>
> // cs_simple_3.c
>
> // adding a value output structure for sending values to and from csound
> // protected by a mutex
>
> #include
> #include
> #include
>
> // csound table number for output values
> const int out_tbl = 2;
> const char *csd_file = "cs_simple_lfo.csd";
>
> // array and mutex for the csound output values
> struct csound_output
> {
> void *mtx;
> float data[16];
> } cs_out;
>
> // Csound state variables:
>
> // pointer to an instance of csound
> CSOUND *csound;
>
> // boolean to tell us if csound is running
> volatile bool display_thread_stop = false;
>
> // an empty user_data pointer ( would be the data for the csound thread routine )
> void *user_data = NULL;
>
> // the routine for the csound thread
> uintptr_t csound_thread_routine( void *user_data );
>
> // the display thread
> uintptr_t display_thread_routine( void *cs_out_data );
>
> // the table value we want to get from csound
> MYFLT table_value;
> float result;
>
> int main( void )
> {
>
> // initialize the mutex for the output values
> cs_out.mtx = csoundCreateThreadLock();
>
> // make our display thread
> void *display_thread;
> display_thread = csoundCreateThread( display_thread_routine, NULL );
>
> // create an instance of csound with no user data
> csound = csoundCreate( NULL );
>
> // cb_thread_yield will get called whenever csound has spare time to do other stuff
> // csoundSetYieldCallback(csound, &cs_yield_routine);
>
> // create a csound thread
> // returns a thread handle pointer, takes pointers to the thread routine and to user data
> void *cs_thread = csoundCreateThread( csound_thread_routine, user_data );
>
> printf( "\n\n SPAWNING CSOUND THREAD.\n\n" );
>
> //printf("LFO value is: %5.2f.\n", float( table_value ) );
> // wait on the csound thread until it is done
> int cs_result = (int) ((unsigned int) csoundJoinThread( cs_thread ));
> display_thread_stop = true;
> // wait for our display thread to exit too
> csoundJoinThread( display_thread );
> printf("Csound thread returned %d\n", cs_result);
> return cs_result;
> }
>
>
> uintptr_t csound_thread_routine(void *user_data)
> {
> printf("Csound thread executing.\n");
>
> // the below does not allow console output for some reason
> const char *argv[] = {"csound", "-+rtaudio=alsa", "-odac", csd_file };
> //csoundCompile(csound, 4, (char **)argv);
>
> // the below makes everything work
> // const char *argv[] = {"csound", "cs_simple_lfo.csd" };
> int retval = csoundCompile(csound, sizeof(argv) / sizeof(char*),
> (char **)argv);
>
> // go is set by the user
> // int index = 0;
> double prvTime, curTime;
> RTCLOCK rt;
> timers_struct_init(&rt);
> prvTime = timers_get_real_time(&rt);
> while( ! retval ) {
> // perform csound for a ksmp
> retval = csoundPerformKsmps(csound);
> if (retval) break;
>
> // get all our output values, protected with mutex
> int result = csoundWaitThreadLock( cs_out.mtx, 1000 );
> if ( result ) {
> printf("Timeout in Csound thread\n");
> return (uintptr_t) ((intptr_t) -1);
> }
>
> for ( int i = 0; i < 16; i++ )
> {
> table_value = csoundTableGet( csound, 2, i );
> cs_out.data[i] = float(table_value);
> }
>
> csoundNotifyThreadLock( cs_out.mtx );
>
> // the below works fine when not using -odac
> // with -odac, no printing ever happens, even with spawining other threads
> curTime = timers_get_real_time(&rt);
> if (curTime - prvTime >= 0.1) { // print 10 values per second
> printf( "Csound thread. LFO value is: %5.3f\n", cs_out.data[0] );
> prvTime = curTime;
> }
>
> }
> // we are done, so clean up
> csoundCleanup(csound);
> printf( "Csound thread all done!\n" );
> retval = (retval == CSOUND_EXITJMP_SUCCESS ? 0 : retval);
> return (uintptr_t) ((intptr_t) retval);
>
> }
>
> // this is running but it sure doesn't seem to get the table data
> uintptr_t display_thread_routine( void *cs_out_data )
> {
> MYFLT lfo_value;
> void *mtx = csoundCreateThreadLock();
> csoundWaitThreadLock(mtx, 1);
>
> while ( ! display_thread_stop )
> {
> // get the lfo value from the csound output structure
> int result = csoundWaitThreadLock( cs_out.mtx, 1000 );
> if ( result ) {
> printf("Timeout in display thread\n");
> return (uintptr_t) ((intptr_t) -1);
> }
> lfo_value = cs_out.data[0];
> csoundNotifyThreadLock( cs_out.mtx );
>
> // without -odac the below prints a moving lfo value
> // with -odac it only ever prints a 0.00
> printf("Display thread. LFO value is: %5.3f\n\n", lfo_value);
> // hack to implement 100 ms sleep (does not work on Mac)
> csoundWaitThreadLock(mtx, 100);
> }
>
> return 0;
> }
>
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
Csound-devel mailing list
Csound-devel@lists.sourceforge.net |