Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30643
Modified Files: Tag: devel_0_37 d_soundfile.c Log Message: threaded soundfiler
Index: d_soundfile.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/d_soundfile.c,v retrieving revision 1.1.1.2.2.3 retrieving revision 1.1.1.2.2.4 diff -C2 -d -r1.1.1.2.2.3 -r1.1.1.2.2.4 *** d_soundfile.c 6 May 2004 08:28:12 -0000 1.1.1.2.2.3 --- d_soundfile.c 10 May 2004 18:18:26 -0000 1.1.1.2.2.4 *************** *** 13,16 **** --- 13,18 ---- for Windows if someone were willing to find a Pthreads package for it. */
+ /* threaded soundfiler by Tim Blechmann */ + #ifdef UNIX #include <unistd.h> *************** *** 29,32 **** --- 31,35 ---- #define MAXSFCHANS 64
+ /***************** soundfile header structures ************************/
*************** *** 862,870 ****
/* ------- soundfiler - reads and writes soundfiles to/from "garrays" ---- */ - #define DEFMAXSIZE 4000000 /* default maximum 16 MB per channel */ - #define SAMPBUFSIZE 1024
! static t_class *soundfiler_class;
typedef struct _soundfiler --- 865,876 ----
/* ------- soundfiler - reads and writes soundfiles to/from "garrays" ---- */
+ #ifndef THREADED_SF + #define DEFMAXSIZE 4000000 /* default maximum 16 MB per channel */ + #else + #define DEFMAXSIZE 40000000 /* threaded we should be able to hande a bit more */ + #endif
! #define SAMPBUFSIZE 1024
typedef struct _soundfiler *************** *** 874,877 **** --- 880,1004 ---- } t_soundfiler;
+ + + #ifdef THREADED_SF + #include <sched.h> + + static pthread_t sf_thread_id; /* id of soundfiler thread */ + static pthread_attr_t sf_attr; + + typedef struct _sfprocess + { + void (* process) (t_soundfiler *, + t_symbol *, int, t_atom *); /* function to call */ + t_soundfiler * x; /* and arguments */ + int argc; + t_atom * argv; + struct _sfprocess * next; /* next object in queue */ + } t_sfprocess; + + /* this is the queue for all soundfiler objects */ + typedef struct _sfqueue + { + t_sfprocess * begin; + t_sfprocess * end; + pthread_mutex_t mutex; + pthread_cond_t cond; + } t_sfqueue; + + static t_sfqueue * soundfiler_queue; + + /* we fill the queue */ + void soundfile_queue_add(void (* process) (t_soundfiler *,t_symbol *, + int,t_atom *), t_soundfiler * x, + int argc, t_atom * argv) + { + + t_atom * largv = copybytes (argv, argc * sizeof(t_atom)); + + t_sfprocess * last_entry=getbytes(sizeof(t_sfprocess)); + + last_entry->process=process; + last_entry->x=x; + last_entry->argc=argc; + last_entry->argv=largv; + last_entry->next=NULL; + + /* inform the queue and the last element */ + pthread_mutex_lock(&(soundfiler_queue->mutex)); + + if (soundfiler_queue->begin==NULL) + soundfiler_queue->begin=last_entry; + if (soundfiler_queue->end!=NULL) + soundfiler_queue->end->next=last_entry; + soundfiler_queue->end=last_entry; + pthread_mutex_unlock(&(soundfiler_queue->mutex)); + + /* and signal the helper thread */ + pthread_cond_signal(&(soundfiler_queue->cond)); + } + + /* global soundfiler thread ... sleeping until signaled */ + void soundfiler_thread() + { + + struct sched_param sf_param; + sf_param.sched_priority=sched_get_priority_min(SCHED_FIFO); + + if (sched_setscheduler(0,SCHED_FIFO,&sf_param) != -1) + fprintf(stderr, "priority %d scheduling for soundfiler.\n", + sf_param.sched_priority); + + while (1) + { + #ifdef DEBUG + post("Soundfiler sleeping"); + #endif + pthread_cond_wait(&soundfiler_queue->cond, &soundfiler_queue->mutex); + #ifdef DEBUG + post("Soundfiler awake"); + #endif + /* work on the queue */ + while (soundfiler_queue->begin!=NULL) + { + t_sfprocess * me = soundfiler_queue->begin; + pthread_mutex_unlock(&(soundfiler_queue->mutex)); + + /* running the specific function */ + me->process(me->x, NULL, me->argc, me->argv); + + pthread_mutex_lock(&(soundfiler_queue->mutex)); + soundfiler_queue->begin=me->next; + + freebytes(me->argv,sizeof(t_atom)* me->argc); + freebytes(me,sizeof(t_sfprocess)); + + }; + soundfiler_queue->end=NULL; + } + + } + + /* create soundfiler thread */ + void sys_start_sfthread() + { + soundfiler_queue = getbytes (sizeof(t_sfqueue)); + + pthread_mutex_init (&soundfiler_queue->mutex,NULL); + pthread_cond_init (&soundfiler_queue->cond,NULL); + soundfiler_queue->begin=soundfiler_queue->end=NULL; + + if (pthread_create(&sf_thread_id, NULL , + soundfiler_thread,NULL) !=0) + error("Couldn't create soundfiler thread"); + else + post("global soundfiler thread launched"); + } + + #endif /* THREADED_SF */ + + static t_class *soundfiler_class; + + static t_soundfiler *soundfiler_new(void) { *************** *** 897,900 **** --- 1024,1028 ---- int argc, t_atom *argv) { + int headersize = -1, channels = 0, bytespersamp = 0, bigendian = 0, resize = 0, i, j; *************** *** 1212,1215 **** --- 1340,1361 ---- }
+ + #ifdef THREADED_SF + + static void soundfiler_twrite(t_soundfiler *x, t_symbol *s, + int argc, t_atom *argv) + { + soundfile_queue_add(soundfiler_write,x,argc, argv); + } + + static void soundfiler_tread(t_soundfiler *x, t_symbol *s, + int argc, t_atom *argv) + { + soundfile_queue_add(soundfiler_read,x,argc, argv); + } + + + #endif /* THREADED_SF */ + static void soundfiler_setup(void) { *************** *** 1220,1223 **** --- 1366,1375 ---- class_addmethod(soundfiler_class, (t_method)soundfiler_write, gensym("write"), A_GIMME, 0); + #ifdef THREADED_SF + class_addmethod(soundfiler_class, (t_method)soundfiler_tread, + gensym("t_read"), A_GIMME, 0); + class_addmethod(soundfiler_class, (t_method)soundfiler_twrite, + gensym("t_write"), A_GIMME, 0); + #endif /* THREADED_SF */ }