add more spacing
[personal-kdebase.git] / workspace / khotkeys / libkhotkeysprivate / voices.cpp
blobd49cf12469956204f722bd05739b29db35804529
1 /****************************************************************************
3 KHotKeys
5 Copyright (C) 2005 Olivier Goffart <ogoffart @ kde.org>
7 Distributed under the terms of the GNU General Public License version 2.
9 ****************************************************************************/
12 #include <kaction.h>
14 #include "voices.h"
15 #include "voicesignature.h"
16 #include "triggers.h"
17 #include "soundrecorder.h"
19 #include <stdlib.h>
20 #include <math.h>
21 #include <assert.h>
24 #include <kapplication.h>
25 #include <kdebug.h>
26 #include <kxerrorhandler.h>
27 #include <QtCore/QTimer>
30 #include <X11/Xlib.h>
31 #include <fixx11h.h>
35 namespace KHotKeys
38 Voice* voice_handler;
40 Voice::Voice( bool enabled_P, QObject* parent_P )
41 : QObject( parent_P) ,_enabled( enabled_P ), _recording( false ), _recorder(0)
43 assert( voice_handler == NULL );
44 voice_handler = this;
46 _kga=0L;
47 _timer=0L;
49 kDebug() ;
53 Voice::~Voice()
55 kDebug() ;
56 enable( false );
57 voice_handler = NULL;
61 void Voice::enable( bool enabled_P )
63 #ifndef HAVE_ARTS
64 enabled_P = false; // never enabled when there's no support
65 #endif
66 if( _enabled == enabled_P )
67 return;
68 _enabled = enabled_P;
69 _kga->setEnabled(enabled_P);
72 void Voice::register_handler( Voice_trigger *trigger_P )
74 if( !_references.contains( trigger_P ))
75 _references.append(trigger_P);
78 void Voice::unregister_handler( Voice_trigger *trigger_P )
80 _references.remove(trigger_P);
84 void Voice::record_start()
86 kDebug() ;
87 if(!_recorder)
89 _recorder= SoundRecorder::create(this);
90 connect(_recorder, SIGNAL(recorded(const Sound& )), this, SLOT(slot_sound_recorded(const Sound& )));
93 _recorder->start();
94 _recording=true;
97 void Voice::record_stop()
99 if(!_recording)
100 return;
102 kDebug() ;
103 delete _timer;
104 _timer=0L;
105 _recording=false;
106 if(_recorder)
107 _recorder->stop();
111 void Voice::slot_sound_recorded(const Sound &sound_P)
113 VoiceSignature signature(sound_P);
115 Voice_trigger *trig=0L;
116 Voice_trigger *sec_trig=0L;
117 double minimum=800000;
118 double second_minimum=80000;
119 int got_count=0;
120 foreach(Voice_trigger *t, _references)
122 for(int ech=1; ech<=2 ; ech++)
124 double diff=VoiceSignature::diff(signature, t->voicesignature(ech));
125 if(minimum>=diff)
127 second_minimum=minimum;
128 minimum=diff;
129 sec_trig=trig;
130 trig=t;
132 else if(second_minimum>=diff)
134 second_minimum=diff;
135 sec_trig=t;
137 if( diff < REJECT_FACTOR_DIFF )
138 got_count++;
139 kDebug() << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <<t->voicecode() << ech << " : " << diff;
142 // double ecart_relatif=(second_minimum-minimum)/minimum;
144 // kDebug() << ecart_relatif;
146 if(trig)
147 kDebug() << "**** " << trig->voicecode() << " : " << minimum;
150 // if(trig && ecart_relatif > REJECT_FACTOR_ECART_REL)
151 // if(trig && got_count==1)
152 bool selected=trig && (got_count==1 || ( minimum < 1.5*REJECT_FACTOR_DIFF && trig==sec_trig ) );
154 if(selected)
156 trig->handle_Voice();
162 /*bool Voice::x11Event( XEvent* pEvent )
164 if( pEvent->type != XKeyPress && pEvent->type != XKeyRelease )
165 return false;
167 KKeyNative keyNative( pEvent );
169 //kDebug() << keyNative.key().toString();
171 if(_shortcut.contains(keyNative))
173 if(pEvent->type == XKeyPress && !_recording )
175 record_start();
176 return true;
178 if(pEvent->type == XKeyRelease && _recording )
180 record_stop();
181 return true;
184 return false;
191 void Voice::set_shortcut( const KShortcut &shortcut)
193 _shortcut = shortcut;
194 if( !_enabled )
195 return;
196 if(!_kga)
198 _kga = new KAction(this);
199 _kga->setObjectName("khotkeys_voice");
200 connect(_kga,SIGNAL(triggered ( bool )) , this , SLOT(slot_key_pressed()));
202 _kga->setGlobalShortcut(shortcut);
205 void Voice::slot_key_pressed()
207 if( !haveArts())
208 return;
209 if( _recording )
210 record_stop();
211 else
213 record_start();
214 if(!_timer)
216 _timer=new QTimer(this);
217 connect(_timer, SIGNAL(timeout()) , this, SLOT(slot_timeout()));
219 _timer->setSingleShot(true);
220 _timer->start(1000*20);
225 void Voice::slot_timeout()
227 if(_recording && _recorder)
229 _recorder->abort();
230 _recording=false;
232 _timer->deleteLater();
233 _timer=0L;
237 QString Voice::isNewSoundFarEnough(const VoiceSignature& signature, const QString &currentTrigger)
239 Voice_trigger *trig=0L;
240 Voice_trigger *sec_trig=0L;
241 double minimum=800000;
242 double second_minimum=80000;
243 int got_count=0;
244 foreach (Voice_trigger *t , _references)
246 if(t->voicecode()==currentTrigger)
247 continue;
249 for(int ech=1; ech<=2 ; ech++)
251 double diff=VoiceSignature::diff(signature, t->voicesignature(ech));
252 if(minimum>=diff)
254 second_minimum=minimum;
255 minimum=diff;
256 sec_trig=trig;
257 trig=t;
259 else if(second_minimum>=diff)
261 second_minimum=diff;
262 sec_trig=t;
264 if( diff < REJECT_FACTOR_DIFF )
265 got_count++;
266 kDebug() << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <<t->voicecode() << ech << " : " << diff;
270 if(trig)
271 kDebug() << "**** " << trig->voicecode() << " : " << minimum;
273 bool selected=trig && ((got_count==1 && minimum < REJECT_FACTOR_DIFF*0.7 ) || ( minimum < REJECT_FACTOR_DIFF && trig==sec_trig ) );
274 return selected ? trig->voicecode() : QString();
277 bool Voice::doesVoiceCodeExists(const QString &vc)
279 foreach (Voice_trigger *t , _references)
281 if(t->voicecode()==vc)
282 return true;
284 return false;
287 } // namespace KHotKeys
289 #include "voices.moc"