Import fmit upstream version 0.97.6
[fmit.git] / libs / Music / FreqAnalysis.h
1 // Copyright 2004-07 "Gilles Degottex"
2
3 // This file is part of "Music"
4
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.
9 //
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.
14 //
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
18
19
20 #ifndef _FreqAnalysis_h_
21 #define _FreqAnalysis_h_
22
23 #include <vector>
24 #include <deque>
25 #include <complex>
26 #include <limits>
27 using namespace std;
28 #include <CppAddons/CAMath.h>
29 //#include <NeuralNet/mlp/LayeredNeuralNet.h>
30
31 #include "Music.h"
32 #include "Algorithm.h"
33 #include "Convolution.h"
34 #include <fftw3.h>
35
36 namespace Music
37 {
38         struct Partial
39         {
40                 double mod;
41                 double phase;
42                 double freq;            // Hz
43                 double noise_lvl;       // in [0,1]
44         };
45         struct Harmonic : Partial
46         {
47                 int harm_number;
48         };
49
50         inline bool is_peak(double p1, double p2, double p3)
51         {
52                 return p1<p2 && p2>p3;
53         }
54         inline bool is_peak(const std::vector<std::complex<double> > spectrum, int c)
55         {
56                 assert(c>0 && c<int(spectrum.size())/2-1);
57
58                 return is_peak(Math::mod2(spectrum[c-1]), Math::mod2(spectrum[c]), Math::mod2(spectrum[c+1]));
59         }
60
61         double PeakRefinementLogParabola(const std::vector<std::complex<double> > spectrum, int peak_index);
62         double PeakRefinementLogParabolaUnbiased(const std::vector<std::complex<double> > spectrum, int peak_index, double zp);
63
64         std::vector<Harmonic> GetHarmonicStruct(const std::vector<std::complex<double> >& spectrum, double approx_f0, int nb_harm, double used_zp, double offset_tresh=0.1);
65         double FundFreqRefinementOfHarmonicStruct(const std::vector<std::complex<double> >& spectrum, double approx_f0, int nb_harm, double used_zp);
66
67         /*! the simpler: only one big convolution on the whole window
68          * O(N)
69          */
70         class SingleResConvolutionTransform : public Transform
71         {
72           protected:
73                 virtual void init();
74                 virtual void AFreqChanged()                                                     {init();}
75                 virtual void samplingRateChanged()                                      {init();}
76                 virtual void semitoneBoundsChanged()                            {init();}
77                 double m_latency_factor;
78                 double m_gauss_factor;
79
80           public:
81                 std::vector<Convolution*> m_convolutions;
82
83                 SingleResConvolutionTransform(double latency_factor, double gauss_factor);
84
85                 void setLatencyFactor(double latency)                           {m_latency_factor=latency; init();}
86                 double getLatencyFactor()                                                       {return m_latency_factor;}
87
88                 void setGaussFactor(double g)                                           {m_gauss_factor=g; init();}
89                 double getGaussFactor()                                                         {return m_gauss_factor;}
90
91                 virtual void apply(const std::deque<double>& buff);
92
93                 virtual ~SingleResConvolutionTransform();
94         };
95
96         /*! extraction des fondamentales avec un r�aux de neurones
97          * entr�s avec la visualisation dans le plan de Gauss
98          */
99         struct NeuralNetGaussAlgo : SingleResConvolutionTransform
100         {
101 //              typedef Neuron TypeNeuron;
102 //              LayeredNeuralNet<TypeNeuron>* m_nn;
103
104                 virtual void init();
105
106                 NeuralNetGaussAlgo(double latency_factor, double gauss_factor);
107
108                 virtual int getSampleAlgoLatency() const {return 0;}
109
110                 virtual void apply(const deque<double>& buff);
111
112                 virtual ~NeuralNetGaussAlgo();
113         };
114
115         /*! Monophonic Algorithm: algo for one voice
116          * O(nbHT)
117          */
118         class MonophonicAlgo : public SingleResConvolutionTransform
119         {
120           protected:
121                 double m_dominant_treshold;
122
123           public:
124                 MonophonicAlgo(double latency_factor, double gauss_factor);
125                 //! in millis
126                 virtual double getAlgoLatency() const                   {return 1000.0*m_convolutions[0]->size()/GetSamplingRate();}
127                 virtual int getSampleAlgoLatency() const;
128
129                 inline double getDominantTreshold()                     {return m_dominant_treshold;}
130                 inline void setDominantTreshold(double t)       {m_dominant_treshold=t;}
131
132                 virtual void apply(const deque<double>& buff);
133
134                 virtual ~MonophonicAlgo()                                       {}
135         };
136
137 #if 0
138         /*! algo for two voice
139          * O()
140          */
141         struct TwoVoiceMHT : MultiHalfTone
142         {
143                 //      typedef RemoveSyncMHT MHT;
144                 typedef SingleResMultiHalfTone MHT;
145
146                 MHT* m_mht;
147                 vector< complex<double> > m_last_sol;
148
149                 deque< vector<complex<double> > > fp;
150                 deque< vector<double> > argpfp;
151                 deque< vector<double> > modfp;
152
153                 TwoVoiceMHT(){}
154                 TwoVoiceMHT(double AFreq, int dataBySecond, double maxRep, double win_factor, int minHT, int maxHT);
155
156                 virtual void apply(deque<double>& buff);
157
158                 virtual ~TwoVoiceMHT();
159         };
160
161         /*! multiply "usefull" data quantity
162          * O()
163          */
164         struct OneDataMultiplierMHT : MultiHalfTone
165         {
166                 vector< SingleHalfTone* > m_sht;
167
168                 rfftw_plan m_fwd_plan;
169                 rfftw_plan m_bck_plan;
170                 fftw_real* m_in;
171                 fftw_real* m_out;
172
173                 int m_length;
174                 int m_size;
175                 int m_rep;
176
177                 OneDataMultiplierMHT(){}
178                 OneDataMultiplierMHT(double AFreq, int dataBySecond, double rep, double win_factor, int minHT, int maxHT);
179
180                 virtual void apply(deque<double>& buff);
181
182                 virtual ~OneDataMultiplierMHT();
183         };
184
185         /*! une grande convolution qui couvre toute la fen�re et qui sert "d'indicateur" �la petit r�olution se trouvant au d�ut
186          * O(nbHT*2)
187          */
188         struct IndicMultiHalfTone : SingleResMultiHalfTone
189         {
190                 vector< SingleHalfTone* > m_small_sht;
191
192                 IndicMultiHalfTone(double AFreq, int dataBySecond, double maxRep, double win_factor, int minHT, int maxHT);
193
194                 virtual void apply(deque<double>& buff);
195         };
196
197         /*! integration sur plusieurs r�olution (Ondelettes)
198          * racourcit consid�ablement la chute d'une note, mais pas l'entr�
199          * O(nbHT*maxRep/3)
200          */
201         struct MultiResMultiHalfTone : MultiHalfTone
202         {
203                 vector< vector<SingleHalfTone*> > m_sht;
204
205                 MultiResMultiHalfTone(){}
206                 MultiResMultiHalfTone(double AFreq, int dataBySecond, double maxRep, double win_factor, int minHT, int maxHT);
207
208                 virtual void apply(deque<double>& buff);
209
210                 virtual ~MultiResMultiHalfTone();
211         };
212
213         /*! minimum sur trois classes de r�olution
214          * - une grande qui couvre toute la fen�re (augmente la r�olution en fr�uence)
215          * - des progressivement plus petites qui commence au d�ut de la grande fen�re (augemente la r�olution en temps �la fin d'une note)
216          * - des progressivement plus petites qui finissent �la fin de la grande fen�re (augmente la r�olution en temps au d�ut d'une note)
217          * O(nbHT*maxRep/2)
218          */
219         struct TriResMultiHalfTone : MultiResMultiHalfTone
220         {
221                 TriResMultiHalfTone(double AFreq, int dataBySecond, double maxRep, double win_factor, int minHT, int maxHT);
222
223                 virtual void apply(deque<double>& buff);
224         };
225
226         /*! supprime les fr�uences syncronis�s
227          * REDO
228          * O()
229          */
230         struct RemoveSyncMHT : MultiHalfTone
231         {
232                 typedef SingleResMultiHalfTone MHT;
233
234                 MHT* m_mht;
235                 vector< complex<double> > m_last_sol;
236
237                 RemoveSyncMHT(){}
238                 RemoveSyncMHT(double AFreq, int dataBySecond, double maxRep, double win_factor, int minHT, int maxHT);
239
240                 virtual void apply(deque<double>& buff);
241
242                 virtual ~RemoveSyncMHT();
243         };
244 #endif
245 }
246
247 #endif // _FreqAnalysis_h_
248