Skip to content
Snippets Groups Projects
slu.py 4.89 KiB
Newer Older
  • Learn to ignore specific revisions
  • Benoit Favre's avatar
    Benoit Favre committed
    from gi.repository import GObject, GLib
    import threading
    
    Benoit Favre's avatar
    Benoit Favre committed
    from ctypes import *
    
    _backend = None
    
    Benoit Favre's avatar
    Benoit Favre committed
    _semaphore = None
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    class SLU:
        #/src.new/rocio_slu -word "$prefix"_dico_word.txt -action "$prefix"_dico_action.txt -fstmodel "$prefix".fst -fstclean "$prefix"_clean_tail.fst
    
        def __init__(self, word_lexicon, action_lexicon, model_fst, cleaner_fst, action_history, library='asr/tools/slu/src/librocio_slu.so'):
    
    Benoit Favre's avatar
    Benoit Favre committed
            global _backend, _semaphore
    
    Benoit Favre's avatar
    Benoit Favre committed
            if _backend == None:
                _backend = cdll.LoadLibrary(library)
    
                # slu_t* init_slu(char* chfileword, char* chfileaction, char* chfilemodel, char* chfileclean);
                _backend.init_slu.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p]
                _backend.init_slu.restype = c_void_p
    
    
                # int run_slu(slu_t* slu, char** words, int num_words, int prevn, char* prevword);
    
                _backend.run_slu.argtypes = [c_void_p, POINTER(c_char_p), c_int, c_int, c_char_p]
    
                _backend.run_slu.restype = c_void_p # c_char_p with manual memory management
    
    Benoit Favre's avatar
    Benoit Favre committed
    
                # int num_actions(slu_t* slu)
                _backend.num_actions.argtypes = [c_void_p]
                _backend.num_actions.restype = c_int
                
    
                # int get_actions(slu_t* slu)
                _backend.get_actions.argtypes = [c_void_p]
                _backend.get_actions.restype = c_void_p
    
    
    Benoit Favre's avatar
    Benoit Favre committed
                # int get_action(slu_t* slu, int index)
                _backend.get_action.argtypes = [c_void_p, c_int]
                _backend.get_action.restype = c_char_p
    
    
                # void reset_slu(slu_t* slu);
                _backend.reset_slu.argtypes = [c_void_p]
                _backend.reset_slu.restype = None
    
    
    Benoit Favre's avatar
    Benoit Favre committed
                # void free_slu(slu_t* slu);
                _backend.free_slu.argtypes = [c_void_p]
                _backend.free_slu.restype = None
    
    
                # void free(void*)  from libc
                _backend.free.argtypes = [c_void_p]
                _backend.free.restype = None
    
    
    Benoit Favre's avatar
    Benoit Favre committed
                _semaphore = threading.Semaphore()
    
            self.load_action_history(action_history)
    
    Benoit Favre's avatar
    Benoit Favre committed
            _semaphore.acquire()
            thread = threading.Thread(target=self._init_thread, args=[word_lexicon, action_lexicon, model_fst, cleaner_fst])
            thread.daemon = True
            thread.start()
    
    
        def load_action_history(self, action_history):
            self.action_history = []
            with open(action_history) as fp:
                for line in fp:
    
                    if line.strip() != '':
                        action, history = line.strip().split('\t')
                        if not('#ENDSEQUENCE' in action or '#ENDSECTION' in action):
                            self.action_history.append([action, history])
    
    
        def get_action_history(self, action_num):
    
            if action_num < 0 or action_num >= len(self.action_history):
                print 'WARNING: no action history for %d' % action_num
                return ''
    
            return self.action_history[action_num][1]
    
    
    Benoit Favre's avatar
    Benoit Favre committed
        def _init_thread(self, word_lexicon, action_lexicon, model_fst, cleaner_fst):
            global _backend, _semaphore
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.slu = _backend.init_slu(word_lexicon, action_lexicon, model_fst, cleaner_fst)
    
    Benoit Favre's avatar
    Benoit Favre committed
            _semaphore.release()
    
    
        def process(self, words, old_words, callback, async=True):
            if async:
                thread = threading.Thread(target=self._process_thread, args=[words, old_words, callback])
                thread.daemon = True
                thread.start()
            else:
                self._process_thread(words, old_words, callback)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    
        def _process_thread(self, words, old_words, callback):
    
    Benoit Favre's avatar
    Benoit Favre committed
            global _backend, _semaphore
    
    Benoit Favre's avatar
    Benoit Favre committed
            c_words = (c_char_p * len(words))(*words)
    
    Benoit Favre's avatar
    Benoit Favre committed
            _semaphore.acquire()
    
            c_output = _backend.run_slu(self.slu, c_words, len(words), -1, old_words)
    
    Benoit Favre's avatar
    Benoit Favre committed
            _semaphore.release()
    
            output = str(cast(c_output, c_char_p).value)
    
            _backend.free(c_output)
    
    Benoit Favre's avatar
    Benoit Favre committed
            GLib.idle_add(callback, self, output)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
        def num_actions(self):
    
    Benoit Favre's avatar
    Benoit Favre committed
            global _backend, _semaphore
            output = _backend.num_actions(self.slu)
            return output
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    
        def get_actions(self):
            global _backend, _semaphore
            c_output = _backend.get_actions(self.slu)
            output = cast(c_output, c_char_p).value
            _backend.free(c_output)
            return output
    
    
    Benoit Favre's avatar
    Benoit Favre committed
        def get_action(self, index):
    
    Benoit Favre's avatar
    Benoit Favre committed
            global _backend, _semaphore
            output = _backend.get_action(self.slu, index)
            return output
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    
        def reset_slu(self):
            global _backend, _semaphore
            _semaphore.acquire()
            _backend.reset_slu(self.slu)
            _semaphore.release()
    
    
    Benoit Favre's avatar
    Benoit Favre committed
        def shutdown(self):
    
    Benoit Favre's avatar
    Benoit Favre committed
            global _backend, _semaphore
    
    Benoit Favre's avatar
    Benoit Favre committed
            _backend.free_slu(self.slu)
    
    if __name__ == '__main__':
    
        prefix = 'tools/slu/automate/homeostasis_25nov_%s'
    
    Benoit Favre's avatar
    Benoit Favre committed
        slu = SLU(prefix % 'dico_word.txt', prefix % 'dico_action.txt', prefix % 'section6.fst', prefix % 'clean_tail.fst')
    
        #print 'before'
    
        slu.process(open('tools/slu/homeostasis_25nov.asr/sect6.ref').read().strip().split(), lambda x: sys.stdout.write('%s\n' % x))
    
        #print 'after'
    
    Benoit Favre's avatar
    Benoit Favre committed
        slu.shutdown()