lbajardsilogic@223
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
lbajardsilogic@223
|
2
|
lbajardsilogic@223
|
3 /* Sound Access
|
lbajardsilogic@223
|
4 EASAIER client application.
|
lbajardsilogic@223
|
5 Silogic 2007. Laure Bajard.
|
lbajardsilogic@223
|
6
|
lbajardsilogic@223
|
7 Integration of the filter provided by:
|
lbajardsilogic@223
|
8 Dublin Institute of Technology - Audio Research Group 2007
|
lbajardsilogic@223
|
9 www.audioresearchgroup.com
|
lbajardsilogic@223
|
10 Author: Dan Barry
|
lbajardsilogic@223
|
11
|
lbajardsilogic@223
|
12 This program is free software; you can redistribute it and/or
|
lbajardsilogic@223
|
13 modify it under the terms of the GNU General Public License as
|
lbajardsilogic@223
|
14 published by the Free Software Foundation; either version 2 of the
|
lbajardsilogic@223
|
15 License, or (at your option) any later version. See the file
|
lbajardsilogic@223
|
16 COPYING included with this distribution for more information.
|
lbajardsilogic@223
|
17 */
|
lbajardsilogic@223
|
18
|
lbajardsilogic@223
|
19 #include <math.h>
|
lbajardsilogic@223
|
20 #include <iostream>
|
lbajardsilogic@223
|
21
|
lbajardsilogic@223
|
22 #include "MultiRealTimeFilter.h"
|
lbajardsilogic@223
|
23
|
lbajardsilogic@223
|
24 #include "FFTReal.h"
|
lbajardsilogic@223
|
25 #include "DSP.h"
|
lbajardsilogic@223
|
26
|
lbajardsilogic@223
|
27 #include "system/System.h"
|
lbajardsilogic@223
|
28 #include "main/MainWindow.h"
|
lbajardsilogic@223
|
29
|
lbajardsilogic@229
|
30 // DAN added
|
lbajardsilogic@229
|
31 float *L_mags; ///CURRENT FRAME MAGNITUDES
|
lbajardsilogic@229
|
32 float *R_mags; ///CURRENT FRAME MAGNITUDES
|
lbajardsilogic@229
|
33 float *pL_mags; ///PREVIOUS FRAME MAGNITUDES
|
lbajardsilogic@229
|
34 float *pR_mags; ///PREVIOUS FRAME MAGNITUDES
|
lbajardsilogic@229
|
35
|
benoitrigolleau@278
|
36 float *plotarray; ///STORES HISTOGRAM PLOT FOR SEPARATOR
|
benoitrigolleau@278
|
37 float *grapharray; ///HIGHER RESOLUTION VERSION OF ABOVE FOR SCREEN PLOTTING
|
benoitrigolleau@278
|
38
|
lbajardsilogic@229
|
39 float *L_FFTframe; //Left FFT Frame
|
lbajardsilogic@229
|
40 float *R_FFTframe; //Right FFT Frame
|
lbajardsilogic@229
|
41
|
lbajardsilogic@223
|
42 extern float hopfactor;
|
lbajardsilogic@223
|
43
|
lbajardsilogic@223
|
44 //need in DSP.cpp
|
lbajardsilogic@223
|
45 float lastfactor;
|
lbajardsilogic@223
|
46
|
lbajardsilogic@223
|
47 int numpeaks;
|
lbajardsilogic@223
|
48 float *peak_locations;
|
lbajardsilogic@223
|
49 int currentposition;
|
lbajardsilogic@223
|
50 //
|
lbajardsilogic@223
|
51
|
lbajardsilogic@223
|
52 MultiRealTimeFilter::MultiRealTimeFilter() : Filter(),
|
lbajardsilogic@223
|
53 m_framesize(4096),
|
lbajardsilogic@223
|
54 m_transhold(0)
|
lbajardsilogic@223
|
55 {
|
lbajardsilogic@223
|
56 m_hop = m_framesize/4;
|
lbajardsilogic@223
|
57
|
lbajardsilogic@223
|
58 currentposition = m_hop;
|
lbajardsilogic@223
|
59
|
lbajardsilogic@232
|
60 m_mutex = new QMutex;
|
lbajardsilogic@232
|
61
|
lbajardsilogic@223
|
62 m_timeStretchFilter = new TimeStretchFilter();
|
lbajardsilogic@232
|
63 m_equalizerFilter = new EqualizerFilter(m_framesize, m_mutex);
|
lbajardsilogic@223
|
64
|
benoitrigolleau@278
|
65
|
lbajardsilogic@223
|
66 m_filterCollection.push_back(m_timeStretchFilter);
|
lbajardsilogic@223
|
67 m_filterCollection.push_back(m_equalizerFilter);
|
lbajardsilogic@223
|
68
|
lbajardsilogic@223
|
69 connect(m_timeStretchFilter, SIGNAL(filterEnabled(bool)), this, SLOT(setFilterEnabled(bool)));
|
lbajardsilogic@223
|
70 connect(m_equalizerFilter, SIGNAL(filterEnabled(bool)), this, SLOT(setFilterEnabled(bool)));
|
lbajardsilogic@223
|
71
|
lbajardsilogic@229
|
72 m_inputBufferL = (float *)calloc(m_framesize*(m_timeStretchFilter->getMaxPitchFactor()+1), sizeof(float));
|
lbajardsilogic@229
|
73 m_inputBufferR = (float *)calloc(m_framesize*(m_timeStretchFilter->getMaxPitchFactor()+1), sizeof(float));
|
lbajardsilogic@229
|
74 /**********malloc***********/
|
lbajardsilogic@223
|
75
|
lbajardsilogic@229
|
76
|
lbajardsilogic@229
|
77 //This block specifically sets up the buffers required to do a 75% overlap scheme
|
lbajardsilogic@229
|
78 window=(float *)calloc((m_framesize), sizeof(float)); //Window
|
lbajardsilogic@229
|
79
|
lbajardsilogic@229
|
80 L_FFTframe=(float *)calloc((m_framesize), sizeof(float));
|
lbajardsilogic@229
|
81 R_FFTframe=(float *)calloc((m_framesize), sizeof(float));
|
lbajardsilogic@229
|
82
|
lbajardsilogic@229
|
83 L_audioframe=(float *)calloc((m_framesize), sizeof(float)); //The current frame
|
lbajardsilogic@229
|
84 R_audioframe=(float *)calloc((m_framesize), sizeof(float));
|
lbajardsilogic@229
|
85 pL_audioframe=(float *)calloc((m_framesize), sizeof(float)); //
|
lbajardsilogic@229
|
86 pR_audioframe=(float *)calloc((m_framesize), sizeof(float));
|
lbajardsilogic@229
|
87 L_processedframe=(float *)calloc((m_framesize), sizeof(float)); //The current frame
|
lbajardsilogic@229
|
88 R_processedframe=(float *)calloc((m_framesize), sizeof(float));
|
lbajardsilogic@229
|
89
|
lbajardsilogic@229
|
90 L_outbuffer=(float *)calloc((m_framesize/4), sizeof(float)); //The current output segment which is 1/4 framesize for 75% overlap
|
lbajardsilogic@229
|
91 L_holdbuffer3=(float *)calloc((m_framesize*0.75), sizeof(float)); //The hold buffer for the previous frame segment
|
lbajardsilogic@229
|
92 L_holdbuffer2=(float *)calloc((m_framesize/2), sizeof(float)); //The fold buffer for the frame segment 2 frames ago
|
lbajardsilogic@229
|
93 L_holdbuffer1=(float *)calloc((m_framesize/4), sizeof(float)); //The fold buffer for the frame segment 3 frames ago
|
lbajardsilogic@223
|
94
|
lbajardsilogic@229
|
95 R_outbuffer=(float *)calloc((m_framesize/4), sizeof(float)); //The current output segment which is 1/4 framesize for 75% overlap
|
lbajardsilogic@229
|
96 R_holdbuffer3=(float *)calloc((m_framesize*0.75), sizeof(float)); //The hold buffer for the previous frame segment
|
lbajardsilogic@229
|
97 R_holdbuffer2=(float *)calloc((m_framesize/2), sizeof(float)); //The fold buffer for the frame segment 2 frames ago
|
lbajardsilogic@229
|
98 R_holdbuffer1=(float *)calloc((m_framesize/4), sizeof(float));
|
lbajardsilogic@229
|
99
|
lbajardsilogic@229
|
100 L_mags=(float *)calloc((m_framesize/2), sizeof(float)); //The magnitude and phase arrays
|
lbajardsilogic@229
|
101 R_mags=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
102 L_phase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
103 R_phase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
104 pL_mags=(float *)calloc((m_framesize/2), sizeof(float)); //The magnitude and phase arrays
|
lbajardsilogic@229
|
105 pR_mags=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
106 pL_phase=(float *)calloc((m_framesize/2), sizeof(float)); //The magnitude and phase arrays
|
lbajardsilogic@229
|
107 pR_phase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
108 cL_synthphase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
109 cR_synthphase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
110 pL_synthphase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
111 pR_synthphase=(float *)calloc((m_framesize/2), sizeof(float));
|
lbajardsilogic@229
|
112
|
lbajardsilogic@223
|
113 peak_locations=(float *)calloc((m_framesize/2), sizeof(float));
|
benoitrigolleau@278
|
114
|
benoitrigolleau@278
|
115 plotarray=(float *)calloc((200), sizeof(float));
|
benoitrigolleau@278
|
116 grapharray=(float *)calloc((400), sizeof(float));
|
lbajardsilogic@223
|
117
|
lbajardsilogic@223
|
118 hanning(window, m_framesize);
|
lbajardsilogic@223
|
119
|
lbajardsilogic@223
|
120 connect(this, SIGNAL(playSpeedChanged(float)),
|
lbajardsilogic@223
|
121 MainWindow::instance(), SLOT(playSpeedChanged(float)));
|
lbajardsilogic@223
|
122
|
lbajardsilogic@223
|
123 hopfactor = 1;
|
lbajardsilogic@223
|
124 /***************************/
|
lbajardsilogic@223
|
125 }
|
lbajardsilogic@223
|
126
|
lbajardsilogic@223
|
127 MultiRealTimeFilter::~MultiRealTimeFilter()
|
lbajardsilogic@223
|
128 {
|
lbajardsilogic@223
|
129 /**********de-alloc***********/
|
lbajardsilogic@229
|
130 delete m_inputBufferL;
|
lbajardsilogic@229
|
131 delete m_inputBufferR;
|
lbajardsilogic@229
|
132 delete L_mags; ///CURRENT FRAME MAGNITUDES
|
lbajardsilogic@229
|
133 delete R_mags; ///CURRENT FRAME MAGNITUDES
|
lbajardsilogic@229
|
134 delete pL_mags; ///PREVIOUS FRAME MAGNITUDES
|
lbajardsilogic@229
|
135 delete pR_mags; ///PREVIOUS FRAME MAGNITUDES
|
lbajardsilogic@229
|
136
|
lbajardsilogic@229
|
137 delete L_FFTframe; //Left FFT Frame
|
lbajardsilogic@229
|
138 delete R_FFTframe;
|
lbajardsilogic@229
|
139
|
lbajardsilogic@229
|
140
|
lbajardsilogic@229
|
141 //delete FFTframe;
|
lbajardsilogic@223
|
142
|
lbajardsilogic@229
|
143 delete L_audioframe; //
|
lbajardsilogic@229
|
144 delete R_audioframe; //
|
lbajardsilogic@229
|
145 delete pL_audioframe; //
|
lbajardsilogic@229
|
146 delete pR_audioframe; //
|
lbajardsilogic@229
|
147 delete L_processedframe; //
|
lbajardsilogic@229
|
148 delete R_processedframe;
|
lbajardsilogic@229
|
149
|
lbajardsilogic@229
|
150 delete window;
|
lbajardsilogic@229
|
151
|
lbajardsilogic@229
|
152 delete L_outbuffer;
|
lbajardsilogic@229
|
153 delete L_holdbuffer3;
|
lbajardsilogic@229
|
154 delete L_holdbuffer2;
|
lbajardsilogic@229
|
155 delete L_holdbuffer1;
|
lbajardsilogic@229
|
156 delete R_outbuffer;
|
lbajardsilogic@229
|
157 delete R_holdbuffer3;
|
lbajardsilogic@229
|
158 delete R_holdbuffer2;
|
lbajardsilogic@229
|
159 delete R_holdbuffer1;
|
lbajardsilogic@229
|
160
|
lbajardsilogic@229
|
161 delete L_phase;
|
lbajardsilogic@229
|
162 delete R_phase;
|
lbajardsilogic@229
|
163 delete pL_phase;
|
lbajardsilogic@229
|
164 delete pR_phase;
|
lbajardsilogic@229
|
165 delete cL_synthphase;
|
lbajardsilogic@229
|
166 delete cR_synthphase;
|
lbajardsilogic@229
|
167 delete pL_synthphase;
|
lbajardsilogic@229
|
168 delete pR_synthphase;
|
lbajardsilogic@223
|
169
|
lbajardsilogic@223
|
170 delete peak_locations;
|
lbajardsilogic@223
|
171
|
lbajardsilogic@223
|
172 hopfactor = 1;
|
lbajardsilogic@223
|
173
|
lbajardsilogic@223
|
174 emit playSpeedChanged(1);
|
lbajardsilogic@223
|
175
|
lbajardsilogic@232
|
176 delete m_mutex;
|
lbajardsilogic@241
|
177 m_mutex = 0;
|
lbajardsilogic@223
|
178 /***************************/
|
lbajardsilogic@223
|
179 }
|
lbajardsilogic@223
|
180
|
lbajardsilogic@223
|
181 void MultiRealTimeFilter::putInput(float **input, size_t samples)
|
lbajardsilogic@223
|
182 {
|
lbajardsilogic@223
|
183 int dd;
|
lbajardsilogic@223
|
184 float sampdiff;
|
lbajardsilogic@223
|
185 float difratio;
|
lbajardsilogic@223
|
186 float interpsample;
|
lbajardsilogic@223
|
187
|
lbajardsilogic@223
|
188 bool drum = 0;
|
lbajardsilogic@223
|
189 float drumthresh = 65;
|
lbajardsilogic@223
|
190
|
lbajardsilogic@223
|
191 int delta = m_hop; //the "current position" is shifted of m_hop
|
lbajardsilogic@223
|
192
|
lbajardsilogic@223
|
193 if ( samples < ( (size_t) floor(m_framesize*(m_timeStretchFilter->getPitchFactor() + 1)) ) )
|
lbajardsilogic@223
|
194 return;
|
lbajardsilogic@223
|
195
|
lbajardsilogic@223
|
196 int channel = getSourceChannelCount();
|
lbajardsilogic@223
|
197
|
lbajardsilogic@229
|
198
|
lbajardsilogic@229
|
199
|
lbajardsilogic@223
|
200 for (int i=0; i< ((int) samples); i++){
|
lbajardsilogic@223
|
201 if (channel > 1)
|
lbajardsilogic@229
|
202 {
|
lbajardsilogic@229
|
203 m_inputBufferL[i] = input[0][i]; //real-time biffer taken from left ring buffer
|
lbajardsilogic@229
|
204 m_inputBufferR[i] = input[1][i]; //real-time biffer taken from right ring buffer
|
lbajardsilogic@229
|
205 } else {
|
lbajardsilogic@229
|
206 m_inputBufferL[i] = input[0][i]; //If file is mono we copy same channel into both buffers into both buffers
|
lbajardsilogic@229
|
207 m_inputBufferR[i] = input[0][i];
|
lbajardsilogic@229
|
208 }
|
lbajardsilogic@223
|
209 }
|
lbajardsilogic@223
|
210
|
lbajardsilogic@229
|
211
|
lbajardsilogic@229
|
212
|
lbajardsilogic@223
|
213 for (int i = 0; i< ((int) m_framesize); i++)
|
lbajardsilogic@223
|
214 {
|
lbajardsilogic@223
|
215
|
lbajardsilogic@223
|
216 //This block was specifically written to do resampling interpolation for crude pitch shifting
|
lbajardsilogic@223
|
217 //if it's not being used the audioframe line after the else should be used which is also used in bypass mode
|
lbajardsilogic@223
|
218 //At
|
lbajardsilogic@223
|
219
|
lbajardsilogic@229
|
220 if (m_timeStretchFilter->bypass() == false)
|
lbajardsilogic@229
|
221 {
|
lbajardsilogic@223
|
222 dd = floor(double(i*m_timeStretchFilter->getPitchFactor()));
|
lbajardsilogic@223
|
223 difratio = (double(i*m_timeStretchFilter->getPitchFactor())) - floor(double(i*m_timeStretchFilter->getPitchFactor()));
|
lbajardsilogic@223
|
224
|
lbajardsilogic@223
|
225 // this block loads a frame as normal
|
lbajardsilogic@229
|
226 sampdiff=m_inputBufferL[dd+delta+1]-m_inputBufferL[dd+delta];
|
lbajardsilogic@229
|
227 interpsample = (difratio*sampdiff)+m_inputBufferL[dd+delta];
|
lbajardsilogic@229
|
228 L_audioframe[i] = interpsample*window[i];
|
lbajardsilogic@223
|
229
|
lbajardsilogic@229
|
230 sampdiff=m_inputBufferL[dd+delta+1-m_hop]-m_inputBufferL[dd+delta-m_hop];
|
lbajardsilogic@229
|
231 interpsample = (difratio*sampdiff)+m_inputBufferL[dd+delta-m_hop];
|
lbajardsilogic@229
|
232 pL_audioframe[i] = interpsample*window[i];
|
lbajardsilogic@229
|
233
|
lbajardsilogic@229
|
234
|
lbajardsilogic@229
|
235 sampdiff=m_inputBufferR[dd+delta+1]-m_inputBufferR[dd+delta];
|
lbajardsilogic@229
|
236 interpsample = (difratio*sampdiff)+m_inputBufferR[dd+delta];
|
lbajardsilogic@229
|
237 R_audioframe[i] = interpsample*window[i];
|
lbajardsilogic@229
|
238
|
lbajardsilogic@229
|
239 sampdiff=m_inputBufferR[dd+delta+1-m_hop]-m_inputBufferR[dd+delta-m_hop];
|
lbajardsilogic@229
|
240 interpsample = (difratio*sampdiff)+m_inputBufferR[dd+delta-m_hop];
|
lbajardsilogic@229
|
241 pR_audioframe[i] = interpsample*window[i];
|
lbajardsilogic@229
|
242
|
lbajardsilogic@223
|
243 }
|
lbajardsilogic@223
|
244 else {
|
lbajardsilogic@229
|
245 L_audioframe[i] = m_inputBufferL[i+delta+1]*window[i];
|
lbajardsilogic@229
|
246 R_audioframe[i] = m_inputBufferR[i+delta+1]*window[i];
|
lbajardsilogic@229
|
247
|
lbajardsilogic@229
|
248 L_processedframe[i] = L_audioframe[i]*window[i];
|
lbajardsilogic@229
|
249 R_processedframe[i] = R_audioframe[i]*window[i];
|
lbajardsilogic@223
|
250 }
|
lbajardsilogic@223
|
251 }
|
lbajardsilogic@223
|
252
|
lbajardsilogic@223
|
253 FFTReal fft_object(m_framesize);
|
lbajardsilogic@223
|
254
|
lbajardsilogic@230
|
255 //if (m_timeStretchFilter->bypass() == false)//DAN This bypass would stop all processing...need to replace this with a master bypass instead of just timestretch bypass
|
lbajardsilogic@230
|
256 if (filterEnabled)
|
lbajardsilogic@223
|
257 {
|
lbajardsilogic@229
|
258
|
lbajardsilogic@229
|
259 //CURRENT FRAME LEFT AND RIGHT TIME 2 FREQUENCY ***** THIS IS REQUIRED BY ALL PROCESSES
|
lbajardsilogic@229
|
260 fft_object.do_fft(L_FFTframe,L_audioframe);
|
lbajardsilogic@229
|
261 fft_object.do_fft(R_FFTframe,R_audioframe);
|
lbajardsilogic@223
|
262
|
lbajardsilogic@229
|
263 cart2pol(L_FFTframe, L_mags, L_phase, m_framesize);
|
lbajardsilogic@229
|
264 cart2pol(R_FFTframe, R_mags, R_phase, m_framesize);
|
lbajardsilogic@223
|
265
|
lbajardsilogic@230
|
266
|
lbajardsilogic@229
|
267 //CURRENT FRAME LEFT AND RIGHT TIME 2 FREQUENCY ***** THIS IS REQUIRED BY ALL PROCESSES
|
lbajardsilogic@229
|
268 fft_object.do_fft (L_FFTframe,pL_audioframe);
|
lbajardsilogic@229
|
269 fft_object.do_fft (R_FFTframe,pR_audioframe);
|
lbajardsilogic@229
|
270
|
lbajardsilogic@229
|
271 cart2pol(L_FFTframe, pL_mags, pL_phase, m_framesize);
|
lbajardsilogic@229
|
272 cart2pol(R_FFTframe, pR_mags, pR_phase, m_framesize);
|
lbajardsilogic@229
|
273
|
lbajardsilogic@223
|
274 //--------------------------------------------
|
lbajardsilogic@229
|
275
|
benoitrigolleau@278
|
276
|
benoitrigolleau@278
|
277
|
lbajardsilogic@229
|
278
|
lbajardsilogic@229
|
279 //EQUALISER CALLS -
|
lbajardsilogic@229
|
280 //Will need a bypass " m_equalizerFilter->bypass()" as below
|
lbajardsilogic@229
|
281 //Will need a simplemode " m_equalizerFilter->simplemode_bypass() " to switch between draw and slider control
|
lbajardsilogic@229
|
282 if (m_equalizerFilter->bypass() == false)
|
lbajardsilogic@229
|
283 {
|
lbajardsilogic@232
|
284
|
lbajardsilogic@232
|
285 m_mutex->lock();
|
lbajardsilogic@232
|
286 if (m_equalizerFilter->simpleMode())
|
lbajardsilogic@229
|
287 {
|
lbajardsilogic@232
|
288 //m_equalizerFilter->create_filterbands();
|
lbajardsilogic@232
|
289 bandeq(L_mags, R_mags, m_equalizerFilter->curve(), m_framesize); //Gainband 1 - 5 values from EQ sliders
|
lbajardsilogic@232
|
290 //log10plot2(bandcurve,plotbandcurve, m_framesize, 400); //Converts linear band curve to log band curve only for plot
|
lbajardsilogic@229
|
291 }
|
lbajardsilogic@229
|
292 else
|
lbajardsilogic@232
|
293 {
|
lbajardsilogic@229
|
294 applyEQ(L_mags, R_mags, m_framesize, m_equalizerFilter->curve().size(), m_equalizerFilter->curve()); //Takes "eqcurve" which is what user draws in advanced mode
|
lbajardsilogic@232
|
295 }
|
lbajardsilogic@223
|
296
|
lbajardsilogic@229
|
297 m_equalizerFilter->emitPlotFFTArray(L_mags, m_framesize);
|
lbajardsilogic@232
|
298 m_mutex->unlock();
|
lbajardsilogic@229
|
299 }
|
lbajardsilogic@229
|
300
|
lbajardsilogic@229
|
301 if (m_timeStretchFilter->bypass() == false)
|
lbajardsilogic@223
|
302 {
|
lbajardsilogic@229
|
303 //TRANSIENT DETECTION FOR TIME STRETCHER
|
lbajardsilogic@229
|
304 drum=transient_detect(L_mags, R_mags, pL_mags, pR_mags, drumthresh, m_framesize);
|
lbajardsilogic@229
|
305
|
lbajardsilogic@229
|
306 if (m_timeStretchFilter->transcheck())
|
lbajardsilogic@229
|
307 {
|
lbajardsilogic@229
|
308
|
lbajardsilogic@229
|
309 if (drum && m_transhold==0){
|
lbajardsilogic@229
|
310 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
311 cur2last(L_phase, cL_synthphase, pL_synthphase, m_framesize);
|
lbajardsilogic@229
|
312 cur2last(R_phase, cR_synthphase, pR_synthphase, m_framesize);
|
lbajardsilogic@229
|
313
|
lbajardsilogic@229
|
314 m_transhold=4;
|
lbajardsilogic@223
|
315 }
|
lbajardsilogic@223
|
316 else{
|
lbajardsilogic@229
|
317 if(m_timeStretchFilter->peakcheck()){
|
lbajardsilogic@229
|
318 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
319 rotatephases_peaklocked(L_phase, pL_phase, cL_synthphase, pL_synthphase, L_mags, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
320 rotatephases_peaklocked(R_phase, pR_phase, cR_synthphase, pR_synthphase, R_mags, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
321
|
lbajardsilogic@229
|
322 }
|
lbajardsilogic@229
|
323 else{
|
lbajardsilogic@229
|
324 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
325 rotatephases(L_phase, pL_phase, cL_synthphase, pL_synthphase, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
326 rotatephases(R_phase, pR_phase, cR_synthphase, pR_synthphase, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
327
|
lbajardsilogic@229
|
328 }
|
lbajardsilogic@223
|
329 }
|
lbajardsilogic@223
|
330 }
|
lbajardsilogic@229
|
331 else
|
lbajardsilogic@229
|
332 {
|
lbajardsilogic@229
|
333 if(m_timeStretchFilter->peakcheck()){
|
lbajardsilogic@229
|
334 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
335 rotatephases_peaklocked(L_phase, pL_phase, cL_synthphase, pL_synthphase, L_mags, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
336 rotatephases_peaklocked(R_phase, pR_phase, cR_synthphase, pR_synthphase, R_mags, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
337
|
lbajardsilogic@229
|
338 }
|
lbajardsilogic@229
|
339 else{
|
lbajardsilogic@229
|
340 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
341 rotatephases(L_phase, pL_phase, cL_synthphase, pL_synthphase, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
342 rotatephases(R_phase, pR_phase, cR_synthphase, pR_synthphase, m_framesize, m_timeStretchFilter->getPitchFactor());
|
lbajardsilogic@229
|
343 }
|
lbajardsilogic@223
|
344 }
|
lbajardsilogic@229
|
345
|
lbajardsilogic@229
|
346 // FOR TIME STRETCHER
|
lbajardsilogic@229
|
347 if(m_transhold != 0){
|
lbajardsilogic@229
|
348 m_transhold = m_transhold - 1;
|
lbajardsilogic@223
|
349 }
|
lbajardsilogic@230
|
350
|
lbajardsilogic@230
|
351 drum = 0;
|
lbajardsilogic@230
|
352
|
lbajardsilogic@230
|
353 pol2cart(L_FFTframe, L_mags, cL_synthphase, m_framesize);
|
lbajardsilogic@230
|
354 pol2cart(R_FFTframe, R_mags, cR_synthphase, m_framesize);
|
lbajardsilogic@230
|
355
|
lbajardsilogic@230
|
356 } else
|
lbajardsilogic@230
|
357 {
|
lbajardsilogic@230
|
358 pol2cart(L_FFTframe, L_mags, L_phase, m_framesize);
|
lbajardsilogic@230
|
359 pol2cart(R_FFTframe, R_mags, R_phase, m_framesize);
|
lbajardsilogic@223
|
360 }
|
lbajardsilogic@229
|
361
|
lbajardsilogic@230
|
362 fft_object.do_ifft (L_FFTframe,L_processedframe);
|
lbajardsilogic@230
|
363 fft_object.do_ifft (R_FFTframe,R_processedframe);
|
lbajardsilogic@229
|
364
|
lbajardsilogic@230
|
365 fft_object.rescale (L_processedframe);
|
lbajardsilogic@230
|
366 fft_object.rescale (R_processedframe);
|
lbajardsilogic@230
|
367
|
lbajardsilogic@230
|
368 }
|
lbajardsilogic@223
|
369
|
lbajardsilogic@223
|
370 for (int p = 0; p < ((int) m_framesize); p++){
|
lbajardsilogic@229
|
371 L_processedframe[p]=L_processedframe[p]*window[p];
|
lbajardsilogic@229
|
372 R_processedframe[p]=R_processedframe[p]*window[p];
|
lbajardsilogic@223
|
373 }
|
lbajardsilogic@223
|
374
|
lbajardsilogic@223
|
375 for (int j = 0; j< ((int) m_framesize); j++)
|
lbajardsilogic@223
|
376 {
|
lbajardsilogic@229
|
377 //This block deals with the buffers for a 75% overlap scheme AND IS NOW STEREO
|
lbajardsilogic@223
|
378 if (j < ((int) m_framesize)/4){
|
lbajardsilogic@229
|
379 L_outbuffer[j]=(L_processedframe[j]+L_holdbuffer1[j]+L_holdbuffer2[j]+L_holdbuffer3[j])*0.5;
|
lbajardsilogic@229
|
380 L_holdbuffer1[j]=L_holdbuffer2[j+(m_framesize/4)];
|
lbajardsilogic@229
|
381
|
lbajardsilogic@229
|
382 R_outbuffer[j]=(R_processedframe[j]+R_holdbuffer1[j]+R_holdbuffer2[j]+R_holdbuffer3[j])*0.5;
|
lbajardsilogic@229
|
383 R_holdbuffer1[j]=R_holdbuffer2[j+(m_framesize/4)];
|
lbajardsilogic@223
|
384 }
|
lbajardsilogic@223
|
385
|
lbajardsilogic@223
|
386 if (j < ((int) m_framesize)/2){
|
lbajardsilogic@229
|
387 L_holdbuffer2[j]=L_holdbuffer3[j+(m_framesize/4)];
|
lbajardsilogic@229
|
388 R_holdbuffer2[j]=R_holdbuffer3[j+(m_framesize/4)];
|
lbajardsilogic@223
|
389 }
|
lbajardsilogic@223
|
390
|
lbajardsilogic@223
|
391 if (j < ((int) m_framesize)*0.75){
|
lbajardsilogic@229
|
392 L_holdbuffer3[j]=L_processedframe[j+(m_framesize/4)];
|
lbajardsilogic@229
|
393 R_holdbuffer3[j]=R_processedframe[j+(m_framesize/4)];
|
lbajardsilogic@223
|
394 }
|
lbajardsilogic@229
|
395
|
lbajardsilogic@229
|
396
|
lbajardsilogic@223
|
397 }
|
lbajardsilogic@223
|
398 }
|
lbajardsilogic@223
|
399
|
lbajardsilogic@223
|
400 void MultiRealTimeFilter::getOutput(float **output, size_t samples)
|
lbajardsilogic@223
|
401 {
|
lbajardsilogic@223
|
402 if (samples > m_framesize/4)
|
lbajardsilogic@223
|
403 return;
|
lbajardsilogic@223
|
404
|
lbajardsilogic@223
|
405 int channel = getSourceChannelCount();
|
lbajardsilogic@223
|
406
|
lbajardsilogic@229
|
407 for (size_t i = 0; i < samples; ++i) // Now that there are 2 out buffers, the output is filled according to channel count
|
lbajardsilogic@229
|
408 {
|
lbajardsilogic@229
|
409
|
lbajardsilogic@229
|
410 output[0][i] = L_outbuffer[i];
|
lbajardsilogic@229
|
411
|
lbajardsilogic@229
|
412 if (channel > 1)
|
lbajardsilogic@229
|
413 {
|
lbajardsilogic@229
|
414 output[1][i] = R_outbuffer[i];
|
lbajardsilogic@229
|
415 }
|
lbajardsilogic@229
|
416 }
|
lbajardsilogic@223
|
417 }
|
lbajardsilogic@223
|
418
|
lbajardsilogic@223
|
419 size_t MultiRealTimeFilter::getRequiredInputSamples(size_t outputSamplesNeeded)
|
lbajardsilogic@223
|
420 {
|
lbajardsilogic@223
|
421 size_t need = (size_t) (floor(m_framesize*(m_timeStretchFilter->getPitchFactor() + 1)));
|
lbajardsilogic@223
|
422 return need;
|
lbajardsilogic@223
|
423 }
|
lbajardsilogic@223
|
424
|
lbajardsilogic@223
|
425 size_t MultiRealTimeFilter::getRequiredSkipSamples()
|
lbajardsilogic@223
|
426 {
|
lbajardsilogic@223
|
427 size_t skip = 1024;
|
lbajardsilogic@223
|
428
|
lbajardsilogic@223
|
429 if (m_timeStretchFilter->bypass() == false && m_transhold==0)
|
lbajardsilogic@223
|
430 {
|
lbajardsilogic@223
|
431 skip = floor(m_hop*hopfactor);
|
lbajardsilogic@223
|
432 currentposition += floor(m_hop*hopfactor);
|
lbajardsilogic@223
|
433 }
|
lbajardsilogic@223
|
434 else
|
lbajardsilogic@223
|
435 {
|
lbajardsilogic@223
|
436 skip = m_hop;
|
lbajardsilogic@223
|
437 currentposition += m_hop;
|
benoitrigolleau@278
|
438
|
lbajardsilogic@223
|
439 }
|
benoitrigolleau@278
|
440
|
benoitrigolleau@278
|
441 if (m_timeStretchFilter->bypass() == false && m_timeStretchFilter->isFreezed() == true)
|
benoitrigolleau@278
|
442 {
|
benoitrigolleau@278
|
443 skip = 0;
|
benoitrigolleau@278
|
444 currentposition += 0;
|
benoitrigolleau@278
|
445 }
|
benoitrigolleau@278
|
446
|
lbajardsilogic@223
|
447 return skip;
|
lbajardsilogic@223
|
448 }
|
lbajardsilogic@223
|
449
|
lbajardsilogic@223
|
450 void MultiRealTimeFilter::setFilterEnabled(bool b)
|
lbajardsilogic@223
|
451 {
|
lbajardsilogic@223
|
452 filterEnabled = (m_timeStretchFilter->isEnabled() || m_equalizerFilter->isEnabled());
|
lbajardsilogic@223
|
453 }
|
lbajardsilogic@223
|
454
|
lbajardsilogic@223
|
455 void MultiRealTimeFilter::setFilterEnabled(int b)
|
lbajardsilogic@223
|
456 {
|
lbajardsilogic@223
|
457 filterEnabled = (m_timeStretchFilter->isEnabled() || m_equalizerFilter->isEnabled());
|
lbajardsilogic@223
|
458 }
|
lbajardsilogic@223
|
459
|
lbajardsilogic@223
|
460
|