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 */
36 /**cur output grain [win_s] */
38 /**last input frame [win_s-hop_s] */
40 /**current input grain [win_s] */
42 /**last input frame [win_s-hop_s] */
44 /** grain window [win_s] */
49 /** returns data and dataold slided by hop_s */
50 static void aubio_pvoc_swapbuffers(
53 const smpl_t * datanew,
54 uint_t win_s, uint_t hop_s);
55 /** do additive synthesis from 'old' and 'cur' */
56 static void aubio_pvoc_addsynth(
60 uint_t win_s, uint_t hop_s);
63 void aubio_pvoc_do(aubio_pvoc_t *pv, fvec_t * datanew, cvec_t *fftgrain) {
65 for (i=0; i<pv->channels; i++) {
67 aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i],
68 datanew->data[i],pv->win_s,pv->hop_s);
70 for (j=0; j<pv->win_s; j++) pv->data->data[i][j] *= pv->w[j];
75 aubio_mfft_do (pv->fft,pv->data,fftgrain);
78 void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
81 aubio_mfft_rdo(pv->fft,fftgrain,pv->synth);
84 for (i=0; i<pv->channels; i++) {
85 for (j=0; j<pv->win_s; j++) pv->synth->data[i][j] *= pv->w[j];
86 aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i],
87 synthnew->data[i],pv->win_s,pv->hop_s);
91 aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) {
92 aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
94 if (win_s < 2*hop_s) {
95 AUBIO_ERR("Hop size bigger than half the window size!\n");
96 AUBIO_ERR("Resetting hop size to half the window size.\n");
101 AUBIO_ERR("Hop size is smaller than 1!\n");
102 AUBIO_ERR("Resetting hop size to half the window size.\n");
106 pv->fft = new_aubio_mfft(win_s,channels);
109 pv->data = new_fvec (win_s, channels);
110 pv->synth = new_fvec (win_s, channels);
112 /* new input output */
113 pv->dataold = new_fvec (win_s-hop_s, channels);
114 pv->synthold = new_fvec (win_s-hop_s, channels);
115 pv->w = AUBIO_ARRAY(smpl_t,win_s);
116 aubio_window(pv->w,win_s,aubio_win_hanningz);
118 pv->channels = channels;
125 void del_aubio_pvoc(aubio_pvoc_t *pv) {
128 del_fvec(pv->dataold);
129 del_fvec(pv->synthold);
134 static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold,
135 const smpl_t * datanew, uint_t win_s, uint_t hop_s)
138 for (i=0;i<win_s-hop_s;i++)
139 data[i] = dataold[i];
140 for (i=0;i<hop_s;i++)
141 data[win_s-hop_s+i] = datanew[i];
142 for (i=0;i<win_s-hop_s;i++)
143 dataold[i] = data[i+hop_s];
146 static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold,
147 smpl_t * synthnew, uint_t win_s, uint_t hop_s)
150 smpl_t scale = 2*hop_s/(win_s+.0);
151 /* add new synth to old one and put result in synthnew */
152 for (i=0;i<hop_s;i++)
153 synthnew[i] = synthold[i]+synth[i]*scale;
155 for (i=0;i<win_s-2*hop_s;i++)
156 synthold[i] = synthold[i+hop_s];
157 /* erase last frame in synthold */
158 for (i=win_s-hop_s;i<win_s;i++)
159 synthold[i-hop_s]=0.;
161 for (i=0;i<win_s-hop_s;i++)
162 synthold[i] += synth[i+hop_s]*scale;