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 
is_peak(double p1,double p2,double p3)50 	inline bool is_peak(double p1, double p2, double p3)
51 	{
52 		return p1<p2 && p2>p3;
53 	}
is_peak(const std::vector<std::complex<double>> spectrum,int c)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, bool pick_nonpeaks=false);
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();
AFreqChanged()74 		virtual void AFreqChanged()							{init();}
samplingRateChanged()75 		virtual void samplingRateChanged()					{init();}
semitoneBoundsChanged()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 
setLatencyFactor(double latency)85 		void setLatencyFactor(double latency)				{m_latency_factor=latency; init();}
getLatencyFactor()86 		double getLatencyFactor()							{return m_latency_factor;}
87 
setGaussFactor(double g)88 		void setGaussFactor(double g)						{m_gauss_factor=g; init();}
getGaussFactor()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 
getSampleAlgoLatencyNeuralNetGaussAlgo108 		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
getAlgoLatency()126 		virtual double getAlgoLatency()	const			{return 1000.0*m_convolutions[0]->size()/GetSamplingRate();}
127 		virtual int getSampleAlgoLatency() const;
128 
getDominantTreshold()129 		inline double getDominantTreshold()			{return m_dominant_treshold;}
setDominantTreshold(double t)130 		inline void setDominantTreshold(double t)	{m_dominant_treshold=t;}
131 
132 		virtual void apply(const deque<double>& buff);
133 
~MonophonicAlgo()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 
249