aboutsummaryrefslogtreecommitdiff
path: root/sndfiler
diff options
context:
space:
mode:
Diffstat (limited to 'sndfiler')
-rwxr-xr-xsndfiler/src/Makefile9
-rwxr-xr-xsndfiler/src/Makefile.pd_main14
-rw-r--r--sndfiler/src/file_input.c253
-rw-r--r--sndfiler/src/file_input.h66
-rwxr-xr-xsndfiler/src/sndfiler.c170
-rwxr-xr-xsndfiler/src/sndfiler.h87
6 files changed, 451 insertions, 148 deletions
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 <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,
+ &current_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 <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__
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 <grh@mur.at>
*
@@ -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 <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
/* 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 <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__