Import fmit upstream version 0.97.6
[fmit.git] / src / LatencyMonoQuantizer.cpp
1 // Copyright 2005 "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 #include "MonoQuantizer.h"
21
22 #include <iostream>
23 using namespace std;
24 #include <Music/Music.h>
25 using namespace Music;
26 #include "LatencyMonoQuantizer.h"
27
28 LatencyMonoQuantizer::LatencyMonoQuantizer()
29 {
30         m_latency = 125;        // ms
31
32         m_time.start();
33 }
34
35 void LatencyMonoQuantizer::quantize(double freq)
36 {
37 //      cerr << "LatencyMonoQuantizer::quantize " << freq << " m_states=" << m_states.size() << endl;
38
39         double current_time = m_time.elapsed();
40
41         m_states.push_front(State(current_time, freq));
42
43         double current_center_freq = h2f(f2h(freq));
44         int max_dens = 1;
45         m_avg_freq = freq;
46         map<double,Note> densities;
47         for(int i=0; i<m_states.size(); i++)
48         {
49                 double cf = h2f(f2h(m_states[i].m_freq));
50                 map<double,Note>::iterator it=densities.find(cf);
51                 if(it==densities.end())
52                         densities.insert(make_pair(cf,Note(m_states[i].m_freq)));
53                 else
54                 {
55                         it->second.m_avg_freq *= it->second.m_dens;
56                         it->second.m_avg_freq += m_states[i].m_freq;
57                         it->second.m_dens++;
58                         it->second.m_avg_freq /= it->second.m_dens;
59                         if(it->second.m_dens>max_dens)
60                         {
61                                 max_dens = it->second.m_dens;
62                                 current_center_freq = it->first;
63                                 m_avg_freq = it->second.m_avg_freq;
64                         }
65                 }
66         }
67
68 //      cerr << m_current_center_freq << ", " << current_center_freq << ", " << m_avg_freq << ", max_dens=" << max_dens << ", m_states.size()=" << m_states.size() << endl;
69
70         m_confidence = double(max_dens)/m_states.size();
71
72         // if a density is strong enough
73         if(m_confidence>m_min_confidence)
74         {
75                 if(m_current_center_freq==0.0)
76                 {
77                         if(current_center_freq>0.0)
78                         {
79                                 m_current_center_freq = current_center_freq;
80                                 m_duration.start();
81                                 double lag = (current_time-m_states.back().m_time)*m_min_confidence;
82                                 m_duration.addMSecs(int(lag));
83                                 emit(noteStarted(m_current_center_freq, -lag));
84                         }
85                 }
86                 else
87                 {
88                         if(current_center_freq==0.0)
89                         {
90                                 m_current_center_freq = current_center_freq;
91                                 double lag = (current_time-m_states.back().m_time)*m_min_confidence;
92                                 emit(noteFinished(m_current_center_freq, -lag));
93                         }
94                         else if(m_current_center_freq != current_center_freq)
95                         {
96                                 double lag = (current_time-m_states.back().m_time)/2.0; // TODO pas forcĂ©ment a fait 2 ~bruit
97                                 emit(noteFinished(m_current_center_freq, -lag));
98                                 m_current_center_freq = current_center_freq;
99                                 m_duration.start();
100                                 m_duration.addMSecs(int(lag));
101                                 emit(noteStarted(m_current_center_freq, -lag));
102                         }
103                 }
104         }
105         else if(m_current_center_freq>0.0)
106         {
107                 m_current_center_freq = 0.0;
108                 double lag = (current_time-m_states.back().m_time)*m_min_confidence;
109                 emit(noteFinished(m_current_center_freq, -lag));
110         }
111
112         while(!m_states.empty() && (current_time-m_states.back().m_time>m_latency))
113                 m_states.pop_back();
114 }
115
116 void LatencyMonoQuantizer::reset()
117 {
118         quantize(0.0);
119         m_avg_freq = 0.0;
120         m_states.clear();
121         m_confidence = 1.0;
122 }