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(a)mur.at>
--- 1,5 ----
/*
*
! * threaded soundfiler for pd
* Copyright (C) 2005, Tim Blechmann
* (C) 2005, Georg Holzmann <grh(a)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(a)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(a)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(a)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;
}