source: src/phasevoc.c @ 4f56a35

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since 4f56a35 was 4f56a35, checked in by Paul Brossier <piem@piem.org>, 13 years ago

phasevoc.c: do not window the signal again during resynthesis

  • Property mode set to 100644
File size: 4.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 "aubio_priv.h"
21#include "sample.h"
22#include "fft.h"
23#include "mathutils.h"
24#include "phasevoc.h"
25
26/** phasevocoder internal object */
27struct _aubio_pvoc_t {
28        /** grain length */
29        uint_t win_s;
30        /** overlap step */
31        uint_t hop_s;
32        /** number of channels */
33        uint_t channels;
34        /** spectral data */
35        aubio_mfft_t * fft;
36        /**cur output grain             [win_s] */
37        fvec_t * synth;         
38        /**last input frame             [win_s-hop_s] */
39        fvec_t * synthold; 
40        /**current input grain          [win_s] */
41        fvec_t * data;           
42        /**last input frame             [win_s-hop_s] */
43        fvec_t * dataold; 
44        /** grain window                [win_s] */
45        float * w;
46};
47
48
49/** returns data and dataold slided by hop_s */
50static void aubio_pvoc_swapbuffers(
51                smpl_t * data,
52                smpl_t * dataold,
53                const smpl_t * datanew,
54                uint_t win_s, uint_t hop_s);
55/** do additive synthesis from 'old' and 'cur' */
56static void aubio_pvoc_addsynth(
57                const smpl_t * synth,
58                smpl_t * synthold,
59                smpl_t * synthnew, 
60                uint_t win_s, uint_t hop_s);
61
62
63void aubio_pvoc_do(aubio_pvoc_t *pv, fvec_t * datanew, cvec_t *fftgrain) {
64        uint_t i,j;
65        for (i=0; i<pv->channels; i++) {
66                /* slide  */
67                aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i],
68                                datanew->data[i],pv->win_s,pv->hop_s);
69                /* windowing */
70                for (j=0; j<pv->win_s; j++) pv->data->data[i][j] *= pv->w[j];
71        }
72        /* shift */
73        vec_shift(pv->data);
74        /* calculate fft */
75        aubio_mfft_do (pv->fft,pv->data,fftgrain);
76}
77
78void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
79        uint_t i,j;
80        /* calculate rfft */
81        aubio_mfft_rdo(pv->fft,fftgrain,pv->synth);
82        /* unshift */
83        vec_shift(pv->synth);
84        for (i=0; i<pv->channels; i++) {
85                aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i],
86                                synthnew->data[i],pv->win_s,pv->hop_s);
87        }
88}
89
90aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) {
91        aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
92
93        if (win_s < 2*hop_s) {
94                AUBIO_ERR("Hop size bigger than half the window size!\n");
95                AUBIO_ERR("Resetting hop size to half the window size.\n");
96                hop_s = win_s / 2;
97        }
98
99        if (hop_s < 1) {
100                AUBIO_ERR("Hop size is smaller than 1!\n");
101                AUBIO_ERR("Resetting hop size to half the window size.\n");
102                hop_s = win_s / 2;
103        }
104       
105        pv->fft      = new_aubio_mfft(win_s,channels);
106
107        /* remember old */
108        pv->data     = new_fvec (win_s, channels);
109        pv->synth    = new_fvec (win_s, channels);
110
111        /* new input output */
112        pv->dataold  = new_fvec  (win_s-hop_s, channels);
113        pv->synthold = new_fvec (win_s-hop_s, channels);
114        pv->w        = AUBIO_ARRAY(smpl_t,win_s);
115        aubio_window(pv->w,win_s,aubio_win_hanningz);
116
117        pv->channels = channels;
118        pv->hop_s    = hop_s;
119        pv->win_s    = win_s;
120
121        return pv;
122}
123
124void del_aubio_pvoc(aubio_pvoc_t *pv) {
125        del_fvec(pv->data);
126        del_fvec(pv->synth);
127        del_fvec(pv->dataold);
128        del_fvec(pv->synthold);
129        del_aubio_mfft(pv->fft);
130        AUBIO_FREE(pv->w);
131        AUBIO_FREE(pv);
132}
133
134static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold, 
135                const smpl_t * datanew, uint_t win_s, uint_t hop_s)
136{
137        uint_t i;
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];
144}
145
146static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, 
147                smpl_t * synthnew, uint_t win_s, uint_t hop_s)
148{
149        uint_t i;
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;
154        /* shift synthold */
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.;
160        /* additive synth */
161        for (i=0;i<win_s-hop_s;i++)     
162                synthold[i] += synth[i+hop_s]*scale;
163}
164
Note: See TracBrowser for help on using the repository browser.