// Copyright 2004 "Gilles Degottex" // This file is part of "Music" // "Music" is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 2.1 of the License, or // (at your option) any later version. // // "Music" is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "MultiCumulativeDiffAlgo.h" #include #include #include #include using namespace std; #include using namespace Math; #include "Music.h" //#define MUSIC_DEBUG #ifdef MUSIC_DEBUG #define LOG(a) a #else #define LOG(a) #endif namespace Music { void MultiCumulativeDiffAlgo::init() { for(size_t i=0; i0); m_test_complexity = test_complexity; m_diffs.resize(size()); for(size_t i=0; i=0 && ih+1=0 && ih-1& buff) { assert(GetSamplingRate()>0); for(size_t i=0; im_s) return; double v = 0.0; for(size_t i=0; im_s; i++) v = max(v, abs(buff[i])); if(v>getAmplitudeTreshold()) { // compute all components m_components_max = 0.0; double min_comp = 1000000; double max_sum = 0.0; for(int ih=int(size())-1; ih>=0; ih--) { m_diffs[ih]->receive(buff, 0); m_components[ih] = m_diffs[ih]->m_error; m_components_max = max(m_components_max, m_components[ih]); } // test components for(int ih=int(size())-1; ih>=0; ih--) { bool ok = true; bool crit_min = true; // criteria: the fond and his first harmonics are minimas if(ok) ok = is_minima(ih) && is_minima(ih-12) && (is_minima(ih-19) || is_minima(ih-19-1) || is_minima(ih-19+1)) && is_minima(ih-24); crit_min = ok; bool crit_small_enough = true; if(ok) { if(m_components[ih]/m_components_max>getComponentTreshold()) crit_small_enough = false; ok = crit_small_enough; } // bool crit_cross_zero = true; /* // criteria: wave should cross the zero value if(ok) { bool cross = true; for(int s=0; cross && sm_s); s++) { double sg = Math::sgn(buff[s]); bool same_side = true; for(int i=0; same_side && im_s); i++) same_side = Math::sgn(buff[s+i])==sg; cross = !same_side; } ok = crit_cross_zero = cross; } */ // bool crit_integ_cst = true; // criteria: integral should be nearly constant while shifting // TODO // (the previous criteria seems sufficient to remove high comp.) // LOG(if(crit_min) // cerr << "ih=" << ih << // " harm_min=(("<max_sum) { size_t step = size_t(m_diffs[ih]->m_s/m_test_complexity); if(step<1) step = 1; for(size_t s=0; ok && sm_s; s+=step) { if(ih-1>=0){ m_diffs[ih-1]->receive(buff, s); m_components[ih-1] = m_diffs[ih-1]->m_error; } if(ih+1receive(buff, s); m_components[ih+1] = m_diffs[ih+1]->m_error; } m_diffs[ih]->receive(buff, s); m_components[ih] = m_diffs[ih]->m_error; ok = is_minima(ih); } if(ok) { max_sum = sum; min_comp = m_components[ih]; m_first_fond = ih; } } } } // cerr << "ff: " << m_first_fond << endl; if(m_first_fond!=-1) m_is_fondamental[m_first_fond] = true; LOG(cerr << "m_first_fond=" << m_first_fond << endl;) } } MultiCumulativeDiffAlgo::~MultiCumulativeDiffAlgo() { for(size_t i=0; i