Update of /cvsroot/pure-data/externals/tb/sndfiler/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3607
Modified Files: sndfiler.c Makefile Makefile.pd_main Added Files: file_input.c file_input.h sndfiler.h Log Message: now possible to read ogg file (using libvorbisfile)
Index: sndfiler.c =================================================================== RCS file: /cvsroot/pure-data/externals/tb/sndfiler/src/sndfiler.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** sndfiler.c 29 Jan 2006 22:13:49 -0000 1.10 --- sndfiler.c 1 Feb 2006 09:01:28 -0000 1.11 *************** *** 1,5 **** /* * ! * threaded soundfiler based on libsndfile * Copyright (C) 2005, Tim Blechmann * (C) 2005, Georg Holzmann grh@mur.at --- 1,5 ---- /* * ! * threaded soundfiler for pd * Copyright (C) 2005, Tim Blechmann * (C) 2005, Georg Holzmann grh@mur.at *************** *** 21,32 **** */
! /* 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 { --- 21,36 ---- */
! #include "sndfiler.h" ! #include "file_input.h"
! /************ forward declarations **************/ ! ! #ifdef UNIX ! /* real-time flag, true if priority boosted */ ! extern int sys_hipriority; ! #endif ! ! #ifdef USE_PD_MAIN struct _garray { *************** *** 40,93 **** 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 <string.h> - #include "semaphore.h" - - /* for alloca */ - #ifdef MSW - #include <malloc.h> - #else - #include "alloca.h" - #endif - - #if (_POSIX_MEMLOCK - 0) >= 200112L - #include <sys/mman.h> - #endif /* _POSIX_MEMLOCK */ - - #ifdef __APPLE__ - #include <mach/mach.h> - #include <mach/task.h> - #include <mach/semaphore.h> - #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
--- 44,47 ---- *************** *** 207,211 **** /* 1mb of stack should be enough */ pthread_attr_setstacksize(&sf_attr,1048576); ! #ifdef UNIX if (sys_hipriority == 1/* && getuid() == 0 */) --- 161,165 ---- /* 1mb of stack should be enough */ pthread_attr_setstacksize(&sf_attr,1048576); ! #ifdef UNIX if (sys_hipriority == 1/* && getuid() == 0 */) *************** *** 253,268 **** 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; - // parse flags while (argc > 0 && argv->a_type == A_SYMBOL && --- 207,219 ---- static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv) { ! int i, j, lib; int channel_count; t_float** helper_arrays; int resize = 0; ! int seek = 0, arraysize = 0;
t_symbol* file; t_garray ** arrays;
// parse flags while (argc > 0 && argv->a_type == A_SYMBOL && *************** *** 277,283 **** 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; } --- 228,235 ---- else if (!strcmp(flag, "skip")) { ! if (argc < 2 || argv[1].a_type != A_FLOAT) goto usage; + else + seek = argv[1].a_w.w_float; argc -= 2; argv += 2; } *************** *** 324,406 **** arraysize = size; } - - 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; - - #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; --- 276,296 ---- arraysize = size; }
! 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 { ! pd_error(x, "Error opening file"); ! return; ! }
! if(arraysize > 0) ! { t_int ** syncdata = getbytes(sizeof(t_int*) * 5);
syncdata[0] = (t_int*)arrays;
Index: Makefile.pd_main =================================================================== RCS file: /cvsroot/pure-data/externals/tb/sndfiler/src/Makefile.pd_main,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Makefile.pd_main 29 Jan 2006 19:29:29 -0000 1.4 --- Makefile.pd_main 1 Feb 2006 09:01:28 -0000 1.5 *************** *** 42,45 **** --- 42,47 ---- LD_FLAGS = --export-dynamic -shared -o
+ OBJ=sndfiler.o file_input.o + current: @echo ---------------------------- *************** *** 57,65 ****
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 --- 59,68 ----
CC_UNIX = -DUNIX -fPIC -pthread ! LIB_UNIX = -lc -lm -lsndfile -lvorbisfile $(THREADLIB_PATH)/threadlib.pd_linux
.c.pd_linux: ! $(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 *************** *** 98,106 **** LD_DARWIN = -bundle -undefined suppress -flat_namespace \ -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) -o $*.pd_darwin $*.o $(LIB) chmod 755 $*.pd_darwin --- 101,110 ---- LD_DARWIN = -bundle -undefined suppress -flat_namespace \ -bundle_loader $(PD_PATH)/bin/pd --export-dynamic \ ! -L/sw/lib -L/opt/local/lib -lsndfile -lvorbisfile \ $(THREADLIB_PATH)/threadlib.pd_darwin
.c.pd_darwin: ! $(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
--- NEW FILE: sndfiler.h --- /* * * threaded soundfiler for pd * Copyright (C) 2005, Tim Blechmann * (C) 2005, Georg Holzmann grh@mur.at * * 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 <stdio.h> #include "sched.h" /* for thread priority */ #include <string.h> #include "semaphore.h"
#ifdef MSW #include <io.h> #include <fcntl.h> #endif
/* for alloca */ #ifdef MSW #include <malloc.h> #else #include "alloca.h" #endif
#if (_POSIX_MEMLOCK - 0) >= 200112L #include <sys/mman.h> #endif /* _POSIX_MEMLOCK */
#ifdef __APPLE__ #include <mach/mach.h> #include <mach/task.h> #include <mach/semaphore.h> #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__
Index: Makefile =================================================================== RCS file: /cvsroot/pure-data/externals/tb/sndfiler/src/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Makefile 20 Nov 2005 21:54:41 -0000 1.1 --- Makefile 1 Feb 2006 09:01:28 -0000 1.2 *************** *** 3,6 **** --- 3,8 ---- CSYM=sndfiler
+ OBJ=sndfiler.o file_input.o + current: pd_linux
*************** *** 66,76 **** -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 --- 68,79 ---- -Wno-unused -Wno-parentheses -Wno-switch
! LINUXINCLUDE = -I../../../../pd/src
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 # $(LSTRIP) $*.pd_linux rm -f $*.o
--- NEW FILE: file_input.h --- /* * threaded soundfiler for PD * Copyright (C) 2005, Georg Holzmann grh@mur.at * * 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__
--- NEW FILE: file_input.c --- /* * threaded soundfiler for PD * Copyright (C) 2005, Georg Holzmann grh@mur.at * * 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; }