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.
20 #include "aubio_priv.h"
23 #include "mathutils.h"
26 /** phasevocoder internal object */
27 struct _aubio_pvoc_t {
32 /** number of channels */
35 aubio_fft_t * spectrum;
36 /**cur output grain [win_s] */
38 /**last input frame [win_s-hop_s] */
40 /**current spectrum [win_s] */
42 /**current input grain [win_s] */
44 /**last input frame [win_s-hop_s] */
46 /** grain window [win_s] */
51 /** memory allocation */
52 static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels);
53 /** object deletion */
54 static void aubio_pvoc_free (aubio_pvoc_t *pv);
55 /** returns data and dataold slided by hop_s */
56 static void aubio_pvoc_swapbuffers(
59 const smpl_t * datanew,
60 uint_t win_s, uint_t hop_s);
61 /** do additive synthesis from 'old' and 'cur' */
62 static void aubio_pvoc_addsynth(
66 uint_t win_s, uint_t hop_s);
69 void aubio_pvoc_do(aubio_pvoc_t *pv, fvec_t * datanew, cvec_t *fftgrain) {
71 for (i=0; i<pv->channels; i++) {
73 aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i],
74 datanew->data[i],pv->win_s,pv->hop_s);
76 for (j=0; j<pv->win_s; j++) pv->data->data[i][j] *= pv->w[j];
80 aubio_fft_do(pv->spectrum,pv->data->data[i],pv->spec[i],pv->win_s);
81 /* put norm and phase to fftgrain */
82 aubio_fft_getnorm(fftgrain->norm[i], pv->spec[i], pv->win_s/2+1);
83 aubio_fft_getphas(fftgrain->phas[i], pv->spec[i], pv->win_s/2+1);
87 void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
89 for (i=0; i<pv->channels; i++) {
90 for (j=0; j<pv->win_s/2+1; j++) {
91 pv->spec[i][j] = CEXPC(I*unwrap2pi(fftgrain->phas[i][j]));
92 pv->spec[i][j] *= fftgrain->norm[i][j];
94 aubio_fft_rdo(pv->spectrum,pv->spec[i],pv->synth->data[i],pv->win_s);
96 for (j=0; j<pv->win_s; j++) pv->synth->data[i][j] *= pv->w[j];
97 aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i],
98 synthnew->data[i],pv->win_s,pv->hop_s);
102 void del_aubio_pvoc(aubio_pvoc_t *pv) {
106 aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) {
107 aubio_pvoc_t * pv = aubio_pvoc_malloc(win_s, hop_s, channels);
108 window(pv->w,pv->win_s,hanningz);
112 static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels) {
115 aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
117 if (win_s < 2*hop_s) {
118 AUBIO_ERR("Window size is smaller than twice the hop size!\n");
123 AUBIO_ERR("Hop size is smaller than 1!\n");
127 pv->spectrum = new_aubio_fft(win_s);
130 pv->data = new_fvec (win_s, channels);
131 pv->synth = new_fvec (win_s, channels);
133 /* new input output */
134 pv->dataold = new_fvec (win_s-hop_s, channels);
135 pv->synthold = new_fvec (win_s-hop_s, channels);
136 pv->w = AUBIO_ARRAY(smpl_t,win_s);
138 pv->spec = AUBIO_ARRAY(fft_data_t*,channels);
139 for (i=0; i<channels; i++)
140 pv->spec[i] = AUBIO_ARRAY(fft_data_t,win_s);
142 pv->channels = channels;
149 static void aubio_pvoc_free (aubio_pvoc_t *pv) {
151 del_aubio_fft(pv->spectrum);
154 del_fvec(pv->dataold);
155 del_fvec(pv->synthold);
157 for (i=0; i< pv->channels; i++) {
158 AUBIO_FREE(pv->spec[i]);
160 AUBIO_FREE(pv->spec);
164 static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold, const smpl_t * datanew,
165 uint_t win_s, uint_t hop_s)
168 for (i=0;i<win_s-hop_s;i++)
169 data[i] = dataold[i];
170 for (i=0;i<hop_s;i++)
171 data[win_s-hop_s+i] = datanew[i];
172 for (i=0;i<win_s-hop_s;i++)
173 dataold[i] = data[i+hop_s];
176 static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, smpl_t * synthnew,
177 uint_t win_s, uint_t hop_s)
180 smpl_t scale = 2*hop_s/(win_s+.0);
181 /* add new synth to old one and put result in synthnew */
182 for (i=0;i<hop_s;i++)
183 synthnew[i] = synthold[i]+synth[i]*scale;
185 for (i=0;i<win_s-2*hop_s;i++)
186 synthold[i] = synthold[i+hop_s];
187 /* erase last frame in synthold */
188 for (i=win_s-hop_s;i<win_s;i++)
189 synthold[i-hop_s]=0.;
191 for (i=0;i<win_s-hop_s;i++)
192 synthold[i] += synth[i+hop_s]*scale;