pocketsphinx-go icon indicating copy to clipboard operation
pocketsphinx-go copied to clipboard

LookupWord always returns an empty string

Open agorman opened this issue 6 years ago • 3 comments

Maybe I'm just doing something wrong. I've confirmed the word is in the dictionary and included my code. I can process data and get a hypothesis so things seem to be working well.

# cat /usr/local/share/pocketsphinx/model/en-us/cmudict-en-us.dict |grep hello
hello HH AH L OW
hello(2) HH EH L OW
othello AH TH EH L OW
cfg := sphinx.NewConfig(
    sphinx.HMMDirOption("/usr/local/share/pocketsphinx/model/en-us/en-us"),
    sphinx.DictFileOption("/usr/local/share/pocketsphinx/model/en-us/cmudict-en-us.dict"),
    sphinx.LMFileOption("/usr/local/share/pocketsphinx/model/en-us/en-us.lm.bin"),
)

dec, err := sphinx.NewDecoder(cfg)
if err != nil {
    panic(err)
}
defer dec.Destroy()

w, ok := dec.LookupWord("hello")
if ok {
    fmt.Println(w)
}

agorman avatar Mar 20 '19 16:03 agorman

The problem is here https://github.com/xlab/pocketsphinx-go/blob/master/pocketsphinx/pocketsphinx.go#L143. It's not returning any elements from that *_Ctype_char.

I got it to work by changing to __v := C.GoString(__ret) and returning a string but I doubt you want to change the functions in pocketsphinx.

agorman avatar Mar 20 '19 17:03 agorman

@agorman the function returns []byte slice that is trimmed to zero length. Because we don't have its length really, and the generator cannot assume the length. It also cannot assume that char * is a string, i.e. is \x00 terminated.

Since you know that the resulting []byte is a string, you can convert it to string manually using this wrapper: https://github.com/xlab/pocketsphinx-go/blob/master/sphinx/helpers.go#L42, example:

// zero-length []byte, but pointing to valid memory
result := LookupWord(ps, word)

// cap word at 255 chars and convert from zero-terminated string into normal Go string
str := String(result[:255]).S()

pocketsphinx.go API is really low-level and is close to C code, but there is a higher-level package https://github.com/xlab/pocketsphinx-go/tree/master/sphinx to make it more usable for people. I think https://github.com/xlab/pocketsphinx-go/blob/master/sphinx/sphinx.go#L147 contains a bug where it converts zero-length []byte into a string like it's normal. Can be fixed with code above. Let me know if that works for you ;)

xlab avatar Mar 20 '19 18:03 xlab

Thanks, for the quick and detailed explanation. Here are the changes I made.

func (d *Decoder) LookupWord(word String) (string, bool) {
	phones := pocketsphinx.LookupWord(d.dec, word.S())
	if phones != nil {
		return String(phones[:255]).S(), true
	}
	return "", false
}

It almost works the way I'd expect. Now it's returning 1A at the end of each string. So for hello it returns HH AH L OW1A rather than HH AH L OW. Any ideas on why that might be?

agorman avatar Mar 20 '19 20:03 agorman