LookupWord always returns an empty string
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)
}
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 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 ;)
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?