source: ext/sndfileio.c @ 9cf2833

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

moved jack and sndfile to aubioext

  • Property mode set to 100644
File size: 6.3 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 "sample.h"
26#include "sndfileio.h"
27#include "mathutils.h"
28
29#define MAX_CHANNELS 6
30#define MAX_SIZE 4096
31
32struct _aubio_file_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_file_t * new_file_ro(const char* outputname) {
42        aubio_file_t * f = AUBIO_NEW(aubio_file_t);
43        SF_INFO sfinfo;
44        AUBIO_MEMSET(&sfinfo, 0, sizeof (sfinfo));
45
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);
50        }       
51
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);
55        }
56
57        f->size       = MAX_SIZE*sfinfo.channels;
58        f->tmpdata    = AUBIO_ARRAY(float,f->size);
59        /* get input specs */
60        f->samplerate = sfinfo.samplerate;
61        f->channels   = sfinfo.channels;
62        f->format     = sfinfo.format;
63
64        return f;
65}
66
67int file_open_wo(aubio_file_t * f, const char* inputname) {
68        SF_INFO sfinfo;
69        memset (&sfinfo, 0, sizeof (sfinfo));
70
71        /* define file output spec */
72        sfinfo.samplerate = f->samplerate;
73        sfinfo.channels   = f->channels;
74        sfinfo.format     = f->format;
75
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);
80        }       
81
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);
85        }
86        f->size       = MAX_SIZE*sfinfo.channels;
87        f->tmpdata    = AUBIO_ARRAY(float,f->size);
88        return AUBIO_OK;
89}
90
91/* setup file struct from existing one */
92aubio_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);
98        return f;
99}
100
101
102/* return 0 if properly closed, 1 otherwise */
103int del_file(aubio_file_t * f) {
104        if (sf_close(f->handle)) {
105                AUBIO_ERR("Error closing file.");
106                puts (sf_strerror (NULL));
107                return 1;
108        }
109        AUBIO_FREE(f->tmpdata);
110        AUBIO_FREE(f);
111        //AUBIO_DBG("File closed.\n");
112        return 0;
113}
114
115/**************************************************************
116 *
117 * Read write methods
118 *
119 */
120
121
122/* read frames from file in data
123 *  return the number of frames actually read */
124int 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;
128        int aread;
129        float *pread;   
130
131        /* allocate data for de/interleaving reallocated when needed. */
132        if (nsamples >= f->size) {
133                AUBIO_ERR("Maximum file_read buffer size exceeded.");
134                return -1;
135                /*
136                AUBIO_FREE(f->tmpdata);
137                f->tmpdata = AUBIO_ARRAY(float,nsamples);
138                */
139        }
140        //f->size = nsamples;
141
142        /* do actual reading */
143        read_frames = sf_read_float (f->handle, f->tmpdata, nsamples);
144
145        aread = (int)FLOOR(read_frames/(float)channels);
146
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];
152                }
153        }
154        return aread;
155}
156
157/* write 'frames' samples to file from data
158 *   return the number of frames actually written
159 */
160int 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;
164        float *pwrite;
165
166        /* allocate data for de/interleaving reallocated when needed. */
167        if (nsamples >= f->size) {
168                AUBIO_ERR("Maximum file_write buffer size exceeded.");
169                return -1;
170                /*
171                AUBIO_FREE(f->tmpdata);
172                f->tmpdata = AUBIO_ARRAY(float,nsamples);
173                */
174        }
175        //f->size = nsamples;
176
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];
182                }
183        }
184        written_frames = sf_write_float (f->handle, f->tmpdata, nsamples);
185        return written_frames/channels;
186}
187
188/*******************************************************************
189 *
190 * Get object info
191 *
192 */
193
194uint_t aubio_file_channels(aubio_file_t * f) {
195        return f->channels;
196}
197
198uint_t aubio_file_samplerate(aubio_file_t * f) {
199        return f->samplerate;
200}
201
202void 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);
206}
207
Note: See TracBrowser for help on using the repository browser.