source: src/phasevoc.c @ e50b695

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

import 0.1.7.1

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[96fb8ad]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_fft_t * spectrum;
36        /**cur output grain             [win_s] */
37        fvec_t * synth;         
38        /**last input frame             [win_s-hop_s] */
39        fvec_t * synthold; 
40        /**current spectrum             [win_s] */
41        fft_data_t ** spec;
42        /**current input grain          [win_s] */
43        fvec_t * data;           
44        /**last input frame             [win_s-hop_s] */
45        fvec_t * dataold; 
46        /** grain window                [win_s] */
47        float * w;
48};
49
50
51/** memory allocation */
52static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels);
53/** object deletion */
54static void aubio_pvoc_free (aubio_pvoc_t *pv);
55/** returns data and dataold slided by hop_s */
56static void aubio_pvoc_swapbuffers(
57                smpl_t * data,
58                smpl_t * dataold,
59                const smpl_t * datanew,
60                uint_t win_s, uint_t hop_s);
61/** do additive synthesis from 'old' and 'cur' */
62static void aubio_pvoc_addsynth(
63                const smpl_t * synth,
64                smpl_t * synthold,
65                smpl_t * synthnew, 
66                uint_t win_s, uint_t hop_s);
67
68
69void aubio_pvoc_do(aubio_pvoc_t *pv, fvec_t * datanew, cvec_t *fftgrain) {
70        uint_t i,j;
71        for (i=0; i<pv->channels; i++) {
72                /* slide  */
73                aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i],
74                                datanew->data[i],pv->win_s,pv->hop_s);
75                /* windowing */
76                for (j=0; j<pv->win_s; j++) pv->data->data[i][j] *= pv->w[j];
77                /* fftshift */
78                vec_shift(pv->data);
79                /* calculate fft */
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);
84        }
85}
86
87void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
88        uint_t i,j;
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];
93                }
94                aubio_fft_rdo(pv->spectrum,pv->spec[i],pv->synth->data[i],pv->win_s);
95                vec_shift(pv->synth);
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);
99        }
100}
101
102void del_aubio_pvoc(aubio_pvoc_t *pv) {
103        aubio_pvoc_free(pv);
104}
105
106aubio_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);
109        return pv;
110}
111
112static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels) {
113        uint_t i;
114
115        aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
116
117        if (win_s < 2*hop_s) {
118                AUBIO_ERR("Window size is smaller than twice the hop size!\n");
119                return 0;
120        }
121
122        if (hop_s < 1) {
123                AUBIO_ERR("Hop size is smaller than 1!\n");
124                return 0;
125        }
126       
127        pv->spectrum = new_aubio_fft(win_s);
128
129        /* remember old */
130        pv->data     = new_fvec (win_s, channels);
131        pv->synth    = new_fvec (win_s, channels);
132
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);
137
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);
141
142        pv->channels = channels;
143        pv->hop_s    = hop_s;
144        pv->win_s    = win_s;
145
146        return pv;
147}
148
149static void aubio_pvoc_free (aubio_pvoc_t *pv) {
150        uint_t i;
151        del_aubio_fft(pv->spectrum);
152        del_fvec(pv->data);
153        del_fvec(pv->synth);
154        del_fvec(pv->dataold);
155        del_fvec(pv->synthold);
156        AUBIO_FREE(pv->w);
157        for (i=0; i< pv->channels; i++) {
158                AUBIO_FREE(pv->spec[i]);
159        }
160        AUBIO_FREE(pv->spec);
161        AUBIO_FREE(pv);
162}
163
164static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold, const smpl_t * datanew, 
165                uint_t win_s, uint_t hop_s)
166{
167        uint_t i;
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];
174}
175
176static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, smpl_t * synthnew, 
177                uint_t win_s, uint_t hop_s)
178{
179        uint_t i;
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;
184        /* shift synthold */
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.;
190        /* additive synth */
191        for (i=0;i<win_s-hop_s;i++)     
192                synthold[i] += synth[i+hop_s]*scale;
193}
194
Note: See TracBrowser for help on using the repository browser.