annotate MonoPitchHMM.cpp @ 64:e291f3657872 tony tony_v0.5

Didn't intend to commit the build in debug mode
author Chris Cannam
date Wed, 02 Apr 2014 10:37:49 +0100
parents b39d6745c596
children 16129c3b1cf5
rev   line source
Chris@9 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@9 2
Chris@9 3 /*
Chris@9 4 pYIN - A fundamental frequency estimator for monophonic audio
Chris@9 5 Centre for Digital Music, Queen Mary, University of London.
Chris@9 6
Chris@9 7 This program is free software; you can redistribute it and/or
Chris@9 8 modify it under the terms of the GNU General Public License as
Chris@9 9 published by the Free Software Foundation; either version 2 of the
Chris@9 10 License, or (at your option) any later version. See the file
Chris@9 11 COPYING included with this distribution for more information.
Chris@9 12 */
Chris@9 13
matthiasm@0 14 #include "MonoPitchHMM.h"
matthiasm@0 15
matthiasm@0 16 #include <boost/math/distributions.hpp>
matthiasm@0 17
matthiasm@0 18 #include <cstdio>
matthiasm@0 19 #include <cmath>
matthiasm@0 20
matthiasm@0 21 using std::vector;
matthiasm@0 22 using std::pair;
matthiasm@0 23
matthiasm@0 24 MonoPitchHMM::MonoPitchHMM() :
matthiasm@58 25 m_minFreq(77.782), // e flat 2
matthiasm@58 26 // m_minFreq(110),
matthiasm@24 27 m_nBPS(5),
matthiasm@0 28 m_nPitch(0),
matthiasm@0 29 m_transitionWidth(0),
matthiasm@0 30 m_selfTrans(0.99),
matthiasm@0 31 m_yinTrust(.5),
matthiasm@0 32 m_freqs(0)
matthiasm@0 33 {
matthiasm@50 34 m_transitionWidth = 9*(m_nBPS/2) + 1;
matthiasm@58 35 m_nPitch = 64 * m_nBPS;
matthiasm@25 36 m_freqs = vector<double>(2*m_nPitch);
matthiasm@0 37 for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
matthiasm@0 38 {
matthiasm@0 39 m_freqs[iPitch] = m_minFreq * std::pow(2, iPitch * 1.0 / (12 * m_nBPS));
matthiasm@0 40 m_freqs[iPitch+m_nPitch] = -m_freqs[iPitch];
matthiasm@0 41 }
matthiasm@0 42 build();
matthiasm@0 43 }
matthiasm@0 44
matthiasm@0 45 const vector<double>
matthiasm@0 46 MonoPitchHMM::calculateObsProb(const vector<pair<double, double> > pitchProb)
matthiasm@0 47 {
matthiasm@0 48 vector<double> out = vector<double>(2*m_nPitch+1);
matthiasm@0 49 double probYinPitched = 0;
matthiasm@0 50 // BIN THE PITCHES
matthiasm@0 51 for (size_t iPair = 0; iPair < pitchProb.size(); ++iPair)
matthiasm@0 52 {
matthiasm@0 53 double freq = 440. * std::pow(2, (pitchProb[iPair].first - 69)/12);
matthiasm@0 54 if (freq <= m_minFreq) continue;
matthiasm@0 55 double d = 0;
matthiasm@0 56 double oldd = 1000;
matthiasm@0 57 for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
matthiasm@0 58 {
matthiasm@0 59 d = std::abs(freq-m_freqs[iPitch]);
matthiasm@0 60 if (oldd < d && iPitch > 0)
matthiasm@0 61 {
matthiasm@0 62 // previous bin must have been the closest
matthiasm@0 63 out[iPitch-1] = pitchProb[iPair].second;
matthiasm@0 64 probYinPitched += out[iPitch-1];
matthiasm@0 65 break;
matthiasm@0 66 }
matthiasm@0 67 oldd = d;
matthiasm@0 68 }
matthiasm@0 69 }
matthiasm@0 70
matthiasm@0 71 double probReallyPitched = m_yinTrust * probYinPitched;
matthiasm@58 72 // std::cerr << probReallyPitched << " " << probYinPitched << std::endl;
matthiasm@58 73 // damn, I forget what this is all about...
matthiasm@0 74 for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
matthiasm@0 75 {
matthiasm@0 76 if (probYinPitched > 0) out[iPitch] *= (probReallyPitched/probYinPitched) ;
matthiasm@0 77 out[iPitch+m_nPitch] = (1 - probReallyPitched) / m_nPitch;
matthiasm@0 78 }
matthiasm@0 79 // out[2*m_nPitch] = m_yinTrust * (1 - probYinPitched);
matthiasm@0 80 return(out);
matthiasm@0 81 }
matthiasm@0 82
matthiasm@0 83 void
matthiasm@0 84 MonoPitchHMM::build()
matthiasm@0 85 {
matthiasm@0 86 // INITIAL VECTOR
matthiasm@25 87 init = vector<double>(2*m_nPitch, 1.0 / 2*m_nPitch);
matthiasm@0 88
matthiasm@0 89 // TRANSITIONS
matthiasm@0 90 for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
matthiasm@0 91 {
matthiasm@0 92 int theoreticalMinNextPitch = static_cast<int>(iPitch)-static_cast<int>(m_transitionWidth/2);
matthiasm@0 93 int minNextPitch = iPitch>m_transitionWidth/2 ? iPitch-m_transitionWidth/2 : 0;
matthiasm@0 94 int maxNextPitch = iPitch<m_nPitch-m_transitionWidth/2 ? iPitch+m_transitionWidth/2 : m_nPitch-1;
matthiasm@0 95
matthiasm@0 96 // WEIGHT VECTOR
matthiasm@0 97 double weightSum = 0;
matthiasm@0 98 vector<double> weights;
matthiasm@0 99 for (size_t i = minNextPitch; i <= maxNextPitch; ++i)
matthiasm@0 100 {
matthiasm@0 101 if (i <= iPitch)
matthiasm@0 102 {
matthiasm@0 103 weights.push_back(i-theoreticalMinNextPitch+1);
matthiasm@0 104 // weights.push_back(i-theoreticalMinNextPitch+1+m_transitionWidth/2);
matthiasm@0 105 } else {
matthiasm@0 106 weights.push_back(iPitch-theoreticalMinNextPitch+1-(i-iPitch));
matthiasm@0 107 // weights.push_back(iPitch-theoreticalMinNextPitch+1-(i-iPitch)+m_transitionWidth/2);
matthiasm@0 108 }
matthiasm@0 109 weightSum += weights[weights.size()-1];
matthiasm@0 110 }
matthiasm@0 111
matthiasm@0 112 // std::cerr << minNextPitch << " " << maxNextPitch << std::endl;
matthiasm@0 113 // TRANSITIONS TO CLOSE PITCH
matthiasm@0 114 for (size_t i = minNextPitch; i <= maxNextPitch; ++i)
matthiasm@0 115 {
matthiasm@0 116 from.push_back(iPitch);
matthiasm@0 117 to.push_back(i);
matthiasm@0 118 transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
matthiasm@0 119
matthiasm@0 120 from.push_back(iPitch);
matthiasm@0 121 to.push_back(i+m_nPitch);
matthiasm@0 122 transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
matthiasm@0 123
matthiasm@0 124 from.push_back(iPitch+m_nPitch);
matthiasm@0 125 to.push_back(i+m_nPitch);
matthiasm@0 126 transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
matthiasm@0 127 // transProb.push_back(weights[i-minNextPitch] / weightSum * 0.5);
matthiasm@0 128
matthiasm@0 129 from.push_back(iPitch+m_nPitch);
matthiasm@0 130 to.push_back(i);
matthiasm@0 131 transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
matthiasm@0 132 // transProb.push_back(weights[i-minNextPitch] / weightSum * 0.5);
matthiasm@0 133 }
matthiasm@0 134
matthiasm@0 135 // TRANSITION TO UNVOICED
matthiasm@0 136 // from.push_back(iPitch+m_nPitch);
matthiasm@0 137 // to.push_back(2*m_nPitch);
matthiasm@0 138 // transProb.push_back(1-m_selfTrans);
matthiasm@0 139
matthiasm@0 140 // TRANSITION FROM UNVOICED TO PITCH
matthiasm@25 141 // from.push_back(2*m_nPitch);
matthiasm@25 142 // to.push_back(iPitch+m_nPitch);
matthiasm@25 143 // transProb.push_back(1.0/m_nPitch);
matthiasm@0 144 }
matthiasm@0 145 // UNVOICED SELFTRANSITION
matthiasm@0 146 // from.push_back(2*m_nPitch);
matthiasm@0 147 // to.push_back(2*m_nPitch);
matthiasm@0 148 // transProb.push_back(m_selfTrans);
matthiasm@0 149
matthiasm@0 150 // for (size_t i = 0; i < from.size(); ++i) {
matthiasm@0 151 // std::cerr << "P(["<< from[i] << " --> " << to[i] << "]) = " << transProb[i] << std::endl;
matthiasm@0 152 // }
matthiasm@0 153
Chris@9 154 }