1 // Copyright 2005 "Gilles Degottex"
3 // This file is part of "Music"
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.
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.
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
20 #include "Quantizer.h"
24 #include <Music/Music.h>
25 using namespace Music;
26 #include <CppAddons/Random.h>
28 Quantizer::Quantizer(float tolerance, float min_density)
31 m_channels.resize(97);
33 m_tolerance = tolerance;
34 m_min_density = min_density;
39 void Quantizer::quantize(const vector<bool> hts, int min_ht)
41 double current_time = m_time.elapsed();
43 m_min_stored_recon = 1000000;
44 for(size_t ht=0; ht<hts.size(); ht++)
46 int rht = ht+min_ht-m_min_ht;
49 m_channels[rht].old_states.push_front(State(current_time, hts[ht]));
51 m_min_stored_recon = min(m_min_stored_recon, int(m_channels[rht].old_states.size()));
56 // drop unused recognitions
57 while(!m_channels[rht].old_states.empty() && (current_time-m_channels[rht].old_states.back().time>m_tolerance))
58 m_channels[rht].old_states.pop_back();
62 void Quantizer::update(int rht)
64 Channel& channel = m_channels[rht];
66 if(!channel.old_states.empty())
70 for(size_t i=0; i<channel.old_states.size(); i++)
71 if(channel.old_states[i].play)
74 channel.reliability = float(dens)/channel.old_states.size();
76 // if a density is strong enough (depend of parameter dens_required)
77 if(channel.reliability>m_min_density)
79 if(channel.state==Channel::QC_NOTHING)
81 channel.state = Channel::QC_STARTING;
82 channel.duration.start();
86 if(channel.state==Channel::QC_STARTING)
88 if(channel.lag.elapsed()>m_tolerance)
90 channel.state = Channel::QC_PLAYING;
91 channel.last_tag = Random::s_random.nextInt();
92 MFireEvent(noteStarted(channel.last_tag, rht+m_min_ht, -channel.lag.elapsed()));
96 if(channel.state==Channel::QC_PLAYING)
101 if(channel.state==Channel::QC_STARTING)
102 channel.state = Channel::QC_NOTHING;
103 else if(channel.state==Channel::QC_PLAYING && channel.lag.elapsed()>m_tolerance)
105 channel.state = Channel::QC_NOTHING;
106 MFireEvent(noteFinished(channel.last_tag, rht+m_min_ht, -channel.lag.elapsed()));
107 MFireEvent(notePlayed(rht+m_min_ht, channel.duration.elapsed()-channel.lag.elapsed(), -channel.lag.elapsed()-channel.duration.elapsed()));
113 void Quantizer::cutAll()
115 m_min_stored_recon = 0;
116 for(size_t ht=0; ht<m_channels.size(); ht++)
118 m_channels[ht].old_states.clear();