Csound Csound-dev Csound-tekno Search About

[Cs-dev] Problems with csoundTableGet()

Date2005-08-20 04:23
FromIain Duncan
Subject[Cs-dev] Problems with csoundTableGet()
Attachmentscs_simple_2.c  cs_simple.csd  
I've managed to get some simple threading working with the api, but 
can't get csoundTableGet() to work. The app compiles but csound exits as 
  soon as I try to use csoundTabelGet()

- the pointer to csound is global
- i try calling it from the main thread after spawning a csound thread, dies
- i try calling it from the yield call back routine, dies also

If anyone can tell me what is wrong here that would be great.

Thanks
Iain

Date2005-08-20 13:02
FromIstvan Varga
SubjectRe: [Cs-dev] Problems with csoundTableGet()
Iain Duncan wrote:

> I've managed to get some simple threading working with the api, but 
> can't get csoundTableGet() to work. The app compiles but csound exits as 
>  soon as I try to use csoundTabelGet()
> 
> - the pointer to csound is global
> - i try calling it from the main thread after spawning a csound thread, 
> dies
> - i try calling it from the yield call back routine, dies also
> 
> If anyone can tell me what is wrong here that would be great.

Beware that the yield callback may be called at a time when the table
does not exist. Before accessing the table, use csoundTableLength to
find out if the table exists (has length >= 1).
Another (not related) issue is that accessing the same instance of
Csound from multiple threads is unsafe, and you may get occasional
crashes unless using locks around calls of Csound API functions.


-------------------------------------------------------
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

Date2005-08-20 13:55
FromIstvan Varga
SubjectRe: [Cs-dev] Problems with csoundTableGet()
Attachmentscs_simple_2.c  
Here is a version with some fixes. It could be implemented in a much
more simple way, though, particularly without threads.

Date2005-08-20 17:45
FromIain Duncan
SubjectRe: [Cs-dev] Problems with csoundTableGet()
Thanks Istvan, I'll try this out later at work. I would be interested in 
seeing the simple way too if you have time. ( I will definitely need 
threads eventually though. )

Iain

Istvan Varga wrote:
> Here is a version with some fixes. It could be implemented in a much
> more simple way, though, particularly without threads.
> 
> 
> ------------------------------------------------------------------------
> 
> // cs_simple_2.c
> // Adds a csound yield callback
> 
> #include 
> #include 
> 
> // Csound state variables:
> 
> // pointer to an instance of csound
> CSOUND *csound;
> 
> // boolean to tell us if csound is running
> bool cs_performing = false;
> bool cs_thread_yield = false;
> 
> // an empty user_data pointer ( would be the data for the csound thread routine )
> void *user_data = NULL;
> 
> void *cs_lock = NULL;
> void *cs_lock_2 = NULL;
> 
> // the routine for the csound thread
> // csoundCreateThread requires the thread routine to return int and take a void pointer as an arg
> uintptr_t csound_thread_routine( void *user_data );
> 
> // the yield callback routine
> int cs_yield_routine(CSOUND *user_data);
> 
> 
> int main( void )
> {
> 	RTCLOCK	clk;
> 	double	prv_time = 0.0;
> 	cs_lock = csoundCreateThreadLock();
> 	cs_lock_2 = csoundCreateThreadLock();
> 	csoundWaitThreadLock( cs_lock_2, 10000 );
> 	cs_thread_yield = true;
> 	int attr = CSOUNDMSG_FG_BOLD | CSOUNDMSG_FG_GREEN;
> 
> 	// 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" );
> 
> 	int index = 0;
> 	timers_struct_init(&clk);
> 	for( ; ; )
> 	{
> 		double	cur_time = timers_get_real_time(&clk);
> 		if (cur_time >= 2.0)		// run for 2 seconds
> 			break;
> 		if (cur_time - prv_time < 0.04) { // print 25 values per second
> 			csoundNotifyThreadLock( cs_lock_2 );
> 			continue;
> 		}
> 		prv_time = cur_time;
> 		// an index counter to roam through our table
> 		if ( index < 8192 ) index++;
> 		else index = 0;
> 
> 		printf( "Index is: %d\n", index );
> 
> 		// try reading a table value, this kills everything
> 		MYFLT table_value;
> 		csoundWaitThreadLock( cs_lock, 10000 );
> 		if (csoundTableLength( csound, 1 ) > 0) {
> 			table_value = csoundTableGet( csound, 1, index );
> 			csoundMessageS(csound, attr, "Index is: %d\n", index );
> 			csoundMessageS(csound, attr, "LFO value is: %5.2f.\n", float( table_value ) );
> 		}
> 		csoundNotifyThreadLock( cs_lock_2 );
> 		csoundNotifyThreadLock( cs_lock );
> 	}
> 	cs_thread_yield = false;
> 	csoundNotifyThreadLock( cs_lock_2 );
> 
> 	//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 ));
> 	printf("Csound returns %d\n", cs_result);
> 	return cs_result;
> }
> 
> uintptr_t csound_thread_routine(void *user_data)
> {
> 	int	retval;
> 	printf("Csound thread executing.\n");
> 
> 	// starting csound
> 	const char *argv[] = {"csound", "-+rtaudio=alsa", "-odac", "cs_simple.csd" };
> 	//const char *argv[] = {"csound", "-W", "-otest.wav", "cs_simple.csd" };
> 	csoundWaitThreadLock( cs_lock, 10000 );
> 	retval = csoundCompile(csound, 4, (char **)argv);
> 	csoundNotifyThreadLock( cs_lock );
> 
> 	if (!retval) {
> 		// cs_performing is set by Csound, and go is set by the user
> 		cs_performing = true;
> 		while( cs_performing )
> 		{
> 			// Csound will call cb_thread_yield.
> 			csoundWaitThreadLock( cs_lock, 10000 );
> 			retval = csoundPerformKsmps(csound);
> 			csoundNotifyThreadLock( cs_lock );
> 			cs_performing = !retval;
> 			if (cs_thread_yield)
> 				csoundWaitThreadLock( cs_lock_2, 10000 );
> 		}
> 	}
> 	// we are done, so clean up
> 	csoundWaitThreadLock( cs_lock, 10000 );
> 	csoundCleanup(csound);
> 	csoundReset(csound);
> 	csoundNotifyThreadLock( cs_lock );
> 
> 	printf( "Csound thread all done!\n" );
> 
> 	retval = (retval > 0 ? 0 : retval);
> 	return (uintptr_t) ((unsigned int) retval);
> }
> 
> 
> int cs_yield_routine(CSOUND *user_data)
> {
> 	if (!cs_performing || csoundTableLength( user_data, 1 ) <= 0)
> 		return 1;
> 	// an index counter to roam through our table
> 	static int index = 0;
> 	if ( index < 8192 )
> 		index++;
> 	else
> 		index = 0;
> 	if (index & 15)		// print less frequently
> 		return 1;
> 
> 	printf( "Index is: %d\n", index );
> 
> 	// try reading a table value, doesn't work here either, kills csound
> 	MYFLT table_value;
> 	table_value = csoundTableGet( user_data, 1, index );
> 
> 	printf("LFO value is: %5.2f.\n", float( table_value ) );
> 
> 	// yield routine should return 1 to signal that everything is a ok.
> 	return 1;
> }
> 


-------------------------------------------------------
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

Date2005-08-20 17:54
FromIain Duncan
SubjectRe: [Cs-dev] Problems with csoundTableGet()
Istvan, ( or anyone else ), would it require less in the way of 
protection to get results out of csound using the inchannel and 
outchannel callback routines? Or will I still be in the same boat as far 
as getting result values from csound in other threads?

In general, what would be the recommended way of getting a given number 
of values in and out on every kpass given a multi-threaded app?

Thanks
iain

Istvan Varga wrote:
> Iain Duncan wrote:
> 
>> I've managed to get some simple threading working with the api, but 
>> can't get csoundTableGet() to work. The app compiles but csound exits 
>> as  soon as I try to use csoundTabelGet()
>>
>> - the pointer to csound is global
>> - i try calling it from the main thread after spawning a csound 
>> thread, dies
>> - i try calling it from the yield call back routine, dies also
>>
>> If anyone can tell me what is wrong here that would be great.
> 
> 
> Beware that the yield callback may be called at a time when the table
> does not exist. Before accessing the table, use csoundTableLength to
> find out if the table exists (has length >= 1).
> Another (not related) issue is that accessing the same instance of
> Csound from multiple threads is unsafe, and you may get occasional
> crashes unless using locks around calls of Csound API functions.
> 
> 
> -------------------------------------------------------
> 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
> https://lists.sourceforge.net/lists/listinfo/csound-devel
> 


-------------------------------------------------------
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

Date2005-08-20 18:36
FromIstvan Varga
SubjectRe: [Cs-dev] Problems with csoundTableGet()
Not sure if this is of much use for you, but you can register a function
with csoundRegisterSenseEventCallback() that will be called by Csound at
performance time - and only at performance time - once in every control
period (thus it is more predictable than the yield callback).
This function runs in the same thread as csoundPerformKsmps, and can safely
make use of the plugin API in the CSOUND structure (excluding any functions
designed specifically for opcodes e.g. InitError). You can then implement
some form of communication (with synchronization using thread locks) between
this callback and any other threads; some examples of using this method
include InOut/widgets.cpp and Opcodes/OSC.c.

Iain Duncan wrote:

> Istvan, ( or anyone else ), would it require less in the way of 
> protection to get results out of csound using the inchannel and 
> outchannel callback routines? Or will I still be in the same boat as far 
> as getting result values from csound in other threads?
> 
> In general, what would be the recommended way of getting a given number 
> of values in and out on every kpass given a multi-threaded app?


-------------------------------------------------------
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