source: ext/sndfileio.c @ 9e0dd58

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 9e0dd58 was d69e37d, checked in by Paul Brossier <piem@piem.org>, 15 years ago

ext/sndfileio.c: convert data from and to float if smpl_t != float

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2   Copyright (C) 2003 Paul Brossier
3
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.
8
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.
13
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.
17
18*/
19
20#include <string.h>
21
22#include <sndfile.h>
23
24#include "aubio_priv.h"
25#include "fvec.h"
26#include "sndfileio.h"
27#include "mathutils.h"
28
29#define MAX_CHANNELS 6
30#define MAX_SIZE 4096
31
32struct _aubio_sndfile_t {
33        SNDFILE *handle;
34        int samplerate;
35        int channels;
36        int format;
37        float *tmpdata; /** scratch pad for interleaving/deinterleaving. */
38        int size;       /** store the size to check if realloc needed */
39};
40
41aubio_sndfile_t * new_aubio_sndfile_ro(const char* outputname) {
42        aubio_sndfile_t * f = AUBIO_NEW(aubio_sndfile_t);
43        SF_INFO sfinfo;
44        AUBIO_MEMSET(&sfinfo, 0, sizeof (sfinfo));
45
46        f->handle = sf_open (outputname, SFM_READ, &sfinfo);
47
48        if (f->handle == NULL) {
49                AUBIO_ERR("Failed opening %s: %s\n", outputname,
50                        sf_strerror (NULL)); /* libsndfile err msg */
51                return NULL;
52        }       
53
54        if (sfinfo.channels > MAX_CHANNELS) { 
55                AUBIO_ERR("Not able to process more than %d channels\n", MAX_CHANNELS);
56                return NULL;
57        }
58
59        f->size       = MAX_SIZE*sfinfo.channels;
60        f->tmpdata    = AUBIO_ARRAY(float,f->size);
61        /* get input specs */
62        f->samplerate = sfinfo.samplerate;
63        f->channels   = sfinfo.channels;
64        f->format     = sfinfo.format;
65
66        return f;
67}
68
69int aubio_sndfile_open_wo(aubio_sndfile_t * f, const char* inputname) {
70        SF_INFO sfinfo;
71        AUBIO_MEMSET(&sfinfo, 0, sizeof (sfinfo));
72
73        /* define file output spec */
74        sfinfo.samplerate = f->samplerate;
75        sfinfo.channels   = f->channels;
76        sfinfo.format     = f->format;
77
78        if (! (f->handle = sf_open (inputname, SFM_WRITE, &sfinfo))) {
79                AUBIO_ERR("Not able to open output file %s.\n", inputname);
80                AUBIO_ERR("%s\n",sf_strerror (NULL)); /* libsndfile err msg */
81                AUBIO_QUIT(AUBIO_FAIL);
82        }       
83
84        if (sfinfo.channels > MAX_CHANNELS) { 
85                AUBIO_ERR("Not able to process more than %d channels\n", MAX_CHANNELS);
86                AUBIO_QUIT(AUBIO_FAIL);
87        }
88        f->size       = MAX_SIZE*sfinfo.channels;
89        f->tmpdata    = AUBIO_ARRAY(float,f->size);
90        return AUBIO_OK;
91}
92
93/* setup file struct from existing one */
94aubio_sndfile_t * new_aubio_sndfile_wo(aubio_sndfile_t * fmodel, const char *outputname) {
95        aubio_sndfile_t * f = AUBIO_NEW(aubio_sndfile_t);
96        f->samplerate    = fmodel->samplerate;
97        f->channels      = fmodel->channels;
98        f->format        = fmodel->format;
99        aubio_sndfile_open_wo(f, outputname);
100        return f;
101}
102
103
104/* return 0 if properly closed, 1 otherwise */
105int del_aubio_sndfile(aubio_sndfile_t * f) {
106        if (sf_close(f->handle)) {
107                AUBIO_ERR("Error closing file.");
108                puts (sf_strerror (NULL));
109                return 1;
110        }
111        AUBIO_FREE(f->tmpdata);
112        AUBIO_FREE(f);
113        //AUBIO_DBG("File closed.\n");
114        return 0;
115}
116
117/**************************************************************
118 *
119 * Read write methods
120 *
121 */
122
123
124/* read frames from file in data
125 *  return the number of frames actually read */
126int aubio_sndfile_read(aubio_sndfile_t * f, int frames, fvec_t * read) {
127        sf_count_t read_frames;
128        int i,j, channels = f->channels;
129        int nsamples = frames*channels;
130        int aread;
131        smpl_t *pread; 
132
133        /* allocate data for de/interleaving reallocated when needed. */
134        if (nsamples >= f->size) {
135                AUBIO_ERR("Maximum aubio_sndfile_read buffer size exceeded.");
136                return -1;
137                /*
138                AUBIO_FREE(f->tmpdata);
139                f->tmpdata = AUBIO_ARRAY(float,nsamples);
140                */
141        }
142        //f->size = nsamples;
143
144        /* do actual reading */
145        read_frames = sf_read_float (f->handle, f->tmpdata, nsamples);
146
147        aread = (int)FLOOR(read_frames/(float)channels);
148
149        /* de-interleaving data  */
150        for (i=0; i<channels; i++) {
151                pread = (smpl_t *)fvec_get_channel(read,i);
152                for (j=0; j<aread; j++) {
153                        pread[j] = (smpl_t)f->tmpdata[channels*j+i];
154                }
155        }
156        return aread;
157}
158
159/* write 'frames' samples to file from data
160 *   return the number of frames actually written
161 */
162int aubio_sndfile_write(aubio_sndfile_t * f, int frames, fvec_t * write) {
163        sf_count_t written_frames = 0;
164        int i, j,       channels = f->channels;
165        int nsamples = channels*frames;
166        smpl_t *pwrite;
167
168        /* allocate data for de/interleaving reallocated when needed. */
169        if (nsamples >= f->size) {
170                AUBIO_ERR("Maximum aubio_sndfile_write buffer size exceeded.");
171                return -1;
172                /*
173                AUBIO_FREE(f->tmpdata);
174                f->tmpdata = AUBIO_ARRAY(float,nsamples);
175                */
176        }
177        //f->size = nsamples;
178
179        /* interleaving data  */
180        for (i=0; i<channels; i++) {
181                pwrite = (smpl_t *)fvec_get_channel(write,i);
182                for (j=0; j<frames; j++) {
183                        f->tmpdata[channels*j+i] = (float)pwrite[j];
184                }
185        }
186        written_frames = sf_write_float (f->handle, f->tmpdata, nsamples);
187        return written_frames/channels;
188}
189
190/*******************************************************************
191 *
192 * Get object info
193 *
194 */
195
196uint_t aubio_sndfile_channels(aubio_sndfile_t * f) {
197        return f->channels;
198}
199
200uint_t aubio_sndfile_samplerate(aubio_sndfile_t * f) {
201        return f->samplerate;
202}
203
204void aubio_sndfile_info(aubio_sndfile_t * f) {
205        AUBIO_DBG("srate    : %d\n", f->samplerate);
206        AUBIO_DBG("channels : %d\n", f->channels);
207        AUBIO_DBG("format   : %d\n", f->format);
208}
209
Note: See TracBrowser for help on using the repository browser.