From 1e17420038c1737ee6aabd4f9cc7dc833bb776f0 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sat, 10 Sep 2005 15:47:23 +0000 Subject: libsndfile base soundfiler. - supports only read command - no resize / nframe flags svn path=/trunk/externals/tb/; revision=3521 --- sndfiler/makefile | 94 ++++++++++++++ sndfiler/sndfiler-help.pd | 10 ++ sndfiler/sndfiler.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 425 insertions(+) create mode 100644 sndfiler/makefile create mode 100644 sndfiler/sndfiler-help.pd create mode 100644 sndfiler/sndfiler.c (limited to 'sndfiler') diff --git a/sndfiler/makefile b/sndfiler/makefile new file mode 100644 index 0000000..f44a8da --- /dev/null +++ b/sndfiler/makefile @@ -0,0 +1,94 @@ +NAME=sndfiler +CSYM=sndfiler + +current: pd_linux + +# ----------------------- NT ----------------------- + +pd_nt: $(NAME).dll + +.SUFFIXES: .dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo +VC="C:\Program Files\Microsoft Visual Studio\Vc98" + +PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include + +PDNTLDIR = $(VC)\lib +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\kernel32.lib \ + ..\..\bin\pd.lib + +.c.dll: + cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: $(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I../../src + +.c.pd_irix5: + $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: $(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +.c.pd_irix6: + $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -O3 -fPIC -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I/home/tim/pd/devel_0_39/src + +LSTRIP = strip --strip-unneeded -R .note -R .comment + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + cc -Wl,-export_dynamic --shared -o $*.pd_linux $*.o -lm -lsndfile +# $(LSTRIP) $*.pd_linux + rm -f $*.o + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +.c.pd_darwin: + $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o + +# ---------------------------------------------------------- + +clean: + rm -f *.o *.pd_* so_locations diff --git a/sndfiler/sndfiler-help.pd b/sndfiler/sndfiler-help.pd new file mode 100644 index 0000000..fe9de17 --- /dev/null +++ b/sndfiler/sndfiler-help.pd @@ -0,0 +1,10 @@ +#N canvas 0 0 450 300 10; +#X obj 36 103 sndfiler; +#X obj 294 87 table array; +#X msg 37 60 read \$1 array; +#X obj 38 33 openpanel; +#X obj 124 15 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X connect 2 0 0 0; +#X connect 3 0 2 0; +#X connect 4 0 3 0; diff --git a/sndfiler/sndfiler.c b/sndfiler/sndfiler.c new file mode 100644 index 0000000..29c692a --- /dev/null +++ b/sndfiler/sndfiler.c @@ -0,0 +1,321 @@ +/* + * + * soundfiler based on libsndfile + * Copyright (C) 2005 Tim Blechmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + + +#include "stdlib.h" +#include "m_pd.h" +#include "g_canvas.h" +#include "m_fifo.h" +#include "pthread.h" /* for helper thread */ +#include "sched.h" /* for thread priority */ +#include "alloca.h" + +#include "sndfile.h" + +#if (_POSIX_MEMLOCK - 0) >= 200112L +#include +#endif /* _POSIX_MEMLOCK */ + +static t_class *sndfiler_class; + + +typedef struct _sndfiler +{ + t_object x_obj; + t_canvas *x_canvas; +} t_sndfiler; + +typedef struct _sfprocess +{ + void* padding; + void (* process) (t_sndfiler *, + int, t_atom *); /* callback function */ + t_sndfiler * x; /* soundfiler */ + int argc; + t_atom * argv; +} t_sfprocess; + + +/* this is the queue for all soundfiler objects */ +typedef struct _sfqueue +{ + t_fifo* x_jobs; + + pthread_mutex_t mutex; + pthread_cond_t cond; +} t_sfqueue; + + +typedef struct _syncdata +{ + t_garray** arrays; + t_float** helper_arrays; + int argc; + t_int frames; +} t_syncdata; + + +static t_sfqueue sndfiler_queue; +static pthread_t sf_thread_id; /* id of soundfiler thread */ + + +static t_sndfiler *sndfiler_new(void) +{ + t_sndfiler *x = (t_sndfiler *)pd_new(sndfiler_class); + x->x_canvas = canvas_getcurrent(); + outlet_new(&x->x_obj, &s_float); + return (x); +} + + +/* global soundfiler thread ... sleeping until signaled */ +static void sndfiler_thread(void) +{ + while (1) + { + t_sfprocess * me; + pthread_cond_wait(&sndfiler_queue.cond, &sndfiler_queue.mutex); + + while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) + { + (me->process)(me->x, me->argc, me->argv); + + /* freeing the argument vector */ + freebytes(me->argv, sizeof(t_atom) * me->argc); + freebytes(me, sizeof(t_sfprocess)); + } + } +} + +static void sndfiler_start_thread(void) +{ + pthread_attr_t sf_attr; + struct sched_param sf_param; + int status; + + //initialize queue + sndfiler_queue.x_jobs = fifo_init(); + pthread_mutex_init (&sndfiler_queue.mutex,NULL); + pthread_cond_init (&sndfiler_queue.cond,NULL); + + // initialize thread + pthread_attr_init(&sf_attr); + + sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); + pthread_attr_setschedparam(&sf_attr,&sf_param); + +#ifdef UNIX + if (sys_hipriority == 1/* && getuid() == 0 */) + { + sf_param.sched_priority=sched_get_priority_min(SCHED_RR); + pthread_attr_setschedpolicy(&sf_attr,SCHED_RR); + } +#endif /* UNIX */ + + //start thread + status = pthread_create(&sf_thread_id, &sf_attr, + (void *) sndfiler_thread,NULL); + if (status != 0) + error("Couldn't create sndfiler thread: %d",status); + else + post("global sndfiler thread launched, priority: %d", + sf_param.sched_priority); +} + + +static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv); + + +/* syntax: + * read soundfile array0..n + * if the soundfile has less channels than arrays are given, these arrays are + * set to zero + * if there are too little arrays given, only the first n channels will be used + * */ + +static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) +{ + t_sfprocess * process = getbytes(sizeof(t_sfprocess)); + + + process->process = &sndfiler_read_cb; + process->x = x; + process->argc = argc; + process->argv = (t_atom*) copybytes(argv, sizeof(t_atom) * argc); + + fifo_put(sndfiler_queue.x_jobs, process); + + pthread_cond_signal(&sndfiler_queue.cond); +} + +static t_int sndfiler_synchonize(t_int * w); + +static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) +{ + int resize = 0; + int frames = -1; + int i, j; + int counter=0; + int channel_count; + t_float** helper_arrays; + + t_symbol* file; + t_garray ** arrays; + + SNDFILE* sndfile; + SF_INFO info; + + if (argc < 2) + { + pd_error(x, "Invalid arguments"); + return; + } + + file = atom_getsymbolarg(0, argc, argv); + + channel_count = argc - 1; + helper_arrays = getbytes(channel_count * sizeof(t_float*)); + + arrays = getbytes(channel_count * sizeof(t_garray*)); + for (i = 0; i != channel_count; ++i) + { + t_garray * array = (t_garray *)pd_findbyclass(atom_getsymbolarg(i+1, argc, argv), garray_class); + + if (array) + arrays[i] = array; + else + { + pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, argc, argv)->s_name); + return; + } + } + + sndfile = sf_open(file->s_name, SFM_READ, &info); + + if (sndfile) + { + int minchannels = (channel_count < info.channels) ? + channel_count : info.channels; + + int maxchannels = (channel_count < info.channels) ? + channel_count : info.channels; + + t_float * item = alloca(maxchannels * sizeof(t_float)); + + t_int ** syncdata = getbytes(sizeof(t_int*) * 5); + +#if (_POSIX_MEMLOCK - 0) >= 200112L + munlockall(); +#endif + + for (i = 0; i != channel_count; ++i) + { + helper_arrays[i] = getalignedbytes(info.frames * sizeof(t_float)); + } + + + for (i = 0; i != info.frames; ++i) + { + sf_read_float(sndfile, item, 1); + + for (j = 0; j != channel_count; ++j) + { + if (j < minchannels) + helper_arrays[j][i] = item[j]; + else + helper_arrays[j][i] = 0; + } + } +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + sf_close(sndfile); + + syncdata[0] = (t_int*)arrays; + syncdata[1] = (t_int*)helper_arrays; + syncdata[2] = (t_int*)channel_count; + syncdata[3] = (t_int*)(long)info.frames; + syncdata[4] = (t_int*)x; + + sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5); + } + else + { + pd_error(x, "Error opening file"); + } +} + + +static t_int sndfiler_synchonize(t_int * w) +{ + int i; + t_garray** arrays = (t_garray**) w[0]; + t_float** helper_arrays = (t_float**) w[1]; + t_int channel_count = (t_int)w[2]; + t_int frames = (t_int)w[3]; + t_sndfiler* x = (t_sndfiler*)w[4]; + + for (i = 0; i != channel_count; ++i) + { + t_garray * garray = arrays[i]; + t_array * array = garray->x_scalar->sc_vec[0].w_array; + t_glist * gl = garray->x_glist;; + + + freealignedbytes(array->a_vec, array->a_n); + array->a_vec = (char*)helper_arrays[i]; + array->a_n = frames; + + if (gl->gl_list == &garray->x_gobj && !garray->x_gobj.g_next) + { + vmess(&gl->gl_pd, gensym("bounds"), "ffff", + 0., gl->gl_y1, (double)(frames > 1 ? frames-1 : 1), gl->gl_y2); + /* close any dialogs that might have the wrong info now... */ + gfxstub_deleteforkey(gl); + } + else + garray_redraw(garray); + } + + free(arrays); + free(helper_arrays); + + canvas_update_dsp(); + + outlet_float(x->x_obj.ob_outlet, frames); + + return 0; +} + + +void sndfiler_setup(void) +{ + sndfiler_class = class_new(gensym("sndfiler"), (t_newmethod)sndfiler_new, + 0, sizeof(t_sndfiler), 0, 0); + class_addmethod(sndfiler_class, (t_method)sndfiler_read, + gensym("read"), A_GIMME, 0); + + sndfiler_start_thread(); +} + + -- cgit v1.2.1 From 9290c9a11f4aea63431c62b3f21b9d59d015bff9 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sun, 23 Oct 2005 22:04:51 +0000 Subject: multichannel fix svn path=/trunk/externals/tb/; revision=3761 --- sndfiler/sndfiler.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/sndfiler.c b/sndfiler/sndfiler.c index 29c692a..c9e0fb4 100644 --- a/sndfiler/sndfiler.c +++ b/sndfiler/sndfiler.c @@ -221,6 +221,7 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) t_float * item = alloca(maxchannels * sizeof(t_float)); + t_int ** syncdata = getbytes(sizeof(t_int*) * 5); #if (_POSIX_MEMLOCK - 0) >= 200112L @@ -235,14 +236,14 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) for (i = 0; i != info.frames; ++i) { - sf_read_float(sndfile, item, 1); + sf_read_float(sndfile, item, info.channels); - for (j = 0; j != channel_count; ++j) + for (j = 0; j != info.channels; ++j) { - if (j < minchannels) + if (j < channel_count) + { helper_arrays[j][i] = item[j]; - else - helper_arrays[j][i] = 0; + } } } #if (_POSIX_MEMLOCK - 0) >= 200112L -- cgit v1.2.1 From 40be3959a23e385aea503ad862565f057e61035d Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Sun, 20 Nov 2005 21:51:26 +0000 Subject: new directory structure svn path=/trunk/externals/tb/; revision=3990 --- sndfiler/makefile | 94 -------------- sndfiler/sndfiler-help.pd | 10 -- sndfiler/sndfiler.c | 322 ---------------------------------------------- 3 files changed, 426 deletions(-) delete mode 100644 sndfiler/makefile delete mode 100644 sndfiler/sndfiler-help.pd delete mode 100644 sndfiler/sndfiler.c (limited to 'sndfiler') diff --git a/sndfiler/makefile b/sndfiler/makefile deleted file mode 100644 index f44a8da..0000000 --- a/sndfiler/makefile +++ /dev/null @@ -1,94 +0,0 @@ -NAME=sndfiler -CSYM=sndfiler - -current: pd_linux - -# ----------------------- NT ----------------------- - -pd_nt: $(NAME).dll - -.SUFFIXES: .dll - -PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo -VC="C:\Program Files\Microsoft Visual Studio\Vc98" - -PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include - -PDNTLDIR = $(VC)\lib -PDNTLIB = $(PDNTLDIR)\libc.lib \ - $(PDNTLDIR)\oldnames.lib \ - $(PDNTLDIR)\kernel32.lib \ - ..\..\bin\pd.lib - -.c.dll: - cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c - link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) - -# ----------------------- IRIX 5.x ----------------------- - -pd_irix5: $(NAME).pd_irix5 - -.SUFFIXES: .pd_irix5 - -SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 - -SGIINCLUDE = -I../../src - -.c.pd_irix5: - $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c - ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o - rm $*.o - -# ----------------------- IRIX 6.x ----------------------- - -pd_irix6: $(NAME).pd_irix6 - -.SUFFIXES: .pd_irix6 - -SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ - -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ - -Ofast=ip32 - -.c.pd_irix6: - $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c - ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o - rm $*.o - -# ----------------------- LINUX i386 ----------------------- - -pd_linux: $(NAME).pd_linux - -.SUFFIXES: .pd_linux - -LINUXCFLAGS = -DPD -O3 -fPIC -funroll-loops -fomit-frame-pointer \ - -Wall -W -Wshadow -Wstrict-prototypes -Werror \ - -Wno-unused -Wno-parentheses -Wno-switch - -LINUXINCLUDE = -I/home/tim/pd/devel_0_39/src - -LSTRIP = strip --strip-unneeded -R .note -R .comment - -.c.pd_linux: - cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - cc -Wl,-export_dynamic --shared -o $*.pd_linux $*.o -lm -lsndfile -# $(LSTRIP) $*.pd_linux - rm -f $*.o - -# ----------------------- Mac OSX ----------------------- - -pd_darwin: $(NAME).pd_darwin - -.SUFFIXES: .pd_darwin - -DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ - -Wno-unused -Wno-parentheses -Wno-switch - -.c.pd_darwin: - $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o - rm -f $*.o - -# ---------------------------------------------------------- - -clean: - rm -f *.o *.pd_* so_locations diff --git a/sndfiler/sndfiler-help.pd b/sndfiler/sndfiler-help.pd deleted file mode 100644 index fe9de17..0000000 --- a/sndfiler/sndfiler-help.pd +++ /dev/null @@ -1,10 +0,0 @@ -#N canvas 0 0 450 300 10; -#X obj 36 103 sndfiler; -#X obj 294 87 table array; -#X msg 37 60 read \$1 array; -#X obj 38 33 openpanel; -#X obj 124 15 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X connect 2 0 0 0; -#X connect 3 0 2 0; -#X connect 4 0 3 0; diff --git a/sndfiler/sndfiler.c b/sndfiler/sndfiler.c deleted file mode 100644 index c9e0fb4..0000000 --- a/sndfiler/sndfiler.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * - * soundfiler based on libsndfile - * Copyright (C) 2005 Tim Blechmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - - -#include "stdlib.h" -#include "m_pd.h" -#include "g_canvas.h" -#include "m_fifo.h" -#include "pthread.h" /* for helper thread */ -#include "sched.h" /* for thread priority */ -#include "alloca.h" - -#include "sndfile.h" - -#if (_POSIX_MEMLOCK - 0) >= 200112L -#include -#endif /* _POSIX_MEMLOCK */ - -static t_class *sndfiler_class; - - -typedef struct _sndfiler -{ - t_object x_obj; - t_canvas *x_canvas; -} t_sndfiler; - -typedef struct _sfprocess -{ - void* padding; - void (* process) (t_sndfiler *, - int, t_atom *); /* callback function */ - t_sndfiler * x; /* soundfiler */ - int argc; - t_atom * argv; -} t_sfprocess; - - -/* this is the queue for all soundfiler objects */ -typedef struct _sfqueue -{ - t_fifo* x_jobs; - - pthread_mutex_t mutex; - pthread_cond_t cond; -} t_sfqueue; - - -typedef struct _syncdata -{ - t_garray** arrays; - t_float** helper_arrays; - int argc; - t_int frames; -} t_syncdata; - - -static t_sfqueue sndfiler_queue; -static pthread_t sf_thread_id; /* id of soundfiler thread */ - - -static t_sndfiler *sndfiler_new(void) -{ - t_sndfiler *x = (t_sndfiler *)pd_new(sndfiler_class); - x->x_canvas = canvas_getcurrent(); - outlet_new(&x->x_obj, &s_float); - return (x); -} - - -/* global soundfiler thread ... sleeping until signaled */ -static void sndfiler_thread(void) -{ - while (1) - { - t_sfprocess * me; - pthread_cond_wait(&sndfiler_queue.cond, &sndfiler_queue.mutex); - - while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) - { - (me->process)(me->x, me->argc, me->argv); - - /* freeing the argument vector */ - freebytes(me->argv, sizeof(t_atom) * me->argc); - freebytes(me, sizeof(t_sfprocess)); - } - } -} - -static void sndfiler_start_thread(void) -{ - pthread_attr_t sf_attr; - struct sched_param sf_param; - int status; - - //initialize queue - sndfiler_queue.x_jobs = fifo_init(); - pthread_mutex_init (&sndfiler_queue.mutex,NULL); - pthread_cond_init (&sndfiler_queue.cond,NULL); - - // initialize thread - pthread_attr_init(&sf_attr); - - sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); - pthread_attr_setschedparam(&sf_attr,&sf_param); - -#ifdef UNIX - if (sys_hipriority == 1/* && getuid() == 0 */) - { - sf_param.sched_priority=sched_get_priority_min(SCHED_RR); - pthread_attr_setschedpolicy(&sf_attr,SCHED_RR); - } -#endif /* UNIX */ - - //start thread - status = pthread_create(&sf_thread_id, &sf_attr, - (void *) sndfiler_thread,NULL); - if (status != 0) - error("Couldn't create sndfiler thread: %d",status); - else - post("global sndfiler thread launched, priority: %d", - sf_param.sched_priority); -} - - -static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv); - - -/* syntax: - * read soundfile array0..n - * if the soundfile has less channels than arrays are given, these arrays are - * set to zero - * if there are too little arrays given, only the first n channels will be used - * */ - -static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) -{ - t_sfprocess * process = getbytes(sizeof(t_sfprocess)); - - - process->process = &sndfiler_read_cb; - process->x = x; - process->argc = argc; - process->argv = (t_atom*) copybytes(argv, sizeof(t_atom) * argc); - - fifo_put(sndfiler_queue.x_jobs, process); - - pthread_cond_signal(&sndfiler_queue.cond); -} - -static t_int sndfiler_synchonize(t_int * w); - -static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) -{ - int resize = 0; - int frames = -1; - int i, j; - int counter=0; - int channel_count; - t_float** helper_arrays; - - t_symbol* file; - t_garray ** arrays; - - SNDFILE* sndfile; - SF_INFO info; - - if (argc < 2) - { - pd_error(x, "Invalid arguments"); - return; - } - - file = atom_getsymbolarg(0, argc, argv); - - channel_count = argc - 1; - helper_arrays = getbytes(channel_count * sizeof(t_float*)); - - arrays = getbytes(channel_count * sizeof(t_garray*)); - for (i = 0; i != channel_count; ++i) - { - t_garray * array = (t_garray *)pd_findbyclass(atom_getsymbolarg(i+1, argc, argv), garray_class); - - if (array) - arrays[i] = array; - else - { - pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, argc, argv)->s_name); - return; - } - } - - sndfile = sf_open(file->s_name, SFM_READ, &info); - - if (sndfile) - { - int minchannels = (channel_count < info.channels) ? - channel_count : info.channels; - - int maxchannels = (channel_count < info.channels) ? - channel_count : info.channels; - - t_float * item = alloca(maxchannels * sizeof(t_float)); - - - t_int ** syncdata = getbytes(sizeof(t_int*) * 5); - -#if (_POSIX_MEMLOCK - 0) >= 200112L - munlockall(); -#endif - - for (i = 0; i != channel_count; ++i) - { - helper_arrays[i] = getalignedbytes(info.frames * sizeof(t_float)); - } - - - for (i = 0; i != info.frames; ++i) - { - sf_read_float(sndfile, item, info.channels); - - for (j = 0; j != info.channels; ++j) - { - if (j < channel_count) - { - helper_arrays[j][i] = item[j]; - } - } - } -#if (_POSIX_MEMLOCK - 0) >= 200112L - mlockall(MCL_FUTURE); -#endif - - sf_close(sndfile); - - syncdata[0] = (t_int*)arrays; - syncdata[1] = (t_int*)helper_arrays; - syncdata[2] = (t_int*)channel_count; - syncdata[3] = (t_int*)(long)info.frames; - syncdata[4] = (t_int*)x; - - sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5); - } - else - { - pd_error(x, "Error opening file"); - } -} - - -static t_int sndfiler_synchonize(t_int * w) -{ - int i; - t_garray** arrays = (t_garray**) w[0]; - t_float** helper_arrays = (t_float**) w[1]; - t_int channel_count = (t_int)w[2]; - t_int frames = (t_int)w[3]; - t_sndfiler* x = (t_sndfiler*)w[4]; - - for (i = 0; i != channel_count; ++i) - { - t_garray * garray = arrays[i]; - t_array * array = garray->x_scalar->sc_vec[0].w_array; - t_glist * gl = garray->x_glist;; - - - freealignedbytes(array->a_vec, array->a_n); - array->a_vec = (char*)helper_arrays[i]; - array->a_n = frames; - - if (gl->gl_list == &garray->x_gobj && !garray->x_gobj.g_next) - { - vmess(&gl->gl_pd, gensym("bounds"), "ffff", - 0., gl->gl_y1, (double)(frames > 1 ? frames-1 : 1), gl->gl_y2); - /* close any dialogs that might have the wrong info now... */ - gfxstub_deleteforkey(gl); - } - else - garray_redraw(garray); - } - - free(arrays); - free(helper_arrays); - - canvas_update_dsp(); - - outlet_float(x->x_obj.ob_outlet, frames); - - return 0; -} - - -void sndfiler_setup(void) -{ - sndfiler_class = class_new(gensym("sndfiler"), (t_newmethod)sndfiler_new, - 0, sizeof(t_sndfiler), 0, 0); - class_addmethod(sndfiler_class, (t_method)sndfiler_read, - gensym("read"), A_GIMME, 0); - - sndfiler_start_thread(); -} - - -- cgit v1.2.1 From 7a3b2297e6f784e608d2013c910657334ee3019e Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Sun, 20 Nov 2005 21:54:41 +0000 Subject: also works with pd_main now - additional threaded resize method svn path=/trunk/externals/tb/; revision=3991 --- sndfiler/GnuGPL.txt | 290 ++++++++++++++++++++++++ sndfiler/INSTALL | 55 +++++ sndfiler/README | 24 ++ sndfiler/doc/sndfiler-help.pd | 48 ++++ sndfiler/src/Makefile | 95 ++++++++ sndfiler/src/Makefile.pd_main | 116 ++++++++++ sndfiler/src/sndfiler.c | 504 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1132 insertions(+) create mode 100755 sndfiler/GnuGPL.txt create mode 100755 sndfiler/INSTALL create mode 100755 sndfiler/README create mode 100755 sndfiler/doc/sndfiler-help.pd create mode 100755 sndfiler/src/Makefile create mode 100755 sndfiler/src/Makefile.pd_main create mode 100755 sndfiler/src/sndfiler.c (limited to 'sndfiler') diff --git a/sndfiler/GnuGPL.txt b/sndfiler/GnuGPL.txt new file mode 100755 index 0000000..fa0bef4 --- /dev/null +++ b/sndfiler/GnuGPL.txt @@ -0,0 +1,290 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This General +Public License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to using it. +(Some other Free Software Foundation software is covered by the +GNU Library General Public License instead.) You can apply it to your +programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone +to deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you distribute +copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis +or for a fee, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And +you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent must +be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS FOR +COPYING, DISTRIBUTION AND +MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under +the terms of this General Public License. The "Program", below, refers +to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, either +verbatim or with modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in the term +"modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether +that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the notices +that refer to this License and to the absence of any warranty; and give +any other recipients of the Program a copy of this License along with the +Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Program, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based +on the Program. + +In addition, mere aggregation of another work not based on the +Program with the Program (or with a work based on the Program) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding + machine-readable source code, which must be distributed under + the terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your cost + of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with + such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy +the source code from the same place counts as distribution of the source +code, even though third parties are not compelled to copy the source +along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full +compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and all +its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these terms +and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. You are not responsible +for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot distribute +so as to satisfy simultaneously your obligations under this License and +any other pertinent obligations, then as a consequence you may not +distribute the Program at all. For example, if a patent license would not +permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system, which is implemented by public license +practices. Many people have made generous contributions to the wide +range of software distributed through that system in reliance on +consistent application of that system; it is up to the author/donor to +decide if he or she is willing to distribute software through any other +system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an +explicit geographical distribution limitation excluding those countries, so +that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number +of this License, you may choose any version ever published by the Free +Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF +CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, +TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD +THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE +COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW +OR AGREED TO IN WRITING WILL ANY COPYRIGHT +HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED +ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING +ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT +LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR +OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS diff --git a/sndfiler/INSTALL b/sndfiler/INSTALL new file mode 100755 index 0000000..8aa5e6a --- /dev/null +++ b/sndfiler/INSTALL @@ -0,0 +1,55 @@ + +[sndfiler] installation instructions: + +------------------------------------------------------- + MAIN PD +------------------------------------------------------- + +- INSTALLATION: + +1) first install threadlib, get it from + http://grh.mur.at/software/threadlib.html + +2) download binaries for your platform at + http://grh.mur.at/software/sndfiler.html + +3) WIN: copy sndfiler.dll to path\to\pd\extra + copy libsndfile.dll to windows\system + + LINUX: copy sndfiler.pd_linux to path/to/pd/extra + install libsndfile (via apt-get or something + similar) + + MAC: copy sndfiler.pd_darwin to path/to/pd/extra + install libsndfile + +4) copy helpfile to path/to/pd/doc/5.reference + +- COMPILATION: + +1) install libsndfile on your platform + +2) adapt the pathes in src/Makefile.pd_main to fit into + your system + +3) make -f Makefile.pd_main pd_linux/pd_darwin/pd_win + (windows: you will need MinGW !) + +4) make -f Makefile.pd_main install + +------------------------------------------------------- + PD DEVEL +------------------------------------------------------- + +- COMPILATION: + +1) install libsndfile on your platform + +2) adapt src/Makefile to fit into your system + +3) make pd_linux/pd_darwin/pd_nt + +------------------------------------------------------- + +in case of problems: +grh@mur.at diff --git a/sndfiler/README b/sndfiler/README new file mode 100755 index 0000000..15995b3 --- /dev/null +++ b/sndfiler/README @@ -0,0 +1,24 @@ + +[sndfiler] + +a threaded soundfiler for PD using libsndfile + + +REQUIREMENTS: + - pd >= 0.39 + - libsndfile + - for main PD you will also need threadlib: + http://grh.mur.at/software/threadlib.html + +FEATURES: + - threaded reading of multichannel soundfiles into arrays + - threaded resize of arrays + + +For more information look at the help patch ! + +See the file INSTALL for installation instructions. + + +(C) 2005, Tim Blechmann , + Georg Holzmann diff --git a/sndfiler/doc/sndfiler-help.pd b/sndfiler/doc/sndfiler-help.pd new file mode 100755 index 0000000..c05142e --- /dev/null +++ b/sndfiler/doc/sndfiler-help.pd @@ -0,0 +1,48 @@ +#N canvas 225 0 465 689 10; +#X obj 29 23 cnv 15 404 54 empty empty empty 22 25 0 18 -1 -66577 0 +; +#X obj 31 25 cnv 15 400 50 empty empty sndfiler 22 25 0 18 -228992 +-66577 0; +#X obj 72 637 print THREADED_SF; +#X obj 72 592 r \$0-tsf; +#X obj 68 394 openpanel; +#X obj 68 438 s \$0-tsf; +#X obj 68 374 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 258 615 table array1; +#X text 89 373 <- read; +#X obj 256 536 s \$0-tsf; +#X msg 256 510 resize array1 4410; +#X text 39 276 read a file: read filename array1 array2 ...; +#X text 40 292 NOTE: this will also resize the array to the filesize +!; +#X text 66 340 for mono files:; +#X msg 68 416 read \$1 array1; +#X obj 239 396 openpanel; +#X obj 239 440 s \$0-tsf; +#X obj 239 376 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X text 260 375 <- read; +#X text 235 340 for multichannel specify; +#X text 237 353 more arrays:; +#X msg 239 418 read \$1 array1 array2; +#X obj 258 637 table array2; +#X obj 72 615 sndfiler; +#X text 288 34 threaded soundfiler; +#X text 308 51 using libsndfile; +#X text 161 113 ::: SNDFILER :::; +#X text 65 152 A threaded soundfiler for PD using libsndfile.; +#X text 65 182 REQUIREMENTS:; +#X text 118 199 - pd >= 0.39; +#X text 118 215 - libsndfile; +#X text 118 231 - threadlib (for main pd); +#X text 65 509 threaded resize of arrays:; +#X connect 3 0 23 0; +#X connect 4 0 14 0; +#X connect 6 0 4 0; +#X connect 10 0 9 0; +#X connect 14 0 5 0; +#X connect 15 0 21 0; +#X connect 17 0 15 0; +#X connect 21 0 16 0; +#X connect 23 0 2 0; diff --git a/sndfiler/src/Makefile b/sndfiler/src/Makefile new file mode 100755 index 0000000..2b17d1c --- /dev/null +++ b/sndfiler/src/Makefile @@ -0,0 +1,95 @@ + +NAME=sndfiler +CSYM=sndfiler + +current: pd_linux + +# ----------------------- NT ----------------------- + +pd_nt: $(NAME).dll + +.SUFFIXES: .dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo +VC="C:\Program Files\Microsoft Visual Studio\Vc98" + +PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include + +PDNTLDIR = $(VC)\lib +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\kernel32.lib \ + ..\..\bin\pd.lib + +.c.dll: + cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: $(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I../../src + +.c.pd_irix5: + $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: $(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +.c.pd_irix6: + $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -O3 -fPIC -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I/home/tim/pd/devel_0_39/src + +LSTRIP = strip --strip-unneeded -R .note -R .comment + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + cc -Wl,-export_dynamic --shared -o $*.pd_linux $*.o -lm -lsndfile +# $(LSTRIP) $*.pd_linux + rm -f $*.o + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +.c.pd_darwin: + $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o + +# ---------------------------------------------------------- + +clean: + rm -f *.o *.pd_darwin *.pd_linux *.dll so_locations diff --git a/sndfiler/src/Makefile.pd_main b/sndfiler/src/Makefile.pd_main new file mode 100755 index 0000000..1b4c5ca --- /dev/null +++ b/sndfiler/src/Makefile.pd_main @@ -0,0 +1,116 @@ +# ---------------------------------------------------------- + +# adjust the next pathes to your system: + +# this should point to the directory which contains +# m_pd.h and g_canvas.h +PD_SCR = /home/holzi/pd-0.39-1/src +#PD_SCR = c:/pd/src + +# this is the pd directory, usually /usr/lib/pd +# or c:/pd etc. +PD_PATH = /usr/lib/pd +#PD_PATH = c:/pd + +# path of sndfile.h from libsndfile, usually it's in +# /usr/include and so detected automatically +SNDFILE_SRC = /usr/include + +# the directory, where libsndfile is located +# (in linux it' normally not necessary, in windows it's +# normally in c:/windwos/system or so) +SNDFILE_PATH = c:/windows/system + +# path to threadlib.h +THREADLIB_SRC = /home/Georg/pd-cvs/externals/grh/threadlib/src +#THREADLIB_SRC = c:/Georg/pd-cvs/externals/grh/threadlib/src + +# path to threadlib.pd_linux/dll/pd_darwin +# (usually path/to/pd/extra) +THREADLIB_PATH = $(PD_PATH)/extra + +# ---------------------------------------------------------- + +NAME=sndfiler + +CC = gcc +LD = gcc +INCLUDE= -I. -I$(PD_SCR) -I$(SNDFILE_SRC) -I$(THREADLIB_SRC) +CC_FLAGS = -DPD -DUSE_PD_MAIN -O3 -funroll-loops \ + -Wall -W -Wshadow -Wno-parentheses -Wno-switch \ + -Wno-unused -fomit-frame-pointer +LD_FLAGS = --export-dynamic -shared -o + +current: + @echo ---------------------------- + @echo USAGE: + @echo linux: make pd_linux + @echo windows: make pd_win + @echo darwin: make pd_darwin + @echo ---------------------------- + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +CC_UNIX = -DUNIX -fPIC -pthread +LIB_UNIX = -lc -lm -lsndfile $(THREADLIB_PATH)/threadlib.pd_linux + +.c.pd_linux: + $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o $*.o -c $*.c + $(LD) $(LD_FLAGS) $*.pd_linux $*.o $(LIB_UNIX) + strip --strip-unneeded $*.pd_linux + chmod 755 $*.pd_linux + @test -d ../bin || mkdir -p ../bin + cp $*.pd_linux ../bin + rm -f $*.o + +# ------------------------ WIN MinGW ----------------------- + +pd_win: $(NAME).dll + +.SUFFIXES: .dll + +CC_WIN = -DMSW -mms-bitfields +LIB_WIN = $(PD_PATH)/bin/pd.dll \ + $(SNDFILE_PATH)/pthreadGC.dll \ + $(SNDFILE_PATH)/libsndfile.dll \ + $(THREADLIB_PATH)/threadlib.dll + +.c.dll: + $(CC) $(CC_WIN) $(CC_FLAGS) $(INCLUDE) -o $*.o -c $*.c + $(LD) $(LD_FLAGS) $*.dll $*.o $(LIB_WIN) + strip --strip-unneeded $*.dll + chmod 755 $*.dll + @test -d ../bin || mkdir -p ../bin + cp $*.dll ../bin + rm -f $*.o + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +CC_DARWIN = -pthread +LD_DARWIN = -bundle -undefined suppress -flat_namespace \ + -bundle_loader $(PD_PATH)/bin/pd --export-dynamic + +.c.pd_darwin: + $(CC) $(CC_FLAGS) $(CC_DARWIN) $(INCLUDE) -o $*.o -c $*.c + $(LD) $(LD_DARWIN) $*.pd_linux $*.o $(LIB) + chmod 755 $*.pd_darwin + @test -d ../bin || mkdir -p ../bin + cp $*.pd_darwin ../bin + rm -f $*.o + +# ---------------------------------------------------------- + +clean: + rm -f *.o *.pd_darwin *.pd_linux *.dll + +install: + install ../bin/$(NAME).* $(PD_PATH)/extra + install ../doc/*.pd $(PD_PATH)/doc/5.reference diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c new file mode 100755 index 0000000..c1579ee --- /dev/null +++ b/sndfiler/src/sndfiler.c @@ -0,0 +1,504 @@ +/* + * + * threaded soundfiler based on libsndfile + * Copyright (C) 2005, Tim Blechmann + * (C) 2005, Georg Holzmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* to be compatible with main pd */ +#ifdef USE_PD_MAIN + +#define getalignedbytes(a) getbytes(a) +#define freealignedbytes(a,b) freebytes(a,b) +#include "threadlib.h" + +/* forward declaration */ +struct _garray +{ + t_gobj x_gobj; + t_scalar *x_scalar; /* scalar "containing" the array */ + t_glist *x_glist; /* containing glist */ + t_symbol *x_name; /* unexpanded name (possibly with leading '$') */ + t_symbol *x_realname; /* expanded name (symbol we're bound to) */ + char x_usedindsp; /* true if some DSP routine is using this */ + char x_saveit; /* true if we should save this with parent */ + char x_listviewing; /* true if list view window is open */ +}; + +#else /* now for pd_devel */ + +#include "m_pd.h" +#include "m_fifo.h" +#include "pthread.h" + +#endif /* USE_PD_MAIN */ + + +#include "g_canvas.h" +#include "sndfile.h" + +#include "stdlib.h" +#include "sched.h" /* for thread priority */ +#include + +/* for alloca */ +#ifdef MSW +#include +#else +#include "alloca.h" +#endif + +#if (_POSIX_MEMLOCK - 0) >= 200112L +#include +#endif /* _POSIX_MEMLOCK */ + + +/************ forward declarations **************/ + +#ifdef UNIX +/* real-time flag, true if priority boosted */ +extern int sys_hipriority; +#endif + +/* get a garray's "array" structure. */ +t_array *h_garray_getarray(t_garray *x) +{ + int zonset, ztype; + t_symbol *zarraytype; + t_scalar *sc = x->x_scalar; + t_symbol *templatesym = sc->sc_template; + t_template *_template = template_findbyname(templatesym); + if (!_template) + { + error("array: couldn't find template %s", templatesym->s_name); + return (0); + } + if (!template_find_field(_template, gensym("z"), + &zonset, &ztype, &zarraytype)) + { + error("array: template %s has no 'z' field", templatesym->s_name); + return (0); + } + if (ztype != DT_ARRAY) + { + error("array: template %s, 'z' field is not an array", + templatesym->s_name); + return (0); + } + return (sc->sc_vec[zonset].w_array); +} + + +/************ sndfiler **************/ + +static t_class *sndfiler_class; + +typedef struct _sndfiler +{ + t_object x_obj; + t_canvas *x_canvas; +} t_sndfiler; + +typedef struct _sfprocess +{ + void* padding; + /* callback function */ + void (* process) (t_sndfiler *, int, t_atom *); + t_sndfiler * x; /* soundfiler */ + int argc; + t_atom * argv; +} t_sfprocess; + +/* this is the queue for all soundfiler objects */ +typedef struct _sfqueue +{ + t_fifo* x_jobs; + + pthread_mutex_t mutex; + pthread_cond_t cond; +} t_sfqueue; + +typedef struct _syncdata +{ + t_garray** arrays; + t_float** helper_arrays; + int argc; + t_int frames; +} t_syncdata; + +static t_sfqueue sndfiler_queue; +static pthread_t sf_thread_id; /* id of soundfiler thread */ + +static t_sndfiler *sndfiler_new(void) +{ + t_sndfiler *x = (t_sndfiler *)pd_new(sndfiler_class); + x->x_canvas = canvas_getcurrent(); + outlet_new(&x->x_obj, &s_float); + return (x); +} + +/* global soundfiler thread ... sleeping until signaled */ +static void sndfiler_thread(void) +{ + while (1) + { + t_sfprocess * me; + pthread_cond_wait(&sndfiler_queue.cond, &sndfiler_queue.mutex); + + while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) + { + (me->process)(me->x, me->argc, me->argv); + + /* freeing the argument vector */ + freebytes(me->argv, sizeof(t_atom) * me->argc); + freebytes(me, sizeof(t_sfprocess)); + } + } +} + +static void sndfiler_start_thread(void) +{ + pthread_attr_t sf_attr; + struct sched_param sf_param; + int status; + + //initialize queue + sndfiler_queue.x_jobs = fifo_init(); + pthread_mutex_init (&sndfiler_queue.mutex,NULL); + pthread_cond_init (&sndfiler_queue.cond,NULL); + + // initialize thread + pthread_attr_init(&sf_attr); + + sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); + pthread_attr_setschedparam(&sf_attr,&sf_param); + +#ifdef UNIX + if (sys_hipriority == 1/* && getuid() == 0 */) + { + sf_param.sched_priority=sched_get_priority_min(SCHED_RR); + pthread_attr_setschedpolicy(&sf_attr,SCHED_RR); + } +#endif /* UNIX */ + + //start thread + status = pthread_create(&sf_thread_id, &sf_attr, + (void *) sndfiler_thread,NULL); + + if (status != 0) + error("Couldn't create sndfiler thread: %d",status); + else + post("Global sndfiler thread launched, priority: %d", + sf_param.sched_priority); +} + +static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv); + +/* syntax: + * read soundfile array0..n + * if the soundfile has less channels than arrays are given, these arrays are + * set to zero + * if there are too little arrays given, only the first n channels will be used + * */ +static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) +{ + t_sfprocess * process = getbytes(sizeof(t_sfprocess)); + + process->process = &sndfiler_read_cb; + process->x = x; + process->argc = argc; + process->argv = (t_atom*) copybytes(argv, sizeof(t_atom) * argc); + + fifo_put(sndfiler_queue.x_jobs, process); + + pthread_cond_signal(&sndfiler_queue.cond); +} + +static t_int sndfiler_synchonize(t_int * w); + +static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) +{ + int i, j; + int channel_count; + t_float** helper_arrays; + + t_symbol* file; + t_garray ** arrays; + + SNDFILE* sndfile; + SF_INFO info; + + if (argc < 2) + { + pd_error(x, "usage: read soundfile array1 array2 ..."); + return; + } + + file = atom_getsymbolarg(0, argc, argv); + + channel_count = argc - 1; + helper_arrays = getbytes(channel_count * sizeof(t_float*)); + + arrays = getbytes(channel_count * sizeof(t_garray*)); + for (i = 0; i != channel_count; ++i) + { + t_garray * array = (t_garray *)pd_findbyclass(atom_getsymbolarg(i+1, + argc, argv), garray_class); + + if (array) + arrays[i] = array; + else + { + pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, argc, argv)->s_name); + return; + } + } + + post("sndfiler: loading file ..."); + + sndfile = sf_open(file->s_name, SFM_READ, &info); + + if (sndfile) + { + int maxchannels = (channel_count < info.channels) ? + channel_count : info.channels; + + t_float * item = alloca(maxchannels * sizeof(t_float)); + + t_int ** syncdata = getbytes(sizeof(t_int*) * 5); + +#if (_POSIX_MEMLOCK - 0) >= 200112L + munlockall(); +#endif + + for (i = 0; i != channel_count; ++i) + { + helper_arrays[i] = getalignedbytes(info.frames * sizeof(t_float)); + } + + for (i = 0; i != info.frames; ++i) + { + sf_read_float(sndfile, item, info.channels); + + for (j = 0; j != info.channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = item[j]; + } + } + } + +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + sf_close(sndfile); + + syncdata[0] = (t_int*)arrays; + syncdata[1] = (t_int*)helper_arrays; + syncdata[2] = (t_int*)channel_count; + syncdata[3] = (t_int*)(long)info.frames; + syncdata[4] = (t_int*)x; + + sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5); + } + else + pd_error(x, "Error opening file"); +} + +static t_int sndfiler_synchonize(t_int * w) +{ + int i; + t_garray** arrays = (t_garray**) w[0]; + t_float** helper_arrays = (t_float**) w[1]; + t_int channel_count = (t_int)w[2]; + t_int frames = (t_int)w[3]; + t_sndfiler* x = (t_sndfiler*)w[4]; + + for (i = 0; i != channel_count; ++i) + { + t_garray * garray = arrays[i]; + t_array * array = h_garray_getarray(garray); + t_glist * gl = garray->x_glist;; + + freealignedbytes(array->a_vec, array->a_n); + array->a_vec = (char*)helper_arrays[i]; + array->a_n = frames; + + if (gl->gl_list == &garray->x_gobj && !garray->x_gobj.g_next) + { + vmess(&gl->gl_pd, gensym("bounds"), "ffff", 0., gl->gl_y1, + (double)(frames > 1 ? frames-1 : 1), gl->gl_y2); + + /* close any dialogs that might have the wrong info now... */ + gfxstub_deleteforkey(gl); + } + else + garray_redraw(garray); + } + + free(arrays); + free(helper_arrays); + + canvas_update_dsp(); + + outlet_float(x->x_obj.ob_outlet, frames); + + return 0; +} + +static void sndfiler_t_resize(t_sndfiler * y, int argc, t_atom* argv); + +/* syntax: + * resize table size + * */ +static void sndfiler_resize(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) +{ + t_sfprocess * process = getbytes(sizeof(t_sfprocess)); + + process->process = &sndfiler_t_resize; + process->x = x; + process->argc = argc; + process->argv = (t_atom*) copybytes(argv, sizeof(t_atom) * argc); + + fifo_put(sndfiler_queue.x_jobs, process); + + pthread_cond_signal(&sndfiler_queue.cond); +} + +static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) +{ + int was, elemsize; /* array contains was elements of size elemsize */ + t_float * vec; /* old array */ + t_glist *gl; + int n; /* resize of n elements */ + char *nvec; /* new array */ + + t_garray * x = (t_garray *)pd_findbyclass(argv[0].a_w.w_symbol, garray_class); + t_array *data = h_garray_getarray(x); + + if (!(x)) + { + pd_error(y, "%s: no such table", argv[0].a_w.w_symbol->s_name); + goto usage; + } + + vec = (t_float*) data->a_vec; + was = data->a_n; + + if ((argv+1)->a_type == A_FLOAT) + n = (int) (argv+1)->a_w.w_float; + else + goto usage; + + if (n == was) return; + + if (n < 1) n = 1; + elemsize = template_findbyname(data->a_templatesym)->t_n * sizeof(t_word); + +#if (_POSIX_MEMLOCK - 0) >= 200112L + munlockall(); +#endif + + if (was > n) + nvec = (char*)copybytes(data->a_vec, was * elemsize); + else + { + nvec = getbytes(n * elemsize); + memcpy (nvec, data->a_vec, was * elemsize); + + /* LATER should check t_resizebytes result */ + memset(nvec + was*elemsize, 0, (n - was) * elemsize); + } + + if (!nvec) + { + pd_error(x, "array resize failed: out of memory"); + +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + return; + } + + /* TB: we'll have to be sure that no one is accessing the array */ + sys_lock(); + +#ifdef GARRAY_THREAD_LOCK + garray_lock(x); +#endif + + data->a_vec = nvec; + data->a_n = n; + +#ifdef GARRAY_THREAD_LOCK + garray_unlock(x); +#endif + + if (x->x_usedindsp) canvas_update_dsp(); + sys_unlock(); + + /* if this is the only array in the graph, + reset the graph's coordinates */ + gl = x->x_glist; + if (gl->gl_list == &x->x_gobj && !x->x_gobj.g_next) + { + vmess(&gl->gl_pd, gensym("bounds"), "ffff", + 0., gl->gl_y1, (double)(n > 1 ? n-1 : 1), gl->gl_y2); + /* close any dialogs that might have the wrong info now... */ + gfxstub_deleteforkey(gl); + } + else garray_redraw(x); + + freebytes (vec, was * elemsize); + +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + sys_lock(); + outlet_float(y->x_obj.ob_outlet, (float)atom_getintarg(1,argc,argv)); + sys_unlock(); + + return; + + usage: + pd_error(x, "usage: resize tablename size"); +} + +void sndfiler_setup(void) +{ + sndfiler_class = class_new(gensym("sndfiler"), + (t_newmethod)sndfiler_new, 0, + sizeof(t_sndfiler), 0, 0); + + class_addmethod(sndfiler_class, (t_method)sndfiler_read, + gensym("read"), A_GIMME, 0); + class_addmethod(sndfiler_class, (t_method)sndfiler_resize, + gensym("resize"), A_GIMME, 0); + +#ifdef USE_PD_MAIN + // needed to start thread callback system + threadlib_setup(); +#endif + + // starts helper thread + sndfiler_start_thread(); +} -- cgit v1.2.1 From dfebc6aa91cc76e8e4ee7b28f159c61dc03d9c60 Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Mon, 21 Nov 2005 09:29:14 +0000 Subject: osx makefile fix svn path=/trunk/externals/tb/; revision=3996 --- sndfiler/src/Makefile.pd_main | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/Makefile.pd_main b/sndfiler/src/Makefile.pd_main index 1b4c5ca..195d396 100755 --- a/sndfiler/src/Makefile.pd_main +++ b/sndfiler/src/Makefile.pd_main @@ -96,11 +96,13 @@ pd_darwin: $(NAME).pd_darwin CC_DARWIN = -pthread LD_DARWIN = -bundle -undefined suppress -flat_namespace \ - -bundle_loader $(PD_PATH)/bin/pd --export-dynamic + -bundle_loader $(PD_PATH)/bin/pd --export-dynamic \ + -L/sw/lib -L/opt/local/lib -lsndfile \ + $(THREADLIB_PATH)/threadlib.pd_darwin .c.pd_darwin: $(CC) $(CC_FLAGS) $(CC_DARWIN) $(INCLUDE) -o $*.o -c $*.c - $(LD) $(LD_DARWIN) $*.pd_linux $*.o $(LIB) + $(LD) $(LD_DARWIN) -o $*.pd_linux $*.o $(LIB) chmod 755 $*.pd_darwin @test -d ../bin || mkdir -p ../bin cp $*.pd_darwin ../bin -- cgit v1.2.1 From 04f24a3a63d8e1f49f966b586b42134269553c66 Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Mon, 21 Nov 2005 17:04:05 +0000 Subject: now the osx version should work :) svn path=/trunk/externals/tb/; revision=4008 --- sndfiler/src/Makefile.pd_main | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sndfiler') diff --git a/sndfiler/src/Makefile.pd_main b/sndfiler/src/Makefile.pd_main index 195d396..b56b4b3 100755 --- a/sndfiler/src/Makefile.pd_main +++ b/sndfiler/src/Makefile.pd_main @@ -102,7 +102,7 @@ LD_DARWIN = -bundle -undefined suppress -flat_namespace \ .c.pd_darwin: $(CC) $(CC_FLAGS) $(CC_DARWIN) $(INCLUDE) -o $*.o -c $*.c - $(LD) $(LD_DARWIN) -o $*.pd_linux $*.o $(LIB) + $(LD) $(LD_DARWIN) -o $*.pd_darwin $*.o $(LIB) chmod 755 $*.pd_darwin @test -d ../bin || mkdir -p ../bin cp $*.pd_darwin ../bin -- cgit v1.2.1 From bc96a98d953afbee541b5e5b5bbcfc99f86842bb Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Mon, 28 Nov 2005 22:27:20 +0000 Subject: new flags: -resize and -skip svn path=/trunk/externals/tb/; revision=4073 --- sndfiler/doc/sndfiler-help.pd | 71 +++++++++++++----------- sndfiler/src/sndfiler.c | 124 +++++++++++++++++++++++++++++++++++------- 2 files changed, 142 insertions(+), 53 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/doc/sndfiler-help.pd b/sndfiler/doc/sndfiler-help.pd index c05142e..fb402f7 100755 --- a/sndfiler/doc/sndfiler-help.pd +++ b/sndfiler/doc/sndfiler-help.pd @@ -1,48 +1,53 @@ -#N canvas 225 0 465 689 10; +#N canvas 135 0 465 772 10; #X obj 29 23 cnv 15 404 54 empty empty empty 22 25 0 18 -1 -66577 0 ; #X obj 31 25 cnv 15 400 50 empty empty sndfiler 22 25 0 18 -228992 -66577 0; -#X obj 72 637 print THREADED_SF; -#X obj 72 592 r \$0-tsf; -#X obj 68 394 openpanel; -#X obj 68 438 s \$0-tsf; -#X obj 68 374 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +#X obj 55 667 print THREADED_SF; +#X obj 55 622 r \$0-tsf; +#X obj 48 440 openpanel; +#X obj 48 484 s \$0-tsf; +#X obj 48 420 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; -#X obj 258 615 table array1; -#X text 89 373 <- read; -#X obj 256 536 s \$0-tsf; -#X msg 256 510 resize array1 4410; -#X text 39 276 read a file: read filename array1 array2 ...; -#X text 40 292 NOTE: this will also resize the array to the filesize -!; -#X text 66 340 for mono files:; -#X msg 68 416 read \$1 array1; -#X obj 239 396 openpanel; -#X obj 239 440 s \$0-tsf; -#X obj 239 376 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +#X obj 241 645 table array1; +#X text 69 419 <- read; +#X obj 239 566 s \$0-tsf; +#X msg 239 540 resize array1 4410; +#X text 46 386 for mono files:; +#X obj 239 442 openpanel; +#X obj 239 486 s \$0-tsf; +#X obj 239 422 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; -#X text 260 375 <- read; -#X text 235 340 for multichannel specify; -#X text 237 353 more arrays:; -#X msg 239 418 read \$1 array1 array2; -#X obj 258 637 table array2; -#X obj 72 615 sndfiler; +#X text 260 421 <- read; +#X text 235 386 for multichannel specify; +#X text 237 399 more arrays:; +#X msg 239 464 read \$1 array1 array2; +#X obj 241 667 table array2; +#X obj 55 645 sndfiler; #X text 288 34 threaded soundfiler; #X text 308 51 using libsndfile; #X text 161 113 ::: SNDFILER :::; -#X text 65 152 A threaded soundfiler for PD using libsndfile.; +#X text 63 152 A threaded soundfiler for PD using libsndfile.; #X text 65 182 REQUIREMENTS:; #X text 118 199 - pd >= 0.39; #X text 118 215 - libsndfile; #X text 118 231 - threadlib (for main pd); -#X text 65 509 threaded resize of arrays:; -#X connect 3 0 23 0; -#X connect 4 0 14 0; +#X text 48 539 threaded resize of arrays:; +#X text 33 267 read a file: read [flags] filename array1 array2 ... +; +#X msg 48 462 read -resize \$1 array1; +#X text 32 287 FLAGS:; +#X text 32 305 -resize: resize the array(s) to the size of the soundfile +; +#X text 33 324 -skip : skip nr. of samples in soundfile \, +if negative \, it will be counted from the end of the file !; +#X text 82 722 (c) 2005 \, Tim Blechmann \, Georg Holzmann; +#X connect 3 0 20 0; +#X connect 4 0 31 0; #X connect 6 0 4 0; #X connect 10 0 9 0; -#X connect 14 0 5 0; -#X connect 15 0 21 0; -#X connect 17 0 15 0; -#X connect 21 0 16 0; -#X connect 23 0 2 0; +#X connect 12 0 18 0; +#X connect 14 0 12 0; +#X connect 18 0 13 0; +#X connect 20 0 2 0; +#X connect 31 0 5 0; diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index c1579ee..80df1c9 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -236,18 +236,37 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) int i, j; int channel_count; t_float** helper_arrays; + int resize = 0; + int seek = 0, arraysize = 0, writesize; t_symbol* file; t_garray ** arrays; SNDFILE* sndfile; SF_INFO info; - - if (argc < 2) + + // parse flags + while (argc > 0 && argv->a_type == A_SYMBOL && + *argv->a_w.w_symbol->s_name == '-') { - pd_error(x, "usage: read soundfile array1 array2 ..."); - return; + char *flag = argv->a_w.w_symbol->s_name + 1; + if (!strcmp(flag, "resize")) + { + resize = 1; + argc -= 1; argv += 1; + } + else if (!strcmp(flag, "skip")) + { + if (argc < 2 || argv[1].a_type != A_FLOAT || + ((seek = argv[1].a_w.w_float) == 0)) + goto usage; + argc -= 2; argv += 2; + } + else goto usage; } + + if (argc < 2) + goto usage; file = atom_getsymbolarg(0, argc, argv); @@ -257,41 +276,83 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) arrays = getbytes(channel_count * sizeof(t_garray*)); for (i = 0; i != channel_count; ++i) { - t_garray * array = (t_garray *)pd_findbyclass(atom_getsymbolarg(i+1, - argc, argv), garray_class); - - if (array) - arrays[i] = array; - else - { - pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, argc, argv)->s_name); - return; - } + t_float *dummy; + int size; + t_garray *array; + + if(!(array = (t_garray *)pd_findbyclass( + atom_getsymbolarg(i+1, argc, argv), garray_class))) + { + pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, + argc, argv)->s_name); + return; + } + + if(garray_getfloatarray(array, &size, &dummy)) + arrays[i] = array; + else + { + pd_error(x, "%s: bad template for sndfiler", atom_getsymbolarg(i+1, + argc, argv)->s_name); + return; + } + + // in multichannel mode: check if arrays have different length + if (arraysize && arraysize != size && !resize) + { + post("sndfiler: arrays have different lengths, resizing to last one ..."); + } + arraysize = size; } - post("sndfiler: loading file ..."); - sndfile = sf_open(file->s_name, SFM_READ, &info); if (sndfile) { + int pos = 0; int maxchannels = (channel_count < info.channels) ? channel_count : info.channels; t_float * item = alloca(maxchannels * sizeof(t_float)); t_int ** syncdata = getbytes(sizeof(t_int*) * 5); - + + // negative seek: offset from the end of the file + if(seek<0) + { + pos = sf_seek(sndfile, seek, SEEK_END); + } + if(seek>0) + { + pos = sf_seek(sndfile, seek, SEEK_SET); + } + if(pos == -1) + { + pd_error(x, "invalid seek in soundfile"); + return; + } + + if(resize) + { + writesize = (info.frames-pos); + arraysize = writesize; + } + else + writesize = (arraysize>(info.frames-pos)) ? + info.frames-pos : arraysize; + + post("sndfiler: loading file ..."); + #if (_POSIX_MEMLOCK - 0) >= 200112L munlockall(); #endif for (i = 0; i != channel_count; ++i) { - helper_arrays[i] = getalignedbytes(info.frames * sizeof(t_float)); + helper_arrays[i] = getalignedbytes(arraysize * sizeof(t_float)); } - for (i = 0; i != info.frames; ++i) + for (i = 0; i != writesize; ++i) { sf_read_float(sndfile, item, info.channels); @@ -303,6 +364,21 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) } } } + + // fill remaining elements with zero + if(!resize && (arraysize>(info.frames-pos))) + { + for (i = writesize; i != arraysize; ++i) + { + for (j = 0; j != info.channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = 0; + } + } + } + } #if (_POSIX_MEMLOCK - 0) >= 200112L mlockall(MCL_FUTURE); @@ -313,13 +389,21 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) syncdata[0] = (t_int*)arrays; syncdata[1] = (t_int*)helper_arrays; syncdata[2] = (t_int*)channel_count; - syncdata[3] = (t_int*)(long)info.frames; + syncdata[3] = (t_int*)arraysize; syncdata[4] = (t_int*)x; sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5); + return; } else + { pd_error(x, "Error opening file"); + return; + } + + usage: + pd_error(x, "usage: read [flags] filename array1 array2 ..."); + post("flags: -skip -resize "); } static t_int sndfiler_synchonize(t_int * w) -- cgit v1.2.1 From 5f7d939d6e3a11830d63afe259d31d3ff3a9f8bb Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Tue, 29 Nov 2005 18:34:32 +0000 Subject: removed annoying debug post svn path=/trunk/externals/tb/; revision=4082 --- sndfiler/src/sndfiler.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 80df1c9..227a261 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -341,8 +341,6 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) writesize = (arraysize>(info.frames-pos)) ? info.frames-pos : arraysize; - post("sndfiler: loading file ..."); - #if (_POSIX_MEMLOCK - 0) >= 200112L munlockall(); #endif -- cgit v1.2.1 From 153d5c53085f3c4d5f89af9f4db04fb97d80ba93 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Fri, 16 Dec 2005 08:34:10 +0000 Subject: using a semaphore instead of a condion variable for synchronization svn path=/trunk/externals/tb/; revision=4235 --- sndfiler/src/sndfiler.c | 192 ++++++++++++++++++++++++------------------------ 1 file changed, 95 insertions(+), 97 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 227a261..38ebfa8 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -45,6 +45,7 @@ struct _garray #include "m_pd.h" #include "m_fifo.h" #include "pthread.h" +#include "semaphore.h" #endif /* USE_PD_MAIN */ @@ -89,7 +90,7 @@ t_array *h_garray_getarray(t_garray *x) return (0); } if (!template_find_field(_template, gensym("z"), - &zonset, &ztype, &zarraytype)) + &zonset, &ztype, &zarraytype)) { error("array: template %s has no 'z' field", templatesym->s_name); return (0); @@ -97,7 +98,7 @@ t_array *h_garray_getarray(t_garray *x) if (ztype != DT_ARRAY) { error("array: template %s, 'z' field is not an array", - templatesym->s_name); + templatesym->s_name); return (0); } return (sc->sc_vec[zonset].w_array); @@ -128,9 +129,7 @@ typedef struct _sfprocess typedef struct _sfqueue { t_fifo* x_jobs; - - pthread_mutex_t mutex; - pthread_cond_t cond; + sem_t sem; } t_sfqueue; typedef struct _syncdata @@ -158,8 +157,8 @@ static void sndfiler_thread(void) while (1) { t_sfprocess * me; - pthread_cond_wait(&sndfiler_queue.cond, &sndfiler_queue.mutex); - + sem_wait(&sndfiler_queue.sem); + while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) { (me->process)(me->x, me->argc, me->argv); @@ -179,9 +178,8 @@ static void sndfiler_start_thread(void) //initialize queue sndfiler_queue.x_jobs = fifo_init(); - pthread_mutex_init (&sndfiler_queue.mutex,NULL); - pthread_cond_init (&sndfiler_queue.cond,NULL); - + sem_init (&sndfiler_queue.sem,0,0); + // initialize thread pthread_attr_init(&sf_attr); @@ -198,13 +196,13 @@ static void sndfiler_start_thread(void) //start thread status = pthread_create(&sf_thread_id, &sf_attr, - (void *) sndfiler_thread,NULL); + (void *) sndfiler_thread,NULL); if (status != 0) error("Couldn't create sndfiler thread: %d",status); else post("Global sndfiler thread launched, priority: %d", - sf_param.sched_priority); + sf_param.sched_priority); } static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv); @@ -226,7 +224,7 @@ static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - pthread_cond_signal(&sndfiler_queue.cond); + sem_post(&sndfiler_queue.sem); } static t_int sndfiler_synchonize(t_int * w); @@ -247,22 +245,22 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) // parse flags while (argc > 0 && argv->a_type == A_SYMBOL && - *argv->a_w.w_symbol->s_name == '-') + *argv->a_w.w_symbol->s_name == '-') { char *flag = argv->a_w.w_symbol->s_name + 1; - if (!strcmp(flag, "resize")) - { - resize = 1; - argc -= 1; argv += 1; - } - else if (!strcmp(flag, "skip")) - { - if (argc < 2 || argv[1].a_type != A_FLOAT || - ((seek = argv[1].a_w.w_float) == 0)) - goto usage; - argc -= 2; argv += 2; - } - else goto usage; + if (!strcmp(flag, "resize")) + { + resize = 1; + argc -= 1; argv += 1; + } + else if (!strcmp(flag, "skip")) + { + if (argc < 2 || argv[1].a_type != A_FLOAT || + ((seek = argv[1].a_w.w_float) == 0)) + goto usage; + argc -= 2; argv += 2; + } + else goto usage; } if (argc < 2) @@ -277,32 +275,32 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) for (i = 0; i != channel_count; ++i) { t_float *dummy; - int size; + int size; t_garray *array; if(!(array = (t_garray *)pd_findbyclass( - atom_getsymbolarg(i+1, argc, argv), garray_class))) - { - pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, - argc, argv)->s_name); - return; - } + atom_getsymbolarg(i+1, argc, argv), garray_class))) + { + pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, + argc, argv)->s_name); + return; + } - if(garray_getfloatarray(array, &size, &dummy)) - arrays[i] = array; - else - { - pd_error(x, "%s: bad template for sndfiler", atom_getsymbolarg(i+1, - argc, argv)->s_name); - return; - } + if(garray_getfloatarray(array, &size, &dummy)) + arrays[i] = array; + else + { + pd_error(x, "%s: bad template for sndfiler", atom_getsymbolarg(i+1, + argc, argv)->s_name); + return; + } - // in multichannel mode: check if arrays have different length - if (arraysize && arraysize != size && !resize) - { - post("sndfiler: arrays have different lengths, resizing to last one ..."); - } - arraysize = size; + // in multichannel mode: check if arrays have different length + if (arraysize && arraysize != size && !resize) + { + post("sndfiler: arrays have different lengths, resizing to last one ..."); + } + arraysize = size; } sndfile = sf_open(file->s_name, SFM_READ, &info); @@ -311,35 +309,35 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) { int pos = 0; int maxchannels = (channel_count < info.channels) ? - channel_count : info.channels; + channel_count : info.channels; t_float * item = alloca(maxchannels * sizeof(t_float)); t_int ** syncdata = getbytes(sizeof(t_int*) * 5); - // negative seek: offset from the end of the file - if(seek<0) - { - pos = sf_seek(sndfile, seek, SEEK_END); - } - if(seek>0) - { - pos = sf_seek(sndfile, seek, SEEK_SET); - } - if(pos == -1) - { - pd_error(x, "invalid seek in soundfile"); - return; - } + // negative seek: offset from the end of the file + if(seek<0) + { + pos = sf_seek(sndfile, seek, SEEK_END); + } + if(seek>0) + { + pos = sf_seek(sndfile, seek, SEEK_SET); + } + if(pos == -1) + { + pd_error(x, "invalid seek in soundfile"); + return; + } - if(resize) - { - writesize = (info.frames-pos); - arraysize = writesize; - } - else - writesize = (arraysize>(info.frames-pos)) ? - info.frames-pos : arraysize; + if(resize) + { + writesize = (info.frames-pos); + arraysize = writesize; + } + else + writesize = (arraysize>(info.frames-pos)) ? + info.frames-pos : arraysize; #if (_POSIX_MEMLOCK - 0) >= 200112L munlockall(); @@ -363,20 +361,20 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) } } - // fill remaining elements with zero - if(!resize && (arraysize>(info.frames-pos))) - { - for (i = writesize; i != arraysize; ++i) - { - for (j = 0; j != info.channels; ++j) - { - if (j < channel_count) - { - helper_arrays[j][i] = 0; - } - } - } - } + // fill remaining elements with zero + if(!resize && (arraysize>(info.frames-pos))) + { + for (i = writesize; i != arraysize; ++i) + { + for (j = 0; j != info.channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = 0; + } + } + } + } #if (_POSIX_MEMLOCK - 0) >= 200112L mlockall(MCL_FUTURE); @@ -391,17 +389,17 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) syncdata[4] = (t_int*)x; sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5); - return; + return; } else { pd_error(x, "Error opening file"); - return; + return; } - usage: + usage: pd_error(x, "usage: read [flags] filename array1 array2 ..."); - post("flags: -skip -resize "); + post("flags: -skip -resize "); } static t_int sndfiler_synchonize(t_int * w) @@ -426,7 +424,7 @@ static t_int sndfiler_synchonize(t_int * w) if (gl->gl_list == &garray->x_gobj && !garray->x_gobj.g_next) { vmess(&gl->gl_pd, gensym("bounds"), "ffff", 0., gl->gl_y1, - (double)(frames > 1 ? frames-1 : 1), gl->gl_y2); + (double)(frames > 1 ? frames-1 : 1), gl->gl_y2); /* close any dialogs that might have the wrong info now... */ gfxstub_deleteforkey(gl); @@ -461,7 +459,7 @@ static void sndfiler_resize(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - pthread_cond_signal(&sndfiler_queue.cond); + sem_post(&sndfiler_queue.sem); } static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) @@ -561,20 +559,20 @@ static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) return; - usage: - pd_error(x, "usage: resize tablename size"); + usage: + pd_error(x, "usage: resize tablename size"); } void sndfiler_setup(void) { sndfiler_class = class_new(gensym("sndfiler"), - (t_newmethod)sndfiler_new, 0, - sizeof(t_sndfiler), 0, 0); + (t_newmethod)sndfiler_new, 0, + sizeof(t_sndfiler), 0, 0); class_addmethod(sndfiler_class, (t_method)sndfiler_read, - gensym("read"), A_GIMME, 0); + gensym("read"), A_GIMME, 0); class_addmethod(sndfiler_class, (t_method)sndfiler_resize, - gensym("resize"), A_GIMME, 0); + gensym("resize"), A_GIMME, 0); #ifdef USE_PD_MAIN // needed to start thread callback system -- cgit v1.2.1 From f35587d21c1b141c847e8660403941ea53963447 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 22 Dec 2005 23:45:20 +0000 Subject: export sndfiler_setup function for Windows svn path=/trunk/externals/tb/; revision=4287 --- sndfiler/src/sndfiler.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 38ebfa8..005b75f 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -563,6 +563,9 @@ static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) pd_error(x, "usage: resize tablename size"); } +#ifdef _MSC_VER +__declspec(dllexport) +#endif void sndfiler_setup(void) { sndfiler_class = class_new(gensym("sndfiler"), -- cgit v1.2.1 From 9c5b12f513dc7631af9d8c4bdee302c25aa4382d Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 22 Dec 2005 23:46:17 +0000 Subject: add config files for the flext build system svn path=/trunk/externals/tb/; revision=4288 --- sndfiler/build/config-lnx.def | 1 + sndfiler/build/config-mac.def | 1 + sndfiler/build/config-win.def | 5 +++++ sndfiler/build/gnumake-lnx-gcc.inc | 1 + sndfiler/build/gnumake-mac-gcc.inc | 1 + sndfiler/build/gnumake-win-cygwin.inc | 3 +++ sndfiler/build/gnumake-win-mingw.inc | 3 +++ sndfiler/build/nmake-win-msvc.inc | 3 +++ sndfiler/package.txt | 4 ++++ 9 files changed, 22 insertions(+) create mode 100644 sndfiler/build/config-lnx.def create mode 100644 sndfiler/build/config-mac.def create mode 100644 sndfiler/build/config-win.def create mode 100644 sndfiler/build/gnumake-lnx-gcc.inc create mode 100644 sndfiler/build/gnumake-mac-gcc.inc create mode 100644 sndfiler/build/gnumake-win-cygwin.inc create mode 100644 sndfiler/build/gnumake-win-mingw.inc create mode 100644 sndfiler/build/nmake-win-msvc.inc create mode 100644 sndfiler/package.txt (limited to 'sndfiler') diff --git a/sndfiler/build/config-lnx.def b/sndfiler/build/config-lnx.def new file mode 100644 index 0000000..fc37b7e --- /dev/null +++ b/sndfiler/build/config-lnx.def @@ -0,0 +1 @@ +# nothing to set diff --git a/sndfiler/build/config-mac.def b/sndfiler/build/config-mac.def new file mode 100644 index 0000000..fc37b7e --- /dev/null +++ b/sndfiler/build/config-mac.def @@ -0,0 +1 @@ +# nothing to set diff --git a/sndfiler/build/config-win.def b/sndfiler/build/config-win.def new file mode 100644 index 0000000..bd7bf72 --- /dev/null +++ b/sndfiler/build/config-win.def @@ -0,0 +1,5 @@ +# where is the libsndfile installation? +SNDFILEPATH=%programfiles%\libsndfile + +SNDFILEINC=$(SNDFILEPATH)\src +SNDFILELIB=$(SNDFILEPATH) diff --git a/sndfiler/build/gnumake-lnx-gcc.inc b/sndfiler/build/gnumake-lnx-gcc.inc new file mode 100644 index 0000000..3314475 --- /dev/null +++ b/sndfiler/build/gnumake-lnx-gcc.inc @@ -0,0 +1 @@ +LIBS += -lsndfile diff --git a/sndfiler/build/gnumake-mac-gcc.inc b/sndfiler/build/gnumake-mac-gcc.inc new file mode 100644 index 0000000..3314475 --- /dev/null +++ b/sndfiler/build/gnumake-mac-gcc.inc @@ -0,0 +1 @@ +LIBS += -lsndfile diff --git a/sndfiler/build/gnumake-win-cygwin.inc b/sndfiler/build/gnumake-win-cygwin.inc new file mode 100644 index 0000000..3b7c000 --- /dev/null +++ b/sndfiler/build/gnumake-win-cygwin.inc @@ -0,0 +1,3 @@ +INCPATH += -I$(SNDFILEINC) +LIBPATH += -L$(SNDFILELIB) +LIBS += -lsndfile diff --git a/sndfiler/build/gnumake-win-mingw.inc b/sndfiler/build/gnumake-win-mingw.inc new file mode 100644 index 0000000..3b7c000 --- /dev/null +++ b/sndfiler/build/gnumake-win-mingw.inc @@ -0,0 +1,3 @@ +INCPATH += -I$(SNDFILEINC) +LIBPATH += -L$(SNDFILELIB) +LIBS += -lsndfile diff --git a/sndfiler/build/nmake-win-msvc.inc b/sndfiler/build/nmake-win-msvc.inc new file mode 100644 index 0000000..9b832cc --- /dev/null +++ b/sndfiler/build/nmake-win-msvc.inc @@ -0,0 +1,3 @@ +INCPATH=$(INCPATH) /I$(SNDFILEINC) +LIBPATH=$(LIBPATH) /LIBPATH:$(SNDFILELIB) +LIBS=$(LIBS) libsndfile.lib diff --git a/sndfiler/package.txt b/sndfiler/package.txt new file mode 100644 index 0000000..8f4281e --- /dev/null +++ b/sndfiler/package.txt @@ -0,0 +1,4 @@ +NAME=sndfiler +SRCDIR=src +SRCS=sndfiler.c +BUILDDIR=build -- cgit v1.2.1 From b65ae6220a420b3a0b1ed23d8ef0934379cebbb6 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 19 Jan 2006 21:02:12 +0000 Subject: fixes for OSX (doesn't have a sem_init function) svn path=/trunk/externals/tb/; revision=4447 --- sndfiler/src/sndfiler.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 005b75f..6d1e4c6 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -129,7 +129,7 @@ typedef struct _sfprocess typedef struct _sfqueue { t_fifo* x_jobs; - sem_t sem; + sem_t* sem; } t_sfqueue; typedef struct _syncdata @@ -154,11 +154,11 @@ static t_sndfiler *sndfiler_new(void) /* global soundfiler thread ... sleeping until signaled */ static void sndfiler_thread(void) { - while (1) + for(;;) { t_sfprocess * me; - sem_wait(&sndfiler_queue.sem); - + sem_wait(sndfiler_queue.sem); + while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) { (me->process)(me->x, me->argc, me->argv); @@ -178,8 +178,17 @@ static void sndfiler_start_thread(void) //initialize queue sndfiler_queue.x_jobs = fifo_init(); - sem_init (&sndfiler_queue.sem,0,0); - +#ifdef __APPLE__ + sndfiler_queue.sem = sem_open("sndfilerthread",O_CREAT|O_EXCL,0,0); + if(sndfiler_queue.sem == SEM_FAILED) + error("Couldn't create sndfiler semaphore: %i",errno); +#else + sndfiler_queue.sem = (sem_t *)getbytes(sizeof(sem_t)); + status = sem_init(sndfiler_queue.sem,0,0); + if(status != 0) + error("Couldn't create sndfiler semaphore: %i",status); +#endif + // initialize thread pthread_attr_init(&sf_attr); @@ -224,7 +233,7 @@ static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - sem_post(&sndfiler_queue.sem); + sem_post(sndfiler_queue.sem); } static t_int sndfiler_synchonize(t_int * w); @@ -459,7 +468,7 @@ static void sndfiler_resize(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - sem_post(&sndfiler_queue.sem); + sem_post(sndfiler_queue.sem); } static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) -- cgit v1.2.1 From a556c60dc72ddf3bd7b4e1cfc3c85f999ccb6e51 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 19 Jan 2006 22:21:01 +0000 Subject: better fixes for OSX (use kernel functions) svn path=/trunk/externals/tb/; revision=4448 --- sndfiler/src/sndfiler.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 6d1e4c6..aa6d8d2 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -44,6 +44,7 @@ struct _garray #include "m_pd.h" #include "m_fifo.h" + #include "pthread.h" #include "semaphore.h" @@ -68,6 +69,18 @@ struct _garray #include #endif /* _POSIX_MEMLOCK */ +#ifdef __APPLE__ +#include +#define SEM_T semaphore_t +#define SEM_INIT(s) (semaphore_create(mach_task_self(),&s,SYNC_POLICY_FIFO,0) == 0) +#define SEM_SIGNAL(s) semaphore_signal(s) +#define SEM_WAIT(s) semaphore_wait(s) +#else +#define SEM_T sem_t +#define SEM_INIT(s) (sem_init(&s,0,0) == 0) +#define SEM_SIGNAL(s) sem_post(&s) +#define SEM_WAIT(s) sem_wait(&s) +#endif /************ forward declarations **************/ @@ -129,7 +142,7 @@ typedef struct _sfprocess typedef struct _sfqueue { t_fifo* x_jobs; - sem_t* sem; + SEM_T sem; } t_sfqueue; typedef struct _syncdata @@ -157,7 +170,7 @@ static void sndfiler_thread(void) for(;;) { t_sfprocess * me; - sem_wait(sndfiler_queue.sem); + SEM_WAIT(sndfiler_queue.sem); while (me = (t_sfprocess *)fifo_get(sndfiler_queue.x_jobs)) { @@ -178,16 +191,10 @@ static void sndfiler_start_thread(void) //initialize queue sndfiler_queue.x_jobs = fifo_init(); -#ifdef __APPLE__ - sndfiler_queue.sem = sem_open("sndfilerthread",O_CREAT|O_EXCL,0,0); - if(sndfiler_queue.sem == SEM_FAILED) - error("Couldn't create sndfiler semaphore: %i",errno); -#else - sndfiler_queue.sem = (sem_t *)getbytes(sizeof(sem_t)); - status = sem_init(sndfiler_queue.sem,0,0); - if(status != 0) + + status = SEM_INIT(sndfiler_queue.sem); + if(!status) error("Couldn't create sndfiler semaphore: %i",status); -#endif // initialize thread pthread_attr_init(&sf_attr); @@ -233,7 +240,7 @@ static void sndfiler_read(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - sem_post(sndfiler_queue.sem); + SEM_SIGNAL(sndfiler_queue.sem); } static t_int sndfiler_synchonize(t_int * w); @@ -468,7 +475,7 @@ static void sndfiler_resize(t_sndfiler * x, t_symbol *s, int argc, t_atom* argv) fifo_put(sndfiler_queue.x_jobs, process); - sem_post(sndfiler_queue.sem); + SEM_SIGNAL(sndfiler_queue.sem); } static void sndfiler_t_resize(t_sndfiler *y, int argc, t_atom *argv) -- cgit v1.2.1 From c9f622385bb18ecfe16e7810507d5ddc1330e468 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Fri, 20 Jan 2006 07:39:13 +0000 Subject: Included more Mach headers for function prototypes svn path=/trunk/externals/tb/; revision=4450 --- sndfiler/src/sndfiler.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index aa6d8d2..8c4dbe5 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -70,6 +70,8 @@ struct _garray #endif /* _POSIX_MEMLOCK */ #ifdef __APPLE__ +#include +#include #include #define SEM_T semaphore_t #define SEM_INIT(s) (semaphore_create(mach_task_self(),&s,SYNC_POLICY_FIFO,0) == 0) -- cgit v1.2.1 From 60fee223a0a27439814547aee438bb5c53e44437 Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Sun, 29 Jan 2006 19:29:29 +0000 Subject: fixed compilation for main pd svn path=/trunk/externals/tb/; revision=4517 --- sndfiler/src/Makefile.pd_main | 6 +++--- sndfiler/src/sndfiler.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/src/Makefile.pd_main b/sndfiler/src/Makefile.pd_main index b56b4b3..f5a70e5 100755 --- a/sndfiler/src/Makefile.pd_main +++ b/sndfiler/src/Makefile.pd_main @@ -4,7 +4,7 @@ # this should point to the directory which contains # m_pd.h and g_canvas.h -PD_SCR = /home/holzi/pd-0.39-1/src +PD_SCR = /usr/local/src/pd/src #PD_SCR = c:/pd/src # this is the pd directory, usually /usr/lib/pd @@ -19,10 +19,10 @@ SNDFILE_SRC = /usr/include # the directory, where libsndfile is located # (in linux it' normally not necessary, in windows it's # normally in c:/windwos/system or so) -SNDFILE_PATH = c:/windows/system +#SNDFILE_PATH = c:/windows/system # path to threadlib.h -THREADLIB_SRC = /home/Georg/pd-cvs/externals/grh/threadlib/src +THREADLIB_SRC = /home/holzi/pd-cvs/externals/grh/threadlib/src #THREADLIB_SRC = c:/Georg/pd-cvs/externals/grh/threadlib/src # path to threadlib.pd_linux/dll/pd_darwin diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 8c4dbe5..507510a 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -46,7 +46,6 @@ struct _garray #include "m_fifo.h" #include "pthread.h" -#include "semaphore.h" #endif /* USE_PD_MAIN */ @@ -57,6 +56,7 @@ struct _garray #include "stdlib.h" #include "sched.h" /* for thread priority */ #include +#include "semaphore.h" /* for alloca */ #ifdef MSW -- cgit v1.2.1 From 682501946dd0637cfe9fc2477bc3a6e78c032349 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sun, 29 Jan 2006 22:13:49 +0000 Subject: limit stacksize of helper thread to 1mb ... should be more than enough ... svn path=/trunk/externals/tb/; revision=4518 --- sndfiler/src/sndfiler.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sndfiler') diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 507510a..9bf6b65 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -203,7 +203,10 @@ static void sndfiler_start_thread(void) sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); pthread_attr_setschedparam(&sf_attr,&sf_param); - + + /* 1mb of stack should be enough */ + pthread_attr_setstacksize(&sf_attr,1048576); + #ifdef UNIX if (sys_hipriority == 1/* && getuid() == 0 */) { -- cgit v1.2.1 From 10dee9a91925645cd9e3bb14e5ef31e8a338949e Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Wed, 1 Feb 2006 09:01:28 +0000 Subject: now possible to read ogg file (using libvorbisfile) svn path=/trunk/externals/tb/; revision=4531 --- sndfiler/src/Makefile | 9 +- sndfiler/src/Makefile.pd_main | 14 ++- sndfiler/src/file_input.c | 253 ++++++++++++++++++++++++++++++++++++++++++ sndfiler/src/file_input.h | 66 +++++++++++ sndfiler/src/sndfiler.c | 170 +++++----------------------- sndfiler/src/sndfiler.h | 87 +++++++++++++++ 6 files changed, 451 insertions(+), 148 deletions(-) create mode 100644 sndfiler/src/file_input.c create mode 100644 sndfiler/src/file_input.h create mode 100755 sndfiler/src/sndfiler.h (limited to 'sndfiler') diff --git a/sndfiler/src/Makefile b/sndfiler/src/Makefile index 2b17d1c..b8f1c8a 100755 --- a/sndfiler/src/Makefile +++ b/sndfiler/src/Makefile @@ -2,6 +2,8 @@ NAME=sndfiler CSYM=sndfiler +OBJ=sndfiler.o file_input.o + current: pd_linux # ----------------------- NT ----------------------- @@ -65,13 +67,14 @@ LINUXCFLAGS = -DPD -O3 -fPIC -funroll-loops -fomit-frame-pointer \ -Wall -W -Wshadow -Wstrict-prototypes -Werror \ -Wno-unused -Wno-parentheses -Wno-switch -LINUXINCLUDE = -I/home/tim/pd/devel_0_39/src +LINUXINCLUDE = -I../../../../pd/src LSTRIP = strip --strip-unneeded -R .note -R .comment .c.pd_linux: - cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - cc -Wl,-export_dynamic --shared -o $*.pd_linux $*.o -lm -lsndfile + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o sndfiler.o -c sndfiler.c + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o file_input.o -c file_input.c + cc -Wl,-export_dynamic --shared -o $*.pd_linux $(OBJ) -lm -lsndfile -lvorbisfile # $(LSTRIP) $*.pd_linux rm -f $*.o diff --git a/sndfiler/src/Makefile.pd_main b/sndfiler/src/Makefile.pd_main index f5a70e5..29bde80 100755 --- a/sndfiler/src/Makefile.pd_main +++ b/sndfiler/src/Makefile.pd_main @@ -41,6 +41,8 @@ CC_FLAGS = -DPD -DUSE_PD_MAIN -O3 -funroll-loops \ -Wno-unused -fomit-frame-pointer LD_FLAGS = --export-dynamic -shared -o +OBJ=sndfiler.o file_input.o + current: @echo ---------------------------- @echo USAGE: @@ -56,11 +58,12 @@ pd_linux: $(NAME).pd_linux .SUFFIXES: .pd_linux CC_UNIX = -DUNIX -fPIC -pthread -LIB_UNIX = -lc -lm -lsndfile $(THREADLIB_PATH)/threadlib.pd_linux +LIB_UNIX = -lc -lm -lsndfile -lvorbisfile $(THREADLIB_PATH)/threadlib.pd_linux .c.pd_linux: - $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o $*.o -c $*.c - $(LD) $(LD_FLAGS) $*.pd_linux $*.o $(LIB_UNIX) + $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o sndfiler.o -c sndfiler.c + $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o file_input.o -c file_input.c + $(LD) $(LD_FLAGS) $*.pd_linux $(OBJ) $(LIB_UNIX) strip --strip-unneeded $*.pd_linux chmod 755 $*.pd_linux @test -d ../bin || mkdir -p ../bin @@ -97,11 +100,12 @@ pd_darwin: $(NAME).pd_darwin CC_DARWIN = -pthread LD_DARWIN = -bundle -undefined suppress -flat_namespace \ -bundle_loader $(PD_PATH)/bin/pd --export-dynamic \ - -L/sw/lib -L/opt/local/lib -lsndfile \ + -L/sw/lib -L/opt/local/lib -lsndfile -lvorbisfile \ $(THREADLIB_PATH)/threadlib.pd_darwin .c.pd_darwin: - $(CC) $(CC_FLAGS) $(CC_DARWIN) $(INCLUDE) -o $*.o -c $*.c + $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o sndfiler.o -c sndfiler.c + $(CC) $(CC_UNIX) $(CC_FLAGS) $(INCLUDE) -o file_input.o -c file_input.c $(LD) $(LD_DARWIN) -o $*.pd_darwin $*.o $(LIB) chmod 755 $*.pd_darwin @test -d ../bin || mkdir -p ../bin diff --git a/sndfiler/src/file_input.c b/sndfiler/src/file_input.c new file mode 100644 index 0000000..79ad27e --- /dev/null +++ b/sndfiler/src/file_input.c @@ -0,0 +1,253 @@ +/* + * threaded soundfiler for PD + * Copyright (C) 2005, Georg Holzmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "sndfiler.h" +#include "file_input.h" + +int check_fileformat(t_symbol* file) +{ + FILE *fp = NULL; + OggVorbis_File vorbisfile; + + // partially opens a vorbis file to test for Vorbis-ness + if( !(fp = fopen(file->s_name, "r")) ) + return -1; + + if( ov_test(fp, &vorbisfile, NULL, 0) < 0 ) + { + fclose(fp); + return USE_LIBSNDFILE; + } + + ov_clear(&vorbisfile); + return USE_LIBVORBISFILE; +} + +int read_libsndfile(t_float** helper_arrays, int channel_count, int seek, + int resize, int array_size, t_symbol* file) +{ + int arraysize = array_size; + int writesize = 0, i=0, j=0; + SNDFILE* sndfile; + SF_INFO info; + + sndfile = sf_open(file->s_name, SFM_READ, &info); + + if(!sndfile) + return -1; + + int pos = 0; + int maxchannels = (channel_count < info.channels) ? + channel_count : info.channels; + + t_float * item = alloca(maxchannels * sizeof(t_float)); + + // negative seek: offset from the end of the file + if(seek<0) + { + if(CHECK_SEEK(seek+info.frames, info.frames)) + pos = sf_seek(sndfile, seek, SEEK_END); + else pos = -1; + } + if(seek>0) + { + if(CHECK_SEEK(seek, info.frames)) + pos = sf_seek(sndfile, seek, SEEK_SET); + else pos = -1; + } + if(pos == -1) + { + sf_close(sndfile); + post("invalid seek in soundfile"); + return -1; + } + + if(resize) + { + writesize = (info.frames-pos); + arraysize = writesize; + } + else + writesize = (arraysize>(info.frames-pos)) ? + info.frames-pos : arraysize; + +#if (_POSIX_MEMLOCK - 0) >= 200112L + munlockall(); +#endif + + for (i = 0; i != channel_count; ++i) + { + helper_arrays[i] = getalignedbytes(arraysize * sizeof(t_float)); + } + + for (i = 0; i != writesize; ++i) + { + sf_read_float(sndfile, item, info.channels); + + for (j = 0; j != info.channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = item[j]; + } + } + } + + // fill remaining elements with zero + if(!resize && (arraysize > (info.frames-pos))) + { + for (i = writesize; i != arraysize; ++i) + { + for (j = 0; j != info.channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = 0; + } + } + } + } + +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + sf_close(sndfile); + return arraysize; +} + +int read_libvorbisfile(t_float** helper_arrays, int channel_count, int seek, + int resize, int array_size, t_symbol* file) +{ + int arraysize = array_size; + int writesize = 0, i=0, j=0; + int pos=0, maxchannels=0, frames=0, frames_read=0; + int current_section=0, finished=0; + float **buftmp = NULL; + FILE *fp = NULL; + OggVorbis_File vorbisfile; + vorbis_info *info; + + if( !(fp = fopen(file->s_name, "r")) ) + return -1; + + if( ov_open(fp, &vorbisfile, NULL, 0) < 0 ) + { + fclose(fp); + return -1; + } + + info = ov_info(&vorbisfile, -1); + frames = ov_pcm_total(&vorbisfile, -1); + if( !info || frames==OV_EINVAL ) + { + ov_clear(&vorbisfile); + post("failed to get info about vorbis file"); + return -1; + } + + maxchannels = (channel_count < info->channels) ? + channel_count : info->channels; + + // negative seek: offset from the end of the file + if(seek<0) + { + if(CHECK_SEEK(frames+seek, frames)) + { + int ret = ov_pcm_seek(&vorbisfile, frames+seek); + if(ret!=0) + pos =-1; + else + pos = frames+seek; + } + else pos = -1; + } + if(seek>0) + { + if(CHECK_SEEK(seek, frames)) + { + int ret = ov_pcm_seek(&vorbisfile, seek); + if(ret!=0) + pos =-1; + else + pos = seek; + } + else pos = -1; + } + if(pos == -1) + { + ov_clear(&vorbisfile); + post("invalid seek in vorbis file"); + return -1; + } + + if(resize) + { + writesize = (frames-pos); + arraysize = writesize; + } + else + writesize = (arraysize>(frames-pos)) ? + frames-pos : arraysize; + +#if (_POSIX_MEMLOCK - 0) >= 200112L + munlockall(); +#endif + + for (i = 0; i != channel_count; ++i) + { + helper_arrays[i] = getalignedbytes(arraysize * sizeof(t_float)); + } + + for (i = 0; i != writesize; ++i) + { + int ret = ov_read_float(&vorbisfile, &buftmp, 1, + ¤t_section); + if(ret!=1) + post("wrong return type while ogg decoding!"); + + for (j = 0; j != channel_count; ++j) + { + helper_arrays[j][i] = buftmp[j][0]; + } + } + + // fill remaining elements with zero + if(!resize && (arraysize > (frames-pos))) + { + for (i = writesize; i != arraysize; ++i) + { + for (j = 0; j != info->channels; ++j) + { + if (j < channel_count) + { + helper_arrays[j][i] = 0; + } + } + } + } + +#if (_POSIX_MEMLOCK - 0) >= 200112L + mlockall(MCL_FUTURE); +#endif + + ov_clear(&vorbisfile); + return arraysize; +} diff --git a/sndfiler/src/file_input.h b/sndfiler/src/file_input.h new file mode 100644 index 0000000..e5b5232 --- /dev/null +++ b/sndfiler/src/file_input.h @@ -0,0 +1,66 @@ +/* + * threaded soundfiler for PD + * Copyright (C) 2005, Georg Holzmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _FILE_INPUT__ +#define _FILE_INPUT__ + +#define USE_LIBSNDFILE 0 +#define USE_LIBVORBISFILE 1 + +//! returns 1 if s is in [0,c) +#define CHECK_SEEK(s, c) (s<0 ? 0 : (s>=c ? 0 : 1)) + +/*! + * checks which library to use + * + * @param file filename + * @return USE_LIBSNDFILE or USE_LIBVORBISFILE, -1 if there was an error + */ +int check_fileformat(t_symbol* file); + +/*! + * read audio data with libsndfile + * + * @param helper_arrays (unallocated) pointer to the data + * @param channel_count nr of channels + * @param seek frames to seek in file + * @param resize 1 if array should be resized + * @param array_size size of the array in samples + * @param file filename + * @return new arraysiize, -1 if there was a failure + */ +int read_libsndfile(t_float** helper_arrays, int channel_count, int seek, + int resize, int array_size, t_symbol* file); + +/*! + * read audio data with libvorbisfile + * + * @param helper_arrays (unallocated) pointer to the data + * @param channel_count nr of channels + * @param seek frames to seek in file + * @param resize 1 if array should be resized + * @param array_size size of the array in samples + * @param file filename + * @return new arraysiize, -1 if there was a failure + */ +int read_libvorbisfile(t_float** helper_arrays, int channel_count, int seek, + int resize, int array_size, t_symbol* file); + +#endif //_FILE_INPUT__ diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c index 9bf6b65..4cd14d9 100755 --- a/sndfiler/src/sndfiler.c +++ b/sndfiler/src/sndfiler.c @@ -1,6 +1,6 @@ /* * - * threaded soundfiler based on libsndfile + * threaded soundfiler for pd * Copyright (C) 2005, Tim Blechmann * (C) 2005, Georg Holzmann * @@ -20,14 +20,18 @@ * Boston, MA 02111-1307, USA. */ -/* to be compatible with main pd */ -#ifdef USE_PD_MAIN +#include "sndfiler.h" +#include "file_input.h" + -#define getalignedbytes(a) getbytes(a) -#define freealignedbytes(a,b) freebytes(a,b) -#include "threadlib.h" +/************ forward declarations **************/ -/* forward declaration */ +#ifdef UNIX +/* real-time flag, true if priority boosted */ +extern int sys_hipriority; +#endif + +#ifdef USE_PD_MAIN struct _garray { t_gobj x_gobj; @@ -39,56 +43,6 @@ struct _garray char x_saveit; /* true if we should save this with parent */ char x_listviewing; /* true if list view window is open */ }; - -#else /* now for pd_devel */ - -#include "m_pd.h" -#include "m_fifo.h" - -#include "pthread.h" - -#endif /* USE_PD_MAIN */ - - -#include "g_canvas.h" -#include "sndfile.h" - -#include "stdlib.h" -#include "sched.h" /* for thread priority */ -#include -#include "semaphore.h" - -/* for alloca */ -#ifdef MSW -#include -#else -#include "alloca.h" -#endif - -#if (_POSIX_MEMLOCK - 0) >= 200112L -#include -#endif /* _POSIX_MEMLOCK */ - -#ifdef __APPLE__ -#include -#include -#include -#define SEM_T semaphore_t -#define SEM_INIT(s) (semaphore_create(mach_task_self(),&s,SYNC_POLICY_FIFO,0) == 0) -#define SEM_SIGNAL(s) semaphore_signal(s) -#define SEM_WAIT(s) semaphore_wait(s) -#else -#define SEM_T sem_t -#define SEM_INIT(s) (sem_init(&s,0,0) == 0) -#define SEM_SIGNAL(s) sem_post(&s) -#define SEM_WAIT(s) sem_wait(&s) -#endif - -/************ forward declarations **************/ - -#ifdef UNIX -/* real-time flag, true if priority boosted */ -extern int sys_hipriority; #endif /* get a garray's "array" structure. */ @@ -206,7 +160,7 @@ static void sndfiler_start_thread(void) /* 1mb of stack should be enough */ pthread_attr_setstacksize(&sf_attr,1048576); - + #ifdef UNIX if (sys_hipriority == 1/* && getuid() == 0 */) { @@ -252,18 +206,15 @@ static t_int sndfiler_synchonize(t_int * w); static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) { - int i, j; + int i, j, lib; int channel_count; t_float** helper_arrays; int resize = 0; - int seek = 0, arraysize = 0, writesize; + int seek = 0, arraysize = 0; t_symbol* file; t_garray ** arrays; - SNDFILE* sndfile; - SF_INFO info; - // parse flags while (argc > 0 && argv->a_type == A_SYMBOL && *argv->a_w.w_symbol->s_name == '-') @@ -276,9 +227,10 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) } else if (!strcmp(flag, "skip")) { - if (argc < 2 || argv[1].a_type != A_FLOAT || - ((seek = argv[1].a_w.w_float) == 0)) + if (argc < 2 || argv[1].a_type != A_FLOAT) goto usage; + else + seek = argv[1].a_w.w_float; argc -= 2; argv += 2; } else goto usage; @@ -323,85 +275,23 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) } arraysize = size; } - - sndfile = sf_open(file->s_name, SFM_READ, &info); - if (sndfile) + lib = check_fileformat(file); + if(lib == USE_LIBSNDFILE) + arraysize = read_libsndfile(helper_arrays, channel_count, seek, + resize, arraysize, file); + else if(lib == USE_LIBVORBISFILE) + arraysize = read_libvorbisfile(helper_arrays, channel_count, seek, + resize, arraysize, file); + else { - int pos = 0; - int maxchannels = (channel_count < info.channels) ? - channel_count : info.channels; + pd_error(x, "Error opening file"); + return; + } - t_float * item = alloca(maxchannels * sizeof(t_float)); - + if(arraysize > 0) + { t_int ** syncdata = getbytes(sizeof(t_int*) * 5); - - // negative seek: offset from the end of the file - if(seek<0) - { - pos = sf_seek(sndfile, seek, SEEK_END); - } - if(seek>0) - { - pos = sf_seek(sndfile, seek, SEEK_SET); - } - if(pos == -1) - { - pd_error(x, "invalid seek in soundfile"); - return; - } - - if(resize) - { - writesize = (info.frames-pos); - arraysize = writesize; - } - else - writesize = (arraysize>(info.frames-pos)) ? - info.frames-pos : arraysize; - -#if (_POSIX_MEMLOCK - 0) >= 200112L - munlockall(); -#endif - - for (i = 0; i != channel_count; ++i) - { - helper_arrays[i] = getalignedbytes(arraysize * sizeof(t_float)); - } - - for (i = 0; i != writesize; ++i) - { - sf_read_float(sndfile, item, info.channels); - - for (j = 0; j != info.channels; ++j) - { - if (j < channel_count) - { - helper_arrays[j][i] = item[j]; - } - } - } - - // fill remaining elements with zero - if(!resize && (arraysize>(info.frames-pos))) - { - for (i = writesize; i != arraysize; ++i) - { - for (j = 0; j != info.channels; ++j) - { - if (j < channel_count) - { - helper_arrays[j][i] = 0; - } - } - } - } - -#if (_POSIX_MEMLOCK - 0) >= 200112L - mlockall(MCL_FUTURE); -#endif - - sf_close(sndfile); syncdata[0] = (t_int*)arrays; syncdata[1] = (t_int*)helper_arrays; diff --git a/sndfiler/src/sndfiler.h b/sndfiler/src/sndfiler.h new file mode 100755 index 0000000..f5fbd2c --- /dev/null +++ b/sndfiler/src/sndfiler.h @@ -0,0 +1,87 @@ +/* + * + * threaded soundfiler for pd + * Copyright (C) 2005, Tim Blechmann + * (C) 2005, Georg Holzmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _SND_FILER__ +#define _SND_FILER__ + + +/* to be compatible with main pd */ +#ifdef USE_PD_MAIN + +#define getalignedbytes(a) getbytes(a) +#define freealignedbytes(a,b) freebytes(a,b) +#include "threadlib.h" + +#else /* now for pd_devel */ + +#include "m_pd.h" +#include "m_fifo.h" + +#include "pthread.h" + +#endif /* USE_PD_MAIN */ + + +#include "g_canvas.h" +#include "sndfile.h" +#include "vorbis/codec.h" +#include "vorbis/vorbisfile.h" + +#include "stdlib.h" +#include +#include "sched.h" /* for thread priority */ +#include +#include "semaphore.h" + +#ifdef MSW +#include +#include +#endif + +/* for alloca */ +#ifdef MSW +#include +#else +#include "alloca.h" +#endif + +#if (_POSIX_MEMLOCK - 0) >= 200112L +#include +#endif /* _POSIX_MEMLOCK */ + +#ifdef __APPLE__ +#include +#include +#include +#define SEM_T semaphore_t +#define SEM_INIT(s) (semaphore_create(mach_task_self(),&s,SYNC_POLICY_FIFO,0) == 0) +#define SEM_SIGNAL(s) semaphore_signal(s) +#define SEM_WAIT(s) semaphore_wait(s) +#else +#define SEM_T sem_t +#define SEM_INIT(s) (sem_init(&s,0,0) == 0) +#define SEM_SIGNAL(s) sem_post(&s) +#define SEM_WAIT(s) sem_wait(&s) +#endif + + +#endif // _SND_FILER__ -- cgit v1.2.1 From ed1c74748d9e187b98ff49cf4d629019e0539584 Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Wed, 1 Feb 2006 09:02:20 +0000 Subject: updated helpfile for new ogg support svn path=/trunk/externals/tb/; revision=4532 --- sndfiler/doc/sndfiler-help.pd | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'sndfiler') diff --git a/sndfiler/doc/sndfiler-help.pd b/sndfiler/doc/sndfiler-help.pd index fb402f7..1e4dbeb 100755 --- a/sndfiler/doc/sndfiler-help.pd +++ b/sndfiler/doc/sndfiler-help.pd @@ -25,12 +25,9 @@ #X obj 241 667 table array2; #X obj 55 645 sndfiler; #X text 288 34 threaded soundfiler; -#X text 308 51 using libsndfile; #X text 161 113 ::: SNDFILER :::; -#X text 63 152 A threaded soundfiler for PD using libsndfile.; #X text 65 182 REQUIREMENTS:; #X text 118 199 - pd >= 0.39; -#X text 118 215 - libsndfile; #X text 118 231 - threadlib (for main pd); #X text 48 539 threaded resize of arrays:; #X text 33 267 read a file: read [flags] filename array1 array2 ... @@ -42,12 +39,16 @@ #X text 33 324 -skip : skip nr. of samples in soundfile \, if negative \, it will be counted from the end of the file !; #X text 82 722 (c) 2005 \, Tim Blechmann \, Georg Holzmann; +#X text 184 53 using libsndfile and libvorbisfile; +#X text 53 140 A threaded soundfiler for PD using libsndfile and libvorbisfile +(for ogg files).; +#X text 118 215 - libsndfile + libvorbisfile; #X connect 3 0 20 0; -#X connect 4 0 31 0; +#X connect 4 0 28 0; #X connect 6 0 4 0; #X connect 10 0 9 0; #X connect 12 0 18 0; #X connect 14 0 12 0; #X connect 18 0 13 0; #X connect 20 0 2 0; -#X connect 31 0 5 0; +#X connect 28 0 5 0; -- cgit v1.2.1 From 6c03ffeef182c00462a6d0375ed81dc0d9983124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Thu, 19 Jun 2008 13:50:58 +0000 Subject: removed the svn:executable bit for code, patches and text svn path=/trunk/externals/tb/; revision=10048 --- sndfiler/GnuGPL.txt | 0 sndfiler/doc/sndfiler-help.pd | 0 sndfiler/src/sndfiler.c | 0 sndfiler/src/sndfiler.h | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 sndfiler/GnuGPL.txt mode change 100755 => 100644 sndfiler/doc/sndfiler-help.pd mode change 100755 => 100644 sndfiler/src/sndfiler.c mode change 100755 => 100644 sndfiler/src/sndfiler.h (limited to 'sndfiler') diff --git a/sndfiler/GnuGPL.txt b/sndfiler/GnuGPL.txt old mode 100755 new mode 100644 diff --git a/sndfiler/doc/sndfiler-help.pd b/sndfiler/doc/sndfiler-help.pd old mode 100755 new mode 100644 diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c old mode 100755 new mode 100644 diff --git a/sndfiler/src/sndfiler.h b/sndfiler/src/sndfiler.h old mode 100755 new mode 100644 -- cgit v1.2.1 From 2c1ff19c4d99921dcd55176b5574e932dda39c68 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 9 Jun 2009 17:34:48 +0000 Subject: replaced -export_dynamic with --export-dynamic and -Wl,--export-dynamic where appropriate. It seems that once upon a time -export_dynamic was a real flag. Now it means -e xport_dynamic, meaning set the entry symbol to xport_dynamic, giving this error message: /usr/bin/ld: warning: cannot find entry symbol xport_dynamic; defaulting to 0000000000001b60 svn path=/trunk/externals/tb/; revision=11724 --- sndfiler/src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sndfiler') diff --git a/sndfiler/src/Makefile b/sndfiler/src/Makefile index b8f1c8a..3bcd658 100755 --- a/sndfiler/src/Makefile +++ b/sndfiler/src/Makefile @@ -74,7 +74,7 @@ LSTRIP = strip --strip-unneeded -R .note -R .comment .c.pd_linux: cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o sndfiler.o -c sndfiler.c cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o file_input.o -c file_input.c - cc -Wl,-export_dynamic --shared -o $*.pd_linux $(OBJ) -lm -lsndfile -lvorbisfile + cc -Wl,--export-dynamic --shared -o $*.pd_linux $(OBJ) -lm -lsndfile -lvorbisfile # $(LSTRIP) $*.pd_linux rm -f $*.o -- cgit v1.2.1