1 // Copyright 2004-07 "Gilles Degottex"
3 // This file is part of "Music"
5 // "Music" is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
10 // "Music" is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "FreqAnalysis.h"
27 #include <CppAddons/Fit.h>
31 double PeakRefinementLogParabola(const vector<std::complex<double> > spectrum, int peak_index)
33 assert(peak_index>0 && peak_index<int(spectrum.size()-1));
35 if(!(is_peak(spectrum, peak_index)))
37 if(peak_index+1<int(spectrum.size()-1) && is_peak(spectrum, peak_index+1))
39 else if(peak_index-1>0 && is_peak(spectrum, peak_index-1))
43 double a,b,c,xapex,yapex;
44 FitParabola(peak_index-1, log(mod(spectrum[peak_index-1])+numeric_limits<double>::min()),
45 peak_index, log(mod(spectrum[peak_index])+numeric_limits<double>::min()),
46 peak_index+1, log(mod(spectrum[peak_index+1])+numeric_limits<double>::min()),
47 a, b, c, xapex, yapex);
53 * M. Abe and J. O. Smith III
54 * “Design Criteria for Simple Sinusoidal Parameter Estimation based on Quadratic
55 * Interpolation of FFT Magnitude Peaks AM/FM Rate Estimation and Bias Correction
56 * for Time-Varying Sinusoidal Modeling,”
57 * Convention Paper Audio Engineering Society,
58 * Dept. of Music, Stanford University, August, (2004).
60 double PeakRefinementLogParabolaUnbiased(const vector<std::complex<double> > spectrum, int peak_index, double zp)
62 double f = PeakRefinementLogParabola(spectrum, peak_index);
64 double df = f - peak_index;
66 double c0 = 0.247560; // hann coefs
69 double xi_zp = c0/(zp*zp) + c1/(zp*zp*zp*zp);
70 double df2 = xi_zp*(df-0.5)*(df+0.5)*df;
72 // double c2 = −0.090608;
73 // double c3 = −0.055781;
74 // double nu_zp = c2/(zp*zp*zp*zp) + c3/(zp*zp*zp*zp*zp*zp);
75 // double da = nu_zp*df*df;
80 vector<Harmonic> GetHarmonicStruct(const vector<complex<double> >& spectrum, double approx_f0, int nb_harm, double used_zp, double offset_tresh)
82 double approx_f0_rel = approx_f0*spectrum.size()/double(GetSamplingRate());
83 assert(approx_f0_rel>1 && approx_f0_rel<=spectrum.size()/2-1);
85 vector<Harmonic> harms;
87 for(int h=1; h<=nb_harm && int(h*approx_f0_rel)<int(spectrum.size()/2)-1; h++)
89 int c = int(h*approx_f0_rel);
90 int llimit = int((h-offset_tresh)*approx_f0_rel);
91 llimit = max(llimit, 1);
92 int rlimit = int((h+offset_tresh)*approx_f0_rel);
93 rlimit = min(rlimit, int(spectrum.size()/2)-1);
96 if(is_peak(spectrum, c))
101 bool cl_is_peak = false;
102 while(!cl_is_peak && cl-1>llimit)
103 cl_is_peak = is_peak(spectrum, --cl);
106 bool cr_is_peak = false;
107 while(!cr_is_peak && cr+1<rlimit)
108 cr_is_peak = is_peak(spectrum, ++cr);
113 peak_index = (c-cl<cr-c)?cl:cr;
124 harm.mod = mod(spectrum[peak_index]);
125 harm.freq = PeakRefinementLogParabolaUnbiased(spectrum, peak_index, used_zp)*double(GetSamplingRate())/spectrum.size();
126 harm.harm_number = h;
127 harms.push_back(harm);
134 double FundFreqRefinementOfHarmonicStruct(const vector<complex<double> >& spectrum, double approx_f0, int nb_harm, double used_zp)
136 double approx_f0_rel = approx_f0*spectrum.size()/double(GetSamplingRate());
137 assert(approx_f0_rel>1 && approx_f0_rel<=spectrum.size()/2-1);
139 vector<Harmonic> harms = GetHarmonicStruct(spectrum, approx_f0, nb_harm, used_zp, 0.2);
146 for(size_t i=0; i<harms.size(); i++)
147 sum_f0 += harms[i].freq/harms[i].harm_number; // TODO mod weigthed ???
149 return sum_f0/harms.size();
153 void SingleResConvolutionTransform::init()
155 if(GetSamplingRate()<=0) return;
157 for(size_t h=0; h<size(); h++)
158 if(m_convolutions[h]!=NULL)
159 delete m_convolutions[h];
161 m_components.resize(GetNbSemitones());
162 m_convolutions.resize(GetNbSemitones());
163 m_harmonics.resize(GetNbSemitones());
164 for(size_t h=0; h<size(); h++)
165 m_convolutions[h] = new Convolution(m_latency_factor, m_gauss_factor, int(h)+GetSemitoneMin());
168 SingleResConvolutionTransform::SingleResConvolutionTransform(double latency_factor, double gauss_factor)
169 : Transform(0.0, 0.0)
170 , m_latency_factor(latency_factor)
171 , m_gauss_factor(gauss_factor)
173 m_convolutions.resize(size());
174 m_harmonics.resize(size());
175 for(size_t h=0; h<size(); h++)
176 m_convolutions[h] = NULL;
179 void SingleResConvolutionTransform::apply(const deque<double>& buff)
181 for(size_t h=0; h<size(); h++)
183 m_is_fondamental[h] = false;
184 m_convolutions[h]->apply(buff);
185 m_harmonics[h] = m_convolutions[h]->m_value;
186 m_components[h] = mod(m_harmonics[h]);
189 SingleResConvolutionTransform::~SingleResConvolutionTransform()
191 for(size_t i=0; i<m_convolutions.size(); i++)
192 delete m_convolutions[i];
195 // NeuralNetGaussAlgo
196 void NeuralNetGaussAlgo::init()
198 cerr << "NeuralNetGaussAlgo::init" << endl;
200 SingleResConvolutionTransform::init();
202 // m_fwd_plan = rfftw_create_plan(m_size, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_OUT_OF_PLACE | FFTW_USE_WISDOM);
204 NeuralNetGaussAlgo::NeuralNetGaussAlgo(double latency_factor, double gauss_factor)
205 : SingleResConvolutionTransform(latency_factor, gauss_factor)
210 void NeuralNetGaussAlgo::apply(const deque<double>& buff)
212 // cerr << "NeuralNetGaussAlgo::apply " << m_components_treshold << endl;
214 m_components_max = 0.0;
215 for(size_t h=0; h<size(); h++)
217 m_convolutions[h]->apply(buff);
218 m_harmonics[h] = m_convolutions[h]->m_value;
219 m_components[h] = mod(m_harmonics[h]);
220 m_components_max = max(m_components_max, m_components[h]);
223 m_first_fond = UNDEFINED_SEMITONE;
224 for(size_t h=0; h<size(); h++)
226 m_is_fondamental[h] = false;
228 if(m_components[h]/m_components_max>m_components_treshold && m_first_fond==UNDEFINED_SEMITONE)
231 m_is_fondamental[h] = true;
236 NeuralNetGaussAlgo::~NeuralNetGaussAlgo()
241 MonophonicAlgo::MonophonicAlgo(double latency_factor, double gauss_factor)
242 : SingleResConvolutionTransform(latency_factor, gauss_factor)
246 int MonophonicAlgo::getSampleAlgoLatency() const
248 return m_convolutions[0]->size();
250 void MonophonicAlgo::apply(const deque<double>& buff)
252 for(size_t h=0; h<m_is_fondamental.size(); h++)
253 m_is_fondamental[h] = false;
256 m_components_max = 0.0;
259 // cout << "buff size=" << buff.size() << " size=" << m_convolutions[m_convolutions.size()-1]->size() << endl;
262 for(h=size()-1; h>=0 && buff.size()>=m_convolutions[h]->size(); h--)
265 if(h!=int(size())-1) i=m_convolutions[h+1]->size();
266 for(; i<m_convolutions[h]->size(); i++)
267 m_volume_max = max(m_volume_max, abs(buff[i]));
269 if(m_volume_max > getVolumeTreshold())
271 m_convolutions[h]->apply(buff);
273 double formant_mod = mod(m_convolutions[h]->m_value);
275 // cerr<<formant_mod<<" "<<getComponentsTreshold()<<endl;
277 // if(formant_mod > getComponentsTreshold())
279 // m_components[h] = min(formant_mod, max_value);
280 m_components[h] = formant_mod;
281 m_components_max = max(m_components_max, m_components[h]);
284 // else m_components[h] = 0.0;
286 else m_components[h] = 0.0;
289 m_components[h] = 0.0;
291 // smash all components below a treshold of the max component
292 // for(size_t h=0; h<size(); h++)
293 // if(m_components[h] < m_dominant_treshold*m_components_max)
294 // m_components[h] = 0.0;
296 // the note is the first resulting component
297 // for(size_t h=0; m_first_fond==-1 && h<size(); h++)
298 // if(m_components[h] > 0.0)
301 // correction: the note is the nearest maximum of m_note
302 // if(m_first_fond!=-1)
303 // while(m_first_fond+1<int(size()) && m_components[m_first_fond+1] > m_components[m_first_fond])
306 // cerr << "m_first_fond=" << m_first_fond << endl;
309 TwoVoiceMHT::TwoVoiceMHT(double AFreq, int dataBySecond, double rep, double win_factor, int minHT, int maxHT)
310 : m_mht(new MHT(AFreq, dataBySecond, rep, win_factor, minHT, maxHT))
311 , m_last_sol(m_mht->m_components.size())
313 int nbHT = maxHT - minHT + 1;
314 m_components.resize(nbHT);
316 for(size_t i=0; i<m_last_sol.size(); i++)
317 m_last_sol[i] = complex<double>(0.0,0.0);
319 void TwoVoiceMHT::apply(deque<double>& buff)
321 // cout << "TwoVoiceMHT::apply" << endl;
325 // double earingTreshold = 0.05;
326 // double modArgTreshold = 0.2;
327 // double modModTreshold = 0.2;
328 // ComputeDiffs(m_mht->m_components, fp, argpfp, modfp);
331 for(size_t h=0;h<m_components.size(); h++)
333 // if(m_mht->m_components[h]!=complex<double>(0.0,0.0) && count<2)
335 m_components[h] = m_mht->m_components[h];
338 // if(fabs(argpfp[0][h])>modArgTreshold) count++;
340 // else m_components[h] = complex<double>(0.0,0.0);
343 // m_last_sol = m_mht->m_components;
345 TwoVoiceMHT::~TwoVoiceMHT()
350 RemoveSyncMHT::RemoveSyncMHT(double AFreq, int dataBySecond, double rep, double win_factor, int minHT, int maxHT)
351 : m_mht(new MHT(AFreq, dataBySecond, rep, win_factor, minHT, maxHT))
352 , m_last_sol(m_mht->m_components.size())
354 int nbHT = maxHT - minHT + 1;
355 m_components.resize(nbHT);
357 for(size_t i=0; i<m_last_sol.size(); i++)
358 m_last_sol[i] = complex<double>(0.0,0.0);
360 void RemoveSyncMHT::apply(deque<double>& buff)
364 double earingTreshold = 0.05;
365 double syncArgTreshold = 0.3; // 0.02 0.25 0.2
366 // double syncModTreshold = 0.2; // 0.05 0.1 0.3
368 double fourier_amplitude = 0.0;
369 for(size_t h=0; h<m_mht->m_components.size(); h++)
370 fourier_amplitude = max(fourier_amplitude, normm(m_mht->m_components[h]));
373 for(size_t h=0; h<m_mht->m_components.size(); h++) // for each half tone
375 bool is_fond = false;
377 if(normm(m_mht->m_components[h])>earingTreshold*fourier_amplitude) // if we can ear it
381 // search for syncronisation with each discovered fondamentals
382 for(size_t i=0; i<notes.size() && is_fond; i++)
384 double rk = m_mht->m_convolutions[h]->m_freq/m_mht->m_convolutions[notes[i]]->m_freq;
386 if(abs(k-rk)<0.05) // TODO // if k is nearly an integer, a potential harmonic
388 complex<double> ft = m_mht->m_components[notes[i]] / normm(m_mht->m_components[notes[i]]);
389 complex<double> ftm1 = m_last_sol[notes[i]] / normm(m_last_sol[notes[i]]);
390 complex<double> rpt = m_mht->m_components[h]/pow(ft, k);
391 complex<double> rptm1 = m_last_sol[h]/pow(ftm1, k);
393 // cout << abs(log(normm(rpt))-log(normm(rptm1))) << " ";
394 // cout << k << "=(arg=" << abs(arg(rpt)-arg(rptm1)) << " mod=" << abs(log(normm(rpt))-log(normm(rptm1))) << ") ";
395 is_fond = abs(arg(rpt)-arg(rptm1)) > syncArgTreshold;
396 // is_fond = is_fond || abs(log(normm(rpt))-log(normm(rptm1))) > syncModTreshold;
402 if(is_fond) notes.push_back(h); // it's a fondamentals
407 if(is_fond) m_components[h] = m_mht->m_components[h];
408 else m_components[h] = complex<double>(0.0,0.0);
411 m_last_sol = m_mht->m_sol;
413 RemoveSyncMHT::~RemoveSyncMHT()
419 NeuralNetMHT::NeuralNetMHT(double AFreq, int dataBySecond, double rep, double win_factor, int minHT, int maxHT, const string& file_name)
420 : m_mht(new MHT(AFreq, dataBySecond, rep, win_factor, minHT, maxHT))
421 , m_nn(new LayeredNeuralNet<TypeNeuron>())
423 m_nbHT = maxHT - minHT + 1;
424 m_components.resize(m_nbHT);
426 m_nn->load(file_name.c_str());
428 assert(m_nbHT==m_nn->getInputLayer()->getNeurons().size());
429 assert(m_nbHT==m_nn->getOutputLayer()->getNeurons().size());
431 cout << "topology: " << m_nn->getInputLayer()->getNeurons().size();
432 for(LayeredNeuralNet<TypeNeuron>::LayerIterator it = ++(m_nn->m_layerList.begin()); it !=m_nn->m_layerList.end(); it++)
433 cout << " => " << (*it)->getNeurons().size();
434 cout << " [" << m_nn->getNbWeights() << " weights]" << endl;
436 void NeuralNetMHT::apply(deque<double>& buff)
438 // cout << "NeuralNetMHT::apply" << endl;
442 vector<double> inputs(m_nbHT);
444 for(int h=0; h<m_nbHT; h++)
445 inputs[h] = normm(m_mht->m_components[h]);
447 m_nn->computeOutputs(inputs);
449 for(int h=0; h<m_nbHT; h++)
450 m_components[h] = complex<double>(m_nn->getOutputLayer()->getNeurons()[h].o);
452 NeuralNetMHT::~NeuralNetMHT()