2 Copyright (C) 2003 Paul Brossier
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "aubio_priv.h"
26 #include "sndfileio.h"
27 #include "mathutils.h"
29 #define MAX_CHANNELS 6
32 struct _aubio_file_t {
37 float *tmpdata; /** scratch pad for interleaving/deinterleaving. */
38 int size; /** store the size to check if realloc needed */
41 aubio_file_t * new_file_ro(const char* outputname) {
42 aubio_file_t * f = AUBIO_NEW(aubio_file_t);
44 AUBIO_MEMSET(&sfinfo, 0, sizeof (sfinfo));
46 if (! (f->handle = sf_open (outputname, SFM_READ, &sfinfo))) {
47 AUBIO_ERR("Not able to open input file %s.\n", outputname);
48 AUBIO_ERR("%s\n",sf_strerror (NULL)); /* libsndfile err msg */
49 AUBIO_QUIT(AUBIO_FAIL);
52 if (sfinfo.channels > MAX_CHANNELS) {
53 AUBIO_ERR("Not able to process more than %d channels\n", MAX_CHANNELS);
54 AUBIO_QUIT(AUBIO_FAIL);
57 f->size = MAX_SIZE*sfinfo.channels;
58 f->tmpdata = AUBIO_ARRAY(float,f->size);
60 f->samplerate = sfinfo.samplerate;
61 f->channels = sfinfo.channels;
62 f->format = sfinfo.format;
67 int file_open_wo(aubio_file_t * f, const char* inputname) {
69 memset (&sfinfo, 0, sizeof (sfinfo));
71 /* define file output spec */
72 sfinfo.samplerate = f->samplerate;
73 sfinfo.channels = f->channels;
74 sfinfo.format = f->format;
76 if (! (f->handle = sf_open (inputname, SFM_WRITE, &sfinfo))) {
77 AUBIO_ERR("Not able to open output file %s.\n", inputname);
78 AUBIO_ERR("%s\n",sf_strerror (NULL)); /* libsndfile err msg */
79 AUBIO_QUIT(AUBIO_FAIL);
82 if (sfinfo.channels > MAX_CHANNELS) {
83 AUBIO_ERR("Not able to process more than %d channels\n", MAX_CHANNELS);
84 AUBIO_QUIT(AUBIO_FAIL);
86 f->size = MAX_SIZE*sfinfo.channels;
87 f->tmpdata = AUBIO_ARRAY(float,f->size);
91 /* setup file struct from existing one */
92 aubio_file_t * new_file_wo(aubio_file_t * fmodel, const char *outputname) {
93 aubio_file_t * f = AUBIO_NEW(aubio_file_t);
94 f->samplerate = fmodel->samplerate;
95 f->channels = fmodel->channels;
96 f->format = fmodel->format;
97 file_open_wo(f, outputname);
102 /* return 0 if properly closed, 1 otherwise */
103 int del_file(aubio_file_t * f) {
104 if (sf_close(f->handle)) {
105 AUBIO_ERR("Error closing file.");
106 puts (sf_strerror (NULL));
109 AUBIO_FREE(f->tmpdata);
111 //AUBIO_DBG("File closed.\n");
115 /**************************************************************
122 /* read frames from file in data
123 * return the number of frames actually read */
124 int file_read(aubio_file_t * f, int frames, fvec_t * read) {
125 sf_count_t read_frames;
126 int i,j, channels = f->channels;
127 int nsamples = frames*channels;
131 /* allocate data for de/interleaving reallocated when needed. */
132 if (nsamples >= f->size) {
133 AUBIO_ERR("Maximum file_read buffer size exceeded.");
136 AUBIO_FREE(f->tmpdata);
137 f->tmpdata = AUBIO_ARRAY(float,nsamples);
140 //f->size = nsamples;
142 /* do actual reading */
143 read_frames = sf_read_float (f->handle, f->tmpdata, nsamples);
145 aread = (int)FLOOR(read_frames/(float)channels);
147 /* de-interleaving data */
148 for (i=0; i<channels; i++) {
149 pread = fvec_get_channel(read,i);
150 for (j=0; j<aread; j++) {
151 pread[j] = f->tmpdata[channels*j+i];
157 /* write 'frames' samples to file from data
158 * return the number of frames actually written
160 int file_write(aubio_file_t * f, int frames, fvec_t * write) {
161 sf_count_t written_frames = 0;
162 int i, j, channels = f->channels;
163 int nsamples = channels*frames;
166 /* allocate data for de/interleaving reallocated when needed. */
167 if (nsamples >= f->size) {
168 AUBIO_ERR("Maximum file_write buffer size exceeded.");
171 AUBIO_FREE(f->tmpdata);
172 f->tmpdata = AUBIO_ARRAY(float,nsamples);
175 //f->size = nsamples;
177 /* interleaving data */
178 for (i=0; i<channels; i++) {
179 pwrite = fvec_get_channel(write,i);
180 for (j=0; j<frames; j++) {
181 f->tmpdata[channels*j+i] = pwrite[j];
184 written_frames = sf_write_float (f->handle, f->tmpdata, nsamples);
185 return written_frames/channels;
188 /*******************************************************************
194 uint_t aubio_file_channels(aubio_file_t * f) {
198 uint_t aubio_file_samplerate(aubio_file_t * f) {
199 return f->samplerate;
202 void file_info(aubio_file_t * f) {
203 AUBIO_DBG("srate : %d\n", f->samplerate);
204 AUBIO_DBG("channels : %d\n", f->channels);
205 AUBIO_DBG("format : %d\n", f->format);