/**************************************************************************** KHotKeys Copyright (C) 2005 Olivier Goffart Distributed under the terms of the GNU General Public License version 2. ****************************************************************************/ #include #include "voices.h" #include "voicesignature.h" #include "triggers.h" #include "soundrecorder.h" #include #include #include #include #include #include #include #include #include namespace KHotKeys { Voice* voice_handler; Voice::Voice( bool enabled_P, QObject* parent_P ) : QObject( parent_P) ,_enabled( enabled_P ), _recording( false ), _recorder(0) { assert( voice_handler == NULL ); voice_handler = this; _kga=0L; _timer=0L; kDebug() ; } Voice::~Voice() { kDebug() ; enable( false ); voice_handler = NULL; } void Voice::enable( bool enabled_P ) { #ifndef HAVE_ARTS enabled_P = false; // never enabled when there's no support #endif if( _enabled == enabled_P ) return; _enabled = enabled_P; _kga->setEnabled(enabled_P); } void Voice::register_handler( Voice_trigger *trigger_P ) { if( !_references.contains( trigger_P )) _references.append(trigger_P); } void Voice::unregister_handler( Voice_trigger *trigger_P ) { _references.remove(trigger_P); } void Voice::record_start() { kDebug() ; if(!_recorder) { _recorder= SoundRecorder::create(this); connect(_recorder, SIGNAL(recorded(Sound)), this, SLOT(slot_sound_recorded(Sound))); } _recorder->start(); _recording=true; } void Voice::record_stop() { if(!_recording) return; kDebug() ; delete _timer; _timer=0L; _recording=false; if(_recorder) _recorder->stop(); } void Voice::slot_sound_recorded(const Sound &sound_P) { VoiceSignature signature(sound_P); Voice_trigger *trig=0L; Voice_trigger *sec_trig=0L; double minimum=800000; double second_minimum=80000; int got_count=0; foreach(Voice_trigger *t, _references) { for(int ech=1; ech<=2 ; ech++) { double diff=VoiceSignature::diff(signature, t->voicesignature(ech)); if(minimum>=diff) { second_minimum=minimum; minimum=diff; sec_trig=trig; trig=t; } else if(second_minimum>=diff) { second_minimum=diff; sec_trig=t; } if( diff < REJECT_FACTOR_DIFF ) got_count++; kDebug() << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <voicecode() << ech << " : " << diff; } } // double ecart_relatif=(second_minimum-minimum)/minimum; // kDebug() << ecart_relatif; if(trig) kDebug() << "**** " << trig->voicecode() << " : " << minimum; // if(trig && ecart_relatif > REJECT_FACTOR_ECART_REL) // if(trig && got_count==1) bool selected=trig && (got_count==1 || ( minimum < 1.5*REJECT_FACTOR_DIFF && trig==sec_trig ) ); if(selected) { trig->handle_Voice(); } } /*bool Voice::x11Event( XEvent* pEvent ) { if( pEvent->type != XKeyPress && pEvent->type != XKeyRelease ) return false; KKeyNative keyNative( pEvent ); //kDebug() << keyNative.key().toString(); if(_shortcut.contains(keyNative)) { if(pEvent->type == XKeyPress && !_recording ) { record_start(); return true; } if(pEvent->type == XKeyRelease && _recording ) { record_stop(); return true; } } return false; } */ void Voice::set_shortcut( const KShortcut &shortcut) { _shortcut = shortcut; if( !_enabled ) return; if(!_kga) { _kga = new KAction(this); _kga->setObjectName("khotkeys_voice"); connect(_kga,SIGNAL(triggered(bool)) , this , SLOT(slot_key_pressed())); } _kga->setGlobalShortcut(shortcut); } void Voice::slot_key_pressed() { if( _recording ) record_stop(); else { record_start(); if(!_timer) { _timer=new QTimer(this); connect(_timer, SIGNAL(timeout()) , this, SLOT(slot_timeout())); } _timer->setSingleShot(true); _timer->start(1000*20); } } void Voice::slot_timeout() { if(_recording && _recorder) { _recorder->abort(); _recording=false; } _timer->deleteLater(); _timer=0L; } QString Voice::isNewSoundFarEnough(const VoiceSignature& signature, const QString ¤tTrigger) { Voice_trigger *trig=0L; Voice_trigger *sec_trig=0L; double minimum=800000; double second_minimum=80000; int got_count=0; foreach (Voice_trigger *t , _references) { if(t->voicecode()==currentTrigger) continue; for(int ech=1; ech<=2 ; ech++) { double diff=VoiceSignature::diff(signature, t->voicesignature(ech)); if(minimum>=diff) { second_minimum=minimum; minimum=diff; sec_trig=trig; trig=t; } else if(second_minimum>=diff) { second_minimum=diff; sec_trig=t; } if( diff < REJECT_FACTOR_DIFF ) got_count++; kDebug() << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <voicecode() << ech << " : " << diff; } } if(trig) kDebug() << "**** " << trig->voicecode() << " : " << minimum; bool selected=trig && ((got_count==1 && minimum < REJECT_FACTOR_DIFF*0.7 ) || ( minimum < REJECT_FACTOR_DIFF && trig==sec_trig ) ); return selected ? trig->voicecode() : QString(); } bool Voice::doesVoiceCodeExists(const QString &vc) { foreach (Voice_trigger *t , _references) { if(t->voicecode()==vc) return true; } return false; } } // namespace KHotKeys #include "moc_voices.cpp"