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