[PD-cvs] pd/src d_soundfile.c,1.1.1.2.2.4,1.1.1.2.2.5

Tim Blechmann timblech at users.sourceforge.net
Thu May 27 20:27:45 CEST 2004


Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23673

Modified Files:
      Tag: devel_0_37
	d_soundfile.c 
Log Message:
the threaded soundfiler is working now...

Index: d_soundfile.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/d_soundfile.c,v
retrieving revision 1.1.1.2.2.4
retrieving revision 1.1.1.2.2.5
diff -C2 -d -r1.1.1.2.2.4 -r1.1.1.2.2.5
*** d_soundfile.c	10 May 2004 18:18:26 -0000	1.1.1.2.2.4
--- d_soundfile.c	27 May 2004 18:27:42 -0000	1.1.1.2.2.5
***************
*** 871,877 ****
  #define DEFMAXSIZE 40000000 	/* threaded we should be able to hande a bit more */
  #endif
- 
  #define SAMPBUFSIZE 1024
  
  typedef struct _soundfiler
  {
--- 871,878 ----
  #define DEFMAXSIZE 40000000 	/* threaded we should be able to hande a bit more */
  #endif
  #define SAMPBUFSIZE 1024
  
+ #include <string.h>
+ 
  typedef struct _soundfiler
  {
***************
*** 880,886 ****
--- 881,890 ----
  } t_soundfiler;
  
+ static t_class *soundfiler_class;
+ 
  
  
  #ifdef THREADED_SF
+ //#define DEBUG
  #include <sched.h>
  
***************
*** 888,901 ****
  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
--- 892,913 ----
  static pthread_attr_t sf_attr;
  
+ typedef enum
+ {
+     S_SOUNDFILER,
+     S_ARRAY
+ } t_sfobjecttype;
+ 
  typedef struct _sfprocess
  {
!     void (* process) (t_soundfiler *,t_symbol *, 
! 		      int, t_atom *); /* function to call */
!     t_soundfiler * x;        /* soundfiler */
!     int argc;  
      t_atom * argv;
      struct _sfprocess * next;  /* next object in queue */
+     pthread_mutex_t mutex;
  } t_sfprocess;
  
+ 
  /* this is the queue for all soundfiler objects */
  typedef struct _sfqueue
***************
*** 910,922 ****
  
  /* 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;
--- 922,953 ----
  
  /* we fill the queue */
! void soundfiler_queue_add(void (* process) (t_soundfiler *,t_symbol *,
! 					   int,t_atom *), void * x, 
  			 int argc, t_atom * argv)
  {
+     /* preparing argument vector */
+     t_atom * largv =  copybytes (argv, argc * sizeof(t_atom));
+     static int i;
  
!     // make sure that the argument vector doesn't get lost 
!     for (i = 0; i != argc; ++i)
!     {
! 	if ( (largv+i)->a_type == A_SYMBOL)
! 	{
! 	    /* we'll have to free these again!!! */
! 	    t_symbol * sym1 = getbytes(sizeof(t_symbol));
! 	    sym1->s_name = copybytes((largv+i)->a_w.w_symbol->s_name,
! 				      strlen((largv+i)->a_w.w_symbol->s_name)
! 				      * (sizeof(char)+1) );
! 	    sym1->s_thing = (largv+i)->a_w.w_symbol->s_thing;
! 	    sym1->s_next = (largv+i)->a_w.w_symbol->s_next;
! 	    (largv+i)->a_w.w_symbol=sym1;
! 	}
!     }
!     
!     /* preparing entry */
      t_sfprocess * last_entry=getbytes(sizeof(t_sfprocess));
!     pthread_mutex_init(&(last_entry->mutex), NULL);
!     pthread_mutex_lock(&(last_entry->mutex));
      last_entry->process=process;
      last_entry->x=x;
***************
*** 924,946 ****
      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);
--- 955,999 ----
      last_entry->argv=largv;
      last_entry->next=NULL; 
!     pthread_mutex_unlock(&(last_entry->mutex));
! 
      /* inform the queue and the last element */ 
      pthread_mutex_lock(&(soundfiler_queue->mutex));
  
      if (soundfiler_queue->begin==NULL)
+     {
  	soundfiler_queue->begin=last_entry;
! 	soundfiler_queue->end=last_entry;
!     }
!     else 
!     {
! 	pthread_mutex_lock(&(soundfiler_queue->end->mutex));
  	soundfiler_queue->end->next=last_entry;
! 	pthread_mutex_unlock(&(soundfiler_queue->end->mutex));
! 	soundfiler_queue->end=last_entry;
!     }
  
!     if ( soundfiler_queue->begin == soundfiler_queue->end )
!     {
! 	/* we should start the helper thread */
! #ifdef DEBUG
! 	post("signaling");
! #endif
! 	pthread_mutex_unlock(&(soundfiler_queue->mutex));
! 	/* and signal the helper thread */
! 	pthread_cond_signal(&(soundfiler_queue->cond));
!     }
!     else
!     {
! #ifdef DEBUG
! 	post("not signaling");
! #endif
! 	pthread_mutex_unlock(&(soundfiler_queue->mutex));
!     }
!     return;
  }
  
  /* global soundfiler thread ... sleeping until signaled */
! void soundfiler_thread(void)
  {    
      struct sched_param sf_param;
      sf_param.sched_priority=sched_get_priority_min(SCHED_FIFO);
***************
*** 956,977 ****
  #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;
--- 1009,1112 ----
  #endif
  	pthread_cond_wait(&soundfiler_queue->cond, &soundfiler_queue->mutex);
+ 	pthread_mutex_unlock(&(soundfiler_queue->mutex)); 
  #ifdef DEBUG
  	post("Soundfiler awake");
  #endif
  	/* work on the queue */
+ 	
+ 	pthread_mutex_lock(&(soundfiler_queue->mutex));
  	while (soundfiler_queue->begin!=NULL)
  	{
! 	    /* locking process */
! 	    pthread_mutex_lock(&(soundfiler_queue->begin->mutex));
! 
! 	    /* create a copy that we can work on */
! 	    t_sfprocess * me = copybytes(soundfiler_queue->begin, 
! 					 sizeof(t_sfprocess));
! 	    
! 	    me->argv = copybytes (soundfiler_queue->begin->argv, 
! 				  soundfiler_queue->begin->argc * sizeof(t_atom));
! 	    
! 	    static int i;
! 	    for (i = 0; i != me->argc; ++i)
! 	    {
! 		if ( (soundfiler_queue->begin->argv+i)->a_type == A_SYMBOL)
! 		    {
! 		    t_symbol * sym1 = getbytes(sizeof(t_symbol));
! 		    sym1->s_name = copybytes((soundfiler_queue->begin->argv+i)
! 					     ->a_w.w_symbol-> s_name,
! 					     strlen((soundfiler_queue->begin
! 						     ->argv+i)->a_w.w_symbol
! 						    ->s_name)
! 					     * (sizeof(char)+1) );
! 		    sym1->s_thing = (soundfiler_queue->begin->argv+i)
! 			->a_w.w_symbol->s_thing;
! 		    sym1->s_next = (soundfiler_queue->begin->argv+i)
! 			->a_w.w_symbol->s_next;
! 		    (me->argv+i)->a_w.w_symbol=sym1;
! 		}
! 	    }
! 		
! 	    pthread_mutex_unlock(&(soundfiler_queue->begin->mutex));
! 
! 	    
  	    pthread_mutex_unlock(&(soundfiler_queue->mutex)); 
+ #ifdef DEBUG
+ 	    post("soundfiler: mutex unlocked, running process");
+ #endif
  
  	    /* running the specific function */
+ 
  	    me->process(me->x, NULL, me->argc, me->argv);
! #ifdef DEBUG
! 	    post("soundfiler: process done, locking mutex");
! #endif
! 	    
  	    pthread_mutex_lock(&(soundfiler_queue->mutex));
! 	    pthread_mutex_lock(&(soundfiler_queue->begin->mutex));
! 	    
! 	    /* freeing the memory we allocated */
! 	    for (i = 0; i != soundfiler_queue->begin->argc; ++i)
! 	    {
! 		if ((soundfiler_queue->begin->argv+i)->a_type == A_SYMBOL)
! 		{
! 		    /* the string */
! 		    freebytes( (soundfiler_queue->begin->argv+i)->
! 			       a_w.w_symbol->s_name, 
! 			       strlen((soundfiler_queue->begin->argv+i)->
! 				      a_w.w_symbol->s_name)
! 			       * (sizeof(char)+1) ); 
! 		    /* the symbol */
! 		    freebytes( (soundfiler_queue->begin->argv+i)->a_w.w_symbol, 
! 			       sizeof(t_symbol) ); 
! 		}
! 	    }
! 	    
! 	    /* the argument vector */
! 	    freebytes(soundfiler_queue->begin->argv,sizeof(t_atom) 
! 		      * soundfiler_queue->begin->argc); 
  
! 	    /* the process struct */
! 	    t_sfprocess * next=soundfiler_queue->begin->next;
! 	    freebytes(soundfiler_queue->begin,sizeof(t_sfprocess));
! 	    soundfiler_queue->begin=next;
  
+ 	    /* we'll have to free the memory again */
+ 	    for (i = 0; i != me->argc; ++i)
+ 	    {
+ 		if ( (me->argv+i)->a_type == A_SYMBOL)
+ 		{
+ 		    /* the string */
+ 		    freebytes( (me->argv+i)->a_w.w_symbol->s_name, 
+ 			       strlen((me->argv+i)->a_w.w_symbol->s_name)
+ 			       * (sizeof(char)+1) ); 
+ 		    /* the symbol */
+ 		    freebytes( (me->argv+i)->a_w.w_symbol, sizeof(t_symbol) );
+ 		}
+ 	    }
+ 	    /* the argument vector */
+ 	    freebytes(me->argv,sizeof(t_atom) * me->argc);
+ 	    /* the process struct */
+ 	    freebytes(me,sizeof(t_sfprocess));
  	};
  	soundfiler_queue->end=NULL;
***************
*** 981,985 ****
  
  /* create soundfiler thread */
! void sys_start_sfthread()
  {
      soundfiler_queue = getbytes (sizeof(t_sfqueue));
--- 1116,1120 ----
  
  /* create soundfiler thread */
! void sys_start_sfthread(void)
  {
      soundfiler_queue = getbytes (sizeof(t_sfqueue));
***************
*** 987,994 ****
      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
--- 1122,1132 ----
      pthread_mutex_init (&soundfiler_queue->mutex,NULL);
      pthread_cond_init (&soundfiler_queue->cond,NULL);
+ 
+     pthread_mutex_lock(&(soundfiler_queue->mutex)); 
      soundfiler_queue->begin=soundfiler_queue->end=NULL;
+     pthread_mutex_unlock(&(soundfiler_queue->mutex)); 
      
      if (pthread_create(&sf_thread_id, NULL ,
! 		       (void *) soundfiler_thread,NULL) !=0)
  	error("Couldn't create soundfiler thread");
      else
***************
*** 996,1002 ****
  }
  
! #endif /* THREADED_SF */
  
! static t_class *soundfiler_class;
  
  
--- 1134,1525 ----
  }
  
! static void soundfiler_t_write(t_soundfiler *x, t_symbol *s,
! 			       int argc, t_atom *argv);
! 
! static void soundfiler_t_write_addq(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     soundfiler_queue_add(soundfiler_t_write,(void *)x,argc, argv);
! }
! 
! static void soundfiler_t_read(t_soundfiler *x, t_symbol *s,
! 			      int argc, t_atom *argv);
! 
! static void soundfiler_t_read_addq(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     soundfiler_queue_add(soundfiler_t_read,(void *)x,argc, argv);
! }
  
! 
!     /* soundfiler_read ...
!     
!     usage: read [flags] filename table ...
!     flags:
!     	-skip <frames> ... frames to skip in file
! 	-nframes <frames>
! 	-onset <frames> ... onset in table to read into (NOT DONE YET)
! 	-raw <headersize channels bytes endian>
! 	-resize
! 	-maxsize <max-size>
!     */
! 
! static void soundfiler_t_read(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     int headersize = -1, channels = 0, bytespersamp = 0, bigendian = 0,
! 	resize = 0, i, j;
!     long skipframes = 0, nframes = 0, finalsize = 0, itemsleft,
!     	maxsize = DEFMAXSIZE, itemsread = 0, bytelimit  = 0x7fffffff;
!     int fd = -1;
!     char endianness, *filename;
!     t_garray *garrays[MAXSFCHANS];
!     t_float *vecs[MAXSFCHANS];
!     char sampbuf[SAMPBUFSIZE];
!     int bufframes, nitems;
!     FILE *fp;
! 
!     while (argc > 0 && argv->a_type == A_SYMBOL &&
!     	*argv->a_w.w_symbol->s_name == '-')
!     {
!     	char *flag = argv->a_w.w_symbol->s_name + 1;
! 	if (!strcmp(flag, "skip"))
! 	{
! 	    if (argc < 2 || argv[1].a_type != A_FLOAT ||
! 	    	((skipframes = argv[1].a_w.w_float) < 0))
! 	    	    goto usage;
! 	    argc -= 2; argv += 2;
! 	}
! 	else if (!strcmp(flag, "nframes"))
! 	{
! 	    if (argc < 2 || argv[1].a_type != A_FLOAT ||
! 	    	((nframes = argv[1].a_w.w_float) < 0))
! 	    	    goto usage;
! 	    argc -= 2; argv += 2;
! 	}
! 	else if (!strcmp(flag, "raw"))
! 	{
! 	    if (argc < 5 ||
! 	    	argv[1].a_type != A_FLOAT ||
! 	    	((headersize = argv[1].a_w.w_float) < 0) ||
! 	    	argv[2].a_type != A_FLOAT ||
! 	    	((channels = argv[2].a_w.w_float) < 1) ||
! 		(channels > MAXSFCHANS) || 
! 	    	argv[3].a_type != A_FLOAT ||
! 	    	((bytespersamp = argv[3].a_w.w_float) < 2) || 
! 		    (bytespersamp > 4) ||
! 	    	argv[4].a_type != A_SYMBOL ||
! 		    ((endianness = argv[4].a_w.w_symbol->s_name[0]) != 'b'
! 		    && endianness != 'l' && endianness != 'n'))
! 	    	    	goto usage;
! 	    if (endianness == 'b')
! 	    	bigendian = 1;
! 	    else if (endianness == 'l')
! 	    	bigendian = 0;
! 	    else
! 	    	bigendian = garray_ambigendian();
! 	    argc -= 5; argv += 5;
! 	}
! 	else if (!strcmp(flag, "resize"))
! 	{
! 	    resize = 1;
! 	    argc -= 1; argv += 1;
! 	}
! 	else if (!strcmp(flag, "maxsize"))
! 	{
! 	    if (argc < 2 || argv[1].a_type != A_FLOAT ||
! 	    	((maxsize = argv[1].a_w.w_float) < 0))
! 	    	    goto usage;
! 	    resize = 1;     /* maxsize implies resize. */
! 	    argc -= 2; argv += 2;
! 	}
! 	else goto usage;
!     }
!     if (argc < 2 || argc > MAXSFCHANS + 1 || argv[0].a_type != A_SYMBOL)
!     	goto usage;
!     filename = argv[0].a_w.w_symbol->s_name;
!     argc--; argv++;
!     
!     for (i = 0; i < argc; i++)
!     {
!     	int vecsize;
! 	//syntax correct?
!     	if (argv[i].a_type != A_SYMBOL)
! 	    goto usage;
! 	//find table
! 	if (!(garrays[i] =
! 	    (t_garray *)pd_findbyclass(argv[i].a_w.w_symbol, garray_class)))
! 	{
! 	    pd_error(x, "%s: no such table", argv[i].a_w.w_symbol->s_name);
! 	    goto done;
! 	}
!     	else if (!garray_getfloatarray(garrays[i], &vecsize, &vecs[i]))
!     	    error("%s: bad template for tabwrite",
! 	    	argv[i].a_w.w_symbol->s_name);
!     	if (finalsize && finalsize != vecsize && !resize)
! 	{
! 	    post("soundfiler_read: arrays have different lengths; resizing...");
! 	    resize = 1;
! 	}
! 	finalsize = vecsize;
!     }
!     fd = open_soundfile(canvas_getdir(x->x_canvas)->s_name, filename,
!     	headersize, &bytespersamp, &bigendian, &channels, &bytelimit,
! 	    skipframes);
! 
!     if (fd < 0)
!     {
! 	pd_error(x, "soundfiler_read: %s: %s", filename, (errno == EIO ?
! 	    "unknown or bad header format" : strerror(errno)));
!     	goto done;
!     }
! 
!     if (resize)
!     {
!     	    /* figure out what to resize to */
!     	long poswas, eofis, framesinfile;
! 	
! 	poswas = lseek(fd, 0, SEEK_CUR);
! 	eofis = lseek(fd, 0, SEEK_END);
! 	if (poswas < 0 || eofis < 0)
! 	{
! 	    pd_error(x, "lseek failed");
! 	    goto done;
! 	}
! 	lseek(fd, poswas, SEEK_SET);
! 	framesinfile = (eofis - poswas) / (channels * bytespersamp);
! 	if (framesinfile > maxsize)
! 	{
! 	    pd_error(x, "soundfiler_read: truncated to %d elements", maxsize);
! 	    framesinfile = maxsize;
! 	}
!         if (framesinfile > bytelimit / (channels * bytespersamp))
!             framesinfile = bytelimit / (channels * bytespersamp);
! 	finalsize = framesinfile;
! 	for (i = 0; i < argc; i++)
! 	{
! 	    int vecsize;
! 
! 	    sys_lock();
!     	    garray_resize(garrays[i], finalsize);
! 	    sys_unlock();
! 
! 	        /* for sanity's sake let's clear the save-in-patch flag here */
! 	    garray_setsaveit(garrays[i], 0);
! 	    garray_getfloatarray(garrays[i], &vecsize, &vecs[i]);
! 	    	/* if the resize failed, garray_resize reported the error */
! 	    if (vecsize != framesinfile)
! 	    {
! 	    	pd_error(x, "resize failed");
! 	     	goto done;
!     	    }
! 	}
!     }
!     if (!finalsize) finalsize = 0x7fffffff;
!     if (finalsize > bytelimit / (channels * bytespersamp))
!     	finalsize = bytelimit / (channels * bytespersamp);
!     fp = fdopen(fd, "rb");
!     bufframes = SAMPBUFSIZE / (channels * bytespersamp);
! 
!     sys_lock();
!     for (itemsread = 0; itemsread < finalsize; )
!     {
!     	int thisread = finalsize - itemsread;
!     	thisread = (thisread > bufframes ? bufframes : thisread);
!     	nitems = fread(sampbuf, channels * bytespersamp, thisread, fp);
! 	if (nitems <= 0) break;
! 	soundfile_xferin(channels, argc, vecs, itemsread,
! 	    (unsigned char *)sampbuf, nitems, bytespersamp, bigendian);
! 	itemsread += nitems;
!     }
!     	/* zero out remaining elements of vectors */
! 	
!     for (i = 0; i < argc; i++)
!     {
! 	int nzero, vecsize;
! 	garray_getfloatarray(garrays[i], &vecsize, &vecs[i]);
! 	for (j = itemsread; j < vecsize; j++)
! 	    vecs[i][j] = 0;
!     }
!     	/* zero out vectors in excess of number of channels */
!     for (i = channels; i < argc; i++)
!     {
! 	int vecsize;
! 	float *foo;
! 	garray_getfloatarray(garrays[i], &vecsize, &foo);
! 	for (j = 0; j < vecsize; j++)
! 	    foo[j] = 0;
!     }
!     sys_unlock();
!     	/* do all graphics updates */
!     for (i = 0; i < argc; i++)
!     	garray_redraw(garrays[i]);
!     fclose(fp);
!     fd = -1;
!     goto done;
! usage:
!     pd_error(x, "usage: read [flags] filename tablename...");
!     post("flags: -skip <n> -nframes <n> -resize -maxsize <n> ...");
!     post("-raw <headerbytes> <channels> <bytespersamp> <endian (b, l, or n)>.");
! done:
!     if (fd >= 0)
!     	close (fd);
!     outlet_float(x->x_obj.ob_outlet, (float)itemsread); 
! }
! 
!     /* this is broken out from soundfiler_write below so garray_write can
!     call it too... not done yet though. */
! 
! long soundfiler_t_dowrite(void *obj, t_canvas *canvas,
!     int argc, t_atom *argv)
! {
!     int headersize, bytespersamp, bigendian,
!     	endianness, swap, filetype, normalize, i, j, nchannels;
!     long onset, nframes, itemsleft,
!     	maxsize = DEFMAXSIZE, itemswritten = 0;
!     t_garray *garrays[MAXSFCHANS];
!     t_float *vecs[MAXSFCHANS];
!     char sampbuf[SAMPBUFSIZE];
!     int bufframes, nitems;
!     int fd = -1;
!     float normfactor, biggest = 0, samplerate;
!     t_symbol *filesym;
! 
!     if (soundfiler_writeargparse(obj, &argc, &argv, &filesym, &filetype,
!     	&bytespersamp, &swap, &bigendian, &normalize, &onset, &nframes,
! 	    &samplerate))
!     	    	goto usage;
!     nchannels = argc;
!     if (nchannels < 1 || nchannels > MAXSFCHANS)
!     	goto usage;
!     if (samplerate < 0)
!     	samplerate = sys_getsr();
!     for (i = 0; i < nchannels; i++)
!     {
!     	int vecsize;
!     	if (argv[i].a_type != A_SYMBOL)
! 	    goto usage;
! 	if (!(garrays[i] =
! 	    (t_garray *)pd_findbyclass(argv[i].a_w.w_symbol, garray_class)))
! 	{
! 	    pd_error(obj, "%s: no such table", argv[i].a_w.w_symbol->s_name);
! 	    goto fail;
! 	}
!     	else if (!garray_getfloatarray(garrays[i], &vecsize, &vecs[i]))
!     	    error("%s: bad template for tabwrite",
! 	    	argv[i].a_w.w_symbol->s_name);
!     	if (nframes > vecsize - onset)
! 	    nframes = vecsize - onset;
!     	
! 	for (j = 0; j < vecsize; j++)
! 	{
! 	    if (vecs[i][j] > biggest)
! 	    	biggest = vecs[i][j];
! 	    else if (-vecs[i][j] > biggest)
! 	    	biggest = -vecs[i][j];
!     	}
!     }
!     if (nframes <= 0)
!     {
! 	pd_error(obj, "soundfiler_write: no samples at onset %ld", onset);
!     	goto fail;
!     }
! 
!     if ((fd = create_soundfile(canvas, filesym->s_name, filetype,
!     	nframes, bytespersamp, bigendian, nchannels,
! 	    swap, samplerate)) < 0)
!     {
!     	post("%s: %s\n", filesym->s_name, strerror(errno));
!     	goto fail;
!     }
!     if (!normalize)
!     {
!     	if ((bytespersamp != 4) && (biggest > 1))
! 	{
!     	    post("%s: normalizing max amplitude %f to 1", filesym->s_name, biggest);
!     	    normalize = 1;
!     	}
! 	else post("%s: biggest amplitude = %f", filesym->s_name, biggest);
!     }
!     if (normalize)
! 	normfactor = (biggest > 0 ? 32767./(32768. * biggest) : 1);
!     else normfactor = 1;
! 
!     bufframes = SAMPBUFSIZE / (nchannels * bytespersamp);
! 
!     for (itemswritten = 0; itemswritten < nframes; )
!     {
!     	int thiswrite = nframes - itemswritten, nitems, nbytes;
!     	thiswrite = (thiswrite > bufframes ? bufframes : thiswrite);
! 	soundfile_xferout(argc, vecs, (unsigned char *)sampbuf, thiswrite,
! 	    onset, bytespersamp, bigendian, normfactor);
!     	nbytes = write(fd, sampbuf, nchannels * bytespersamp * thiswrite);
! 	if (nbytes < nchannels * bytespersamp * thiswrite)
! 	{
! 	    post("%s: %s", filesym->s_name, strerror(errno));
! 	    if (nbytes > 0)
! 	    	itemswritten += nbytes / (nchannels * bytespersamp);
! 	    break;
! 	}
! 	itemswritten += thiswrite;
! 	onset += thiswrite;
!     }
!     if (fd >= 0)
!     {
!     	soundfile_finishwrite(obj, filesym->s_name, fd,
!     	    filetype, nframes, itemswritten, nchannels * bytespersamp, swap);
!     	close (fd);
!     }
!     return ((float)itemswritten); 
! usage:
!     pd_error(obj, "usage: write [flags] filename tablename...");
!     post("flags: -skip <n> -nframes <n> -bytes <n> -wave -aiff -nextstep ...");
!     post("-big -little -normalize");
!     post("(defaults to a 16-bit wave file).");
! fail:
!     if (fd >= 0)
!     	close (fd);
!     return (0); 
! } 
! 
! static void soundfiler_t_write(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     long bozo = soundfiler_t_dowrite(x, x->x_canvas,
!     	argc, argv);
!     outlet_float(x->x_obj.ob_outlet, (float)bozo); 
! }
! 
! static void soundfiler_t_resize(t_soundfiler *x, t_symbol *s,
! 				int argc, t_atom *argv);
! 
! static void soundfiler_t_resize_addq(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     soundfiler_queue_add(soundfiler_t_resize,(void *)x,argc, argv);
! }
! 
! 
!     /* soundfiler_t_resize ...
!     usage: resize table size ...
!     */
! static void soundfiler_t_resize(t_soundfiler *x, t_symbol *s,
!     int argc, t_atom *argv)
! {
!     sys_lock();
!     garray_resize((t_garray *)pd_findbyclass(argv[0].a_w.w_symbol, garray_class), atom_getintarg(1,argc,argv));
!     sys_unlock();
! 
!     outlet_float(x->x_obj.ob_outlet, (float)atom_getintarg(1,argc,argv)); 
!     return;
!     
! usage:
!     pd_error(x, "usage: read [flags] filename tablename...");
!     post("flags: -skip <n> -nframes <n> -resize -maxsize <n> ...");
!     post("-raw <headerbytes> <channels> <bytespersamp> <endian (b, l, or n)>.");
! }
! 
! 
! #endif /* THREADED_SF */
  
  
***************
*** 1341,1360 ****
  
  
- #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)
--- 1864,1867 ----
***************
*** 1367,1374 ****
      	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 */
  }
--- 1874,1883 ----
      	gensym("write"), A_GIMME, 0);
  #ifdef THREADED_SF
!     class_addmethod(soundfiler_class, (t_method)soundfiler_t_read_addq, 
  		    gensym("t_read"), A_GIMME, 0);
!     class_addmethod(soundfiler_class, (t_method)soundfiler_t_write_addq,
  		    gensym("t_write"), A_GIMME, 0);
+     class_addmethod(soundfiler_class, (t_method)soundfiler_t_resize_addq,
+ 		    gensym("resize"), A_GIMME, 0);
  #endif /* THREADED_SF */
  }





More information about the Pd-cvs mailing list