From 3d705ecb42583d1653188fcb172f8d4b8b7645d4 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Fri, 24 Aug 2007 14:54:02 +1000 Subject: [PATCH] Add file Octave/sfread.cc and hook into build. --- .bzrignore | 1 + Octave/Makefile.am | 2 ++ Octave/sfread.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 Octave/sfread.cc diff --git a/.bzrignore b/.bzrignore index 513346a1..06f9f469 100644 --- a/.bzrignore +++ b/.bzrignore @@ -83,3 +83,4 @@ tests/utils.c tests/utils.h tests/write_read_test.c src/FLAC/src/test_libFLAC/matrix +*.oct diff --git a/Octave/Makefile.am b/Octave/Makefile.am index 414b2e40..fb872e3a 100644 --- a/Octave/Makefile.am +++ b/Octave/Makefile.am @@ -6,6 +6,8 @@ octconfigdir = $(exec_prefix)/share/octave/site/m octconfig_DATA = sndfile_load.m sndfile_save.m sndfile_play.m +sfread.oct : sfread.cc + $(MKOCTFILE) $< -lsndfile %.o: %.c ; $(MKOCTFILE) -c $< %.o: %.f ; $(MKOCTFILE) -c $< diff --git a/Octave/sfread.cc b/Octave/sfread.cc new file mode 100644 index 00000000..a801c2e0 --- /dev/null +++ b/Octave/sfread.cc @@ -0,0 +1,90 @@ +/* +** Copyright (C) 2007 Erik de Castro Lopo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +//#include +#include + +#include "sndfile.h" + +#define FOUR_GIG (0x100000000LL) + +DEFUN_DLD (sfread, args, nargout , "\ +-*- texinfo -*-\n\ +@deftypefn {Function File} {@var{I} =} sfread (@var{filename})\n\ +Read a sound file from disk using libsndfile.\n\ +\n\ +@seealso{wavread}\n\ +@end deftypefn\n\ +") { + SNDFILE * file ; + SF_INFO sfinfo ; + + octave_value_list retval ; + + int nargin = args.length () ; + + /* Bail out if the input parameters are bad. */ + if ((nargin != 1) || !args (0) .is_string () || (nargout < 1)) + { print_usage () ; + return retval ; + } ; + + memset (&sfinfo, 0, sizeof (sfinfo)) ; + + std::string filename = args (0) .string_value () ; + + if ((file = sf_open (filename.c_str (), SFM_READ, &sfinfo)) == NULL) + { error ("sfread: couldn't open file %s : %s", filename.c_str (), sf_strerror (NULL)) ; + return retval ; + } ; + + if (sfinfo.frames > FOUR_GIG) + printf ("This is a really huge file (%d Meg).\nYou may run out of memory trying to load it.\n", sfinfo.frames / (1024 * 1024)) ; + + dim_vector dim = dim_vector () ; + dim.resize (2) ; + dim (0) = sfinfo.frames ; + dim (1) = sfinfo.channels ; + NDArray out = NDArray (dim, 0.0) ; + + float buffer [4096 * sfinfo.channels] ; + int readcount ; + sf_count_t total = 0 ; + + do + { readcount = sf_read_float (file, buffer, 4096) ; + + /* Make sure we don't read more frames than we allocated. */ + if (total + readcount > sfinfo.frames) + readcount = sfinfo.frames - total ; + + for (unsigned ch = 0 ; ch < sfinfo.channels ; ch++) + { for (int k = 0 ; k < readcount ; k++) + out (total + k, ch) = buffer [k * sfinfo.channels + ch] ; + } ; + + total += readcount ; + } while (readcount > 0 && total < sfinfo.frames) ; + + retval.append (out.squeeze ()) ; + + /* Clean up. */ + sf_close (file) ; + + return retval ; +} /* sfread */