aboutsummaryrefslogtreecommitdiff
path: root/sndfiler/sndfiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'sndfiler/sndfiler.c')
-rw-r--r--sndfiler/sndfiler.c322
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();
-}
-
-