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