| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -180,6 +180,154 @@ struct ProcessParameters | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline REALTYPE profile(REALTYPE fi, REALTYPE bwi) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE x = fi / bwi; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				x *= x; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (x>14.71280603) return 0.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return exp(-x);///bwi; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_do_harmonics(ProcessParameters& pars, std::vector<REALTYPE>& tmpfreq1, int nfreq, double samplerate, REALTYPE *freq1, REALTYPE *freq2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE freq = pars.harmonics.freq; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE bandwidth = pars.harmonics.bandwidth; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int nharmonics = pars.harmonics.nharmonics; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (freq<10.0) freq = 10.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE *amp = tmpfreq1.data(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) amp[i] = 0.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int nh = 1; nh <= nharmonics; nh++) {//for each harmonic | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE bw_Hz;//bandwidth of the current harmonic measured in Hz | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE bwi; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE fi; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE f = nh * freq; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (f >= samplerate / 2) break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					bw_Hz = (pow(2.0f, bandwidth / 1200.0f) - 1.0f)*f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					bwi = bw_Hz / (2.0f*samplerate); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					fi = f / samplerate; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE sum = 0.0f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE max = 0.0f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (int i = 1; i<nfreq; i++) {//todo: optimize here | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						REALTYPE hprofile; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						hprofile = profile((i / (REALTYPE)nfreq*0.5f) - fi, bwi); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						amp[i] += hprofile; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (max<hprofile) max = hprofile; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						sum += hprofile; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE max = 0.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 1; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (amp[i]>max) max = amp[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (max<1e-8f) max = 1e-8f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 1; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					//REALTYPE c,s; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE a = amp[i] / max; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (!pars.harmonics.gauss) a = (a<0.368f ? 0.0f : 1.0f); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					freq2[i] = freq1[i] * a; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_add(int nfreq, REALTYPE *freq2, REALTYPE *freq1, REALTYPE a) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) freq2[i] += freq1[i] * a; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_zero(int nfreq,REALTYPE *freq1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) freq1[i] = 0.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_do_freq_shift(ProcessParameters& pars, int nfreq, double samplerate, REALTYPE *freq1, REALTYPE *freq2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				spectrum_zero(nfreq, freq2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int ifreq = (int)(pars.freq_shift.Hz / (samplerate*0.5)*nfreq); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					int i2 = ifreq + i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if ((i2>0) && (i2<nfreq)) freq2[i2] = freq1[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_do_pitch_shift(ProcessParameters& pars, int nfreq, REALTYPE *freq1, REALTYPE *freq2, REALTYPE _rap) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				spectrum_zero(nfreq,freq2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_rap<1.0) {//down | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (int i = 0; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						int i2 = (int)(i*_rap); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (i2 >= nfreq) break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						freq2[i2] += freq1[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (_rap >= 1.0) {//up | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					_rap = 1.0f / _rap; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (int i = 0; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						freq2[i] = freq1[(int)(i*_rap)]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_do_octave(ProcessParameters& pars, int nfreq, double samplerate,  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				std::vector<REALTYPE>& sumfreq,  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				std::vector<REALTYPE>& tmpfreq1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE *freq1, REALTYPE *freq2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				spectrum_zero(nfreq,sumfreq.data()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.om2>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_do_pitch_shift(pars,nfreq, freq1, tmpfreq1.data(), 0.25); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq, sumfreq.data(), tmpfreq1.data(), pars.octave.om2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.om1>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_do_pitch_shift(pars,nfreq, freq1, tmpfreq1.data(), 0.5); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq,sumfreq.data(), tmpfreq1.data(), pars.octave.om1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.o0>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq,sumfreq.data(), freq1, pars.octave.o0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.o1>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_do_pitch_shift(pars,nfreq, freq1, tmpfreq1.data(), 2.0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq,sumfreq.data(), tmpfreq1.data(), pars.octave.o1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.o15>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_do_pitch_shift(pars,nfreq, freq1, tmpfreq1.data(), 3.0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq,sumfreq.data(), tmpfreq1.data(), pars.octave.o15); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.octave.o2>1e-3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_do_pitch_shift(pars, nfreq, freq1, tmpfreq1.data(), 4.0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					spectrum_add(nfreq,sumfreq.data(), tmpfreq1.data(), pars.octave.o2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE sum = 0.01f + pars.octave.om2 + pars.octave.om1 + pars.octave.o0 + pars.octave.o1 + pars.octave.o15 + pars.octave.o2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (sum<0.5f) sum = 0.5f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) freq2[i] = sumfreq[i] / sum; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			inline void spectrum_do_filter(ProcessParameters& pars, int nfreq, double samplerate, REALTYPE *freq1, REALTYPE *freq2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE low = 0, high = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pars.filter.low<pars.filter.high) {//sort the low/high freqs | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					low = pars.filter.low; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					high = pars.filter.high; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					high = pars.filter.low; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					low = pars.filter.high; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int ilow = (int)(low / samplerate * nfreq*2.0f); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int ihigh = (int)(high / samplerate * nfreq*2.0f); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE dmp = 1.0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				REALTYPE dmprap = 1.0f - pow(pars.filter.hdamp*0.5f, 4.0f); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (int i = 0; i<nfreq; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					REALTYPE a = 0.0f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if ((i >= ilow) && (i<ihigh)) a = 1.0f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (pars.filter.stop) a = 1.0f - a; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					freq2[i] = freq1[i] * a*dmp; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					dmp *= dmprap + 1e-8f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			class SpectrumProcess | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			public: | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |