diff options
Diffstat (limited to 'sndfiler/sndfiler.c')
-rw-r--r-- | sndfiler/sndfiler.c | 322 |
1 files changed, 0 insertions, 322 deletions
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 <sys/mman.h> -#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(); -} - - |