CircularPeakTunner.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2006 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef CircularPeakTunner_hxx
00023 #define CircularPeakTunner_hxx
00024 #include <list>
00025 #include <vector>
00026 #include <cmath>
00027 
00028 namespace Simac
00029 {
00030 
00041 class CircularPeakTunner
00042 {
00043 public:
00044         typedef std::vector<std::pair<double, double> > PeakList;
00045         typedef std::vector<std::pair<double, double> > PitchProfile;
00046 private:
00047         double _referenceTunning;
00048         PeakList _output;
00049         static const unsigned nSemitones = 12;
00050         static const unsigned binsPerSemitone = 3;
00051 public:
00052         CircularPeakTunner(double referenceTunning)
00053                 : _referenceTunning(referenceTunning)
00054         {
00055                 _output.reserve(nSemitones*binsPerSemitone);
00056         }
00057         ~CircularPeakTunner()
00058         {
00059         }
00068         unsigned chromagramToSemitone(double tunning, double peakPosition)
00069         {
00070                 double scaledPosition = peakPosition/binsPerSemitone;
00071                 double scaledTunning = tunning/binsPerSemitone;
00072                 double scaledReference = _referenceTunning/binsPerSemitone;
00073 
00074                 double shift = tunningShift(scaledReference, scaledTunning);
00075                 double tunnedPosition = tune(scaledPosition, shift);
00076 
00077                 int quantizedSemitone = int(tunnedPosition + .5);
00078                 unsigned refoldedSemitone = (quantizedSemitone+nSemitones)%nSemitones;
00079                 return refoldedSemitone;
00080         }
00081 
00082         static double tunningShift(double reference, double tunning)
00083         {
00084                 return - tunning - std::floor(reference-tunning+0.5);
00085         }
00086         static double tune(double peakPosition, double shift)
00087         {
00088                 double tunnedPosition = peakPosition + shift;
00089                 while (tunnedPosition<0) tunnedPosition += nSemitones;
00090                 while (tunnedPosition>= nSemitones) tunnedPosition -= nSemitones;
00091                 return tunnedPosition;
00092         }
00093 
00094         void doIt(double center, const PeakList & peaks)
00095         {
00096                 _output.resize(0);
00097                 const unsigned nPeaks=peaks.size();
00098                 double shift= tunningShift(_referenceTunning, center);
00099                 for (unsigned i=0; i<nPeaks; i++)
00100                 {
00101                         double tunnedPosition =  tune(peaks[i].first,shift);
00102                         _output.push_back(std::make_pair(tunnedPosition,peaks[i].second));
00103                 }
00104         }
00105 
00106         const PeakList & output() const
00107         {
00108                 return _output;
00109         }
00110 };
00111 
00112 } // namespace Simac
00113 
00114 #endif// CircularPeakTunner_hxx
00115 
Generated by  doxygen 1.6.3