/**************************************************************************** KHotKeys Copyright (C) 2005 Olivier Goffart Distributed under the terms of the GNU General Public License version 2. ****************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "voices.h" #include "voicesignature.h" #include "triggers.h" #include "soundrecorder.h" #include #include #include #include #include #include #include #include #include #include #include namespace KHotKeys { Voice* voice_handler; Voice::Voice( bool enabled_P, TQObject* parent_P ) : TQObject( parent_P) ,_enabled( enabled_P ), _recording( false ), _recorder(0) { assert( voice_handler == NULL ); voice_handler = this; _kga=0L; _timer=0L; kdDebug(1217) << k_funcinfo << endl; } Voice::~Voice() { kdDebug(1217) << k_funcinfo << endl; 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; if( _enabled ) // activate the shortcut set_shortcut( _shortcut ); else { delete _kga; _kga = NULL; } } void Voice::register_handler( Voice_trigger *trigger_P ) { if( !_references.tqcontains( trigger_P )) _references.append(trigger_P); } void Voice::unregister_handler( Voice_trigger *trigger_P ) { _references.remove(trigger_P); } void Voice::record_start() { kdDebug(1217) << k_funcinfo << endl; if(!_recorder) { _recorder= SoundRecorder::create(this); connect(_recorder, TQT_SIGNAL(recorded(const Sound& )), this, TQT_SLOT(slot_sound_recorded(const Sound& ))); } _recorder->start(); _recording=true; } void Voice::record_stop() { if(!_recording) return; kdDebug(1217) << k_funcinfo << endl; 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; TQValueList::Iterator it; for ( it = _references.begin(); it != _references.end(); ++it ) { for(int ech=1; ech<=2 ; ech++) { Voice_trigger *t=*it; 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++; kdDebug(1217) << k_funcinfo << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <voicecode() << ech << " : " << diff << endl; } } // double ecart_relatif=(second_minimum-minimum)/minimum; // kdDebug(1217) << k_funcinfo << ecart_relatif << endl; if(trig) kdDebug(1217) << k_funcinfo << "**** " << trig->voicecode() << " : " << minimum << endl; // 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 ); //kdDebug(1217) << k_funcinfo << keyNative.key().toString() << endl; if(_shortcut.tqcontains(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 KGlobalAccel( this ); _kga->remove("voice"); _kga->insert( "voice", i18n("Voice"), TQString::null, shortcut, 0, this, TQT_SLOT(slot_key_pressed())) ; _kga->updateConnections(); } void Voice::slot_key_pressed() { if( !haveArts()) return; if( _recording ) record_stop(); else { record_start(); if(!_timer) { _timer=new TQTimer(this); connect(_timer, TQT_SIGNAL(timeout()) , this, TQT_SLOT(slot_timeout())); } _timer->start(1000*20,true); } } void Voice::slot_timeout() { if(_recording && _recorder) { _recorder->abort(); _recording=false; } _timer->deleteLater(); _timer=0L; } TQString Voice::isNewSoundFarEnough(const VoiceSignature& signature, const TQString ¤tTrigger) { Voice_trigger *trig=0L; Voice_trigger *sec_trig=0L; double minimum=800000; double second_minimum=80000; int got_count=0; TQValueList::Iterator it; for ( it = _references.begin(); it != _references.end(); ++it ) { Voice_trigger *t=*it; 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++; kdDebug(1217) << k_funcinfo << ( (diff < REJECT_FACTOR_DIFF) ? "+++" : "---" ) <voicecode() << ech << " : " << diff << endl; } } if(trig) kdDebug(1217) << k_funcinfo << "**** " << trig->voicecode() << " : " << minimum << endl; bool selected=trig && ((got_count==1 && minimum < REJECT_FACTOR_DIFF*0.7 ) || ( minimum < REJECT_FACTOR_DIFF && trig==sec_trig ) ); return selected ? trig->voicecode() : TQString::null; } bool Voice::doesVoiceCodeExists(const TQString &vc) { TQValueList::Iterator it; for ( it = _references.begin(); it != _references.end(); ++it ) { Voice_trigger *t=*it; if(t->voicecode()==vc) return true; } return false; } } // namespace KHotKeys #include "voices.moc"