I have a very strange issue. My code below works just fine when I run it via the command line but it crashes (around ps_init(config) I believe) when I double-click the executable with my mouse pointer or try to run the code inside of a Qt application. I'm running this on a Raspberry Pi 3. Can anyone tell me what is wrong?
// Libraries for speech decoding#include<iostream>#include<unordered_map>#include<ctime>#include<string>#include<pocketsphinx.h>#include<sphinxbase/ad.h>#include<sphinxbase/err.h>// Libraries for running system commands#include<stdlib.h>// We use these libraries to create background timers#include<chrono>#include<future>#include<thread>#include<mutex>usingnamespacestd;#define AUDIO_BUFFER_SIZE 4096#define INPUT_WAIT_TIME_SEC 5#define KEY_PHRASE "HEY JEEVES"#define COMMAND_BEGIN_CUE (system("aplay -D plughw:0,0 /home/pi/Speech_Recognition/Sound_Effects/Beep_Init.wav"))#define COMMAND_END_CUE (system("aplay -D plughw:0,0 /home/pi/Speech_Recognition/Sound_Effects/Beep_ACK.wav"))#define COMMAND_TIMEOUT_CUE (system("aplay -D plughw:0,0 /home/pi/Speech_Recognition/Sound_Effects/Beep_NACK.wav"))stringrecognize_from_microphone();inlinevoidbackground_timer();boolreadTimeOut();inlinevoidspeak(conststring&speech);booltimeout=false;mutextimeout_flag_mutex;typedefvoid(*Action)(void);// function pointer typetypedefstringCommand;typedefunordered_map<Command,Action>CommandActionMap;ps_decoder_t*ps;// create pocketsphinx decoder structurecmd_ln_t*config;// create configuration structuread_rec_t*ad;// create audio recording structure - for use with ALSA functionsint16adbuf[AUDIO_BUFFER_SIZE];// buffer array to hold audio datauint8utt_started,in_speech;// flags for tracking active speech - has speech started? - is speech currently happening?int32k;// holds the number of frames in the audio buffercharconst*hyp;// pointer to "hypothesis" (best guess at the decoded result)conststringempty_string=string();// Command actions beginstaticvoidintroduction(){stringspeech="Hello. I am Jeeves, your personal assistant.";speak(speech);return;}// End of Command actionsintmain(intargc,char*argv[]){// Initialize command/action dictionaryCommandActionMapcommandActions={{"INTRODUCE YOURSELF",&introduction}};COMMAND_BEGIN_CUE;// Initialize speech to text engineconfig=cmd_ln_init(NULL,ps_args(),TRUE,// Load the configuration structure - ps_args() passes the default values"-hmm","/usr/local/share/pocketsphinx/model/en-us/en-us",// path to the standard english language model"-lm","/home/pi/Speech_Recognition/Custom_Models/7221.lm",// custom language model (file must be present)"-dict","/home/pi/Speech_Recognition/Custom_Models/7221.dic",// custom dictionary (file must be present)"-remove_noise","yes",// filter background noise"-logfn","/dev/null",// suppress log info from being sent to screenNULL);ps=ps_init(config);// initialize the pocketsphinx decoderad=ad_open_dev("sysdefault",(int)cmd_ln_float32_r(config,"-samprate"));// open default microphone (plughw:0,0) at default sampleratewhile(1){timeout_flag_mutex.lock();timeout=false;timeout_flag_mutex.unlock();stringdecoded_speech=recognize_from_microphone();// call the function to capture and decode speech cout<<"Decoded Speech: "<<decoded_speech<<"\n"<<endl;// send decoded speech to screenif(decoded_speech.compare(KEY_PHRASE)==0){autofuture=async(background_timer);// start a background timer to cancel command listening if no speech detectedcout<<"Key phrase "<<KEY_PHRASE<<" detected; waiting for additional input..."<<endl;COMMAND_BEGIN_CUE;// cue command ready sound effectstringdecoded_command=recognize_from_microphone();// call the function to capture and decode commandsif(decoded_command.compare(empty_string)!=0){COMMAND_END_CUE;cout<<"Decoded Command: "<<decoded_command<<"\n"<<endl;// send decoded command to screen// Parse the command and find associated action if it existsautoiter=commandActions.find(decoded_command);if(iter==commandActions.end()){// not foundspeak("I'm sorry, I did not recognize that command.");}else{(*iter->second)();}}}}COMMAND_END_CUE;ad_close(ad);// close the microphone}stringrecognize_from_microphone(){ad_start_rec(ad);// start recordingps_start_utt(ps);// mark the start of the utteranceutt_started=FALSE;// clear the utt_started flagwhile(!readTimeOut()||utt_started){k=ad_read(ad,adbuf,AUDIO_BUFFER_SIZE);// capture the number of frames in the audio bufferps_process_raw(ps,adbuf,k,FALSE,FALSE);// send the audio buffer to the pocketsphinx decoderin_speech=ps_get_in_speech(ps);// test to see if speech is being detectedif(in_speech&&!utt_started){// if speech has started and utt_started flag is false utt_started=TRUE;// then set the flag}if(!in_speech&&utt_started){// if speech has ended and the utt_started flag is true ps_end_utt(ps);// then mark the end of the utterancead_stop_rec(ad);// stop recordinghyp=ps_get_hyp(ps,NULL);// query pocketsphinx for "hypothesis" of decoded statementreturnhyp;// the function returns the hypothesisbreak;// exit the while loop and return to main}}COMMAND_TIMEOUT_CUE;// cue command timeout sound effectcout<<"Command timeout..."<<endl;returnempty_string;}voidbackground_timer(){// Sleep for a period of time and then set the timeout flagthis_thread::sleep_for(chrono::seconds(INPUT_WAIT_TIME_SEC));timeout_flag_mutex.lock();timeout=true;timeout_flag_mutex.unlock();return;}boolreadTimeOut(){timeout_flag_mutex.lock();boolresult=timeout;timeout_flag_mutex.unlock();returntimeout;}voidspeak(conststring&speech){// Convert speech to .wav file and then call OS media playerstringcommand="pico2wave -w res.wav \"";command+=speech;command+="\" && aplay -D plughw:0,0 res.wav";system(command.c_str());return;}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Running it through gdb (via script so I could reproduce the behavior) it doesn't seem to technically crash. But it exits with code 01 when it calls ps_init().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think it has something to do with the environment variables. I know running from terminal versus double-clicking the executable changes the perspective. But, if I am correct, I don't know which environment variables ps_init() depends on.
Last edit: Justin 2018-01-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You have two pocketsphinx installations - old in /usr and new probably in /usr/local. You configured LD_LIBRARY_PATH to load new installation but just in terminal, not globally. Probably you added it to bash_profile but didn't relogin. So desktop software still uses old library.
You need to configure linker properly.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ah that would seem to be in the right direction, thank you! I had the program dump out the environment variables every time it runs.
When I type ./Jeeves in the terminal, the environment variable list shows LD_LIBRARY_PATH=/usr/local/lib as it should. But when I double click the Jeeves executable or try to run it via external qt app, the environment variable list no longer contains LD_LIBRARY_PATH so it probably is defaulting to the old stuff.
I have a very strange issue. My code below works just fine when I run it via the command line but it crashes (around ps_init(config) I believe) when I double-click the executable with my mouse pointer or try to run the code inside of a Qt application. I'm running this on a Raspberry Pi 3. Can anyone tell me what is wrong?
COMPILE CMD:
g++ -o Jeeves Jeeves.cpp 'pkg-config --cflags --libs pocketsphinx sphinxbase'
CODE:
You'd better provide a backtrace of the crash. You can collect it with gdb.
Running it through gdb (via script so I could reproduce the behavior) it doesn't seem to technically crash. But it exits with code 01 when it calls ps_init().
I think it has something to do with the environment variables. I know running from terminal versus double-clicking the executable changes the perspective. But, if I am correct, I don't know which environment variables ps_init() depends on.
Last edit: Justin 2018-01-26
I just tried running the program with my gdb script with the logs unsupressed and the last entry in the logs is this:
"FATAL: "cmn.c", line 126: Unknown CMN type 'batch'"
Can anyone tell me what's happening here?
I just tried running the program with my gdb script with the logs unsupressed and the last entry in the logs is this:
"FATAL: "cmn.c", line 126: Unknown CMN type 'batch'"
Can anyone tell me what's happening here?
You have two pocketsphinx installations - old in /usr and new probably in /usr/local. You configured LD_LIBRARY_PATH to load new installation but just in terminal, not globally. Probably you added it to bash_profile but didn't relogin. So desktop software still uses old library.
You need to configure linker properly.
Ah that would seem to be in the right direction, thank you! I had the program dump out the environment variables every time it runs.
When I type ./Jeeves in the terminal, the environment variable list shows LD_LIBRARY_PATH=/usr/local/lib as it should. But when I double click the Jeeves executable or try to run it via external qt app, the environment variable list no longer contains LD_LIBRARY_PATH so it probably is defaulting to the old stuff.
I tried adding this to /etc/bash.bashrc:
LD_LIBRARY_PATH="/usr/local/lib"
export LD_LIBRARY_PATH
PATH=$PATH:/usr/local/lib/
export PATH
Hoping it would set it globally but it seems it didn't work. How do I remedy this?
Edit /etc/ld.so.conf and run ldconfig
Thanks! Actually editing /etc/ld.so.conf on Raspbian didn't work. I tried this method here and it worked:
http://www.linuxforums.org/forum/ubuntu-linux/176983-solved-cannot-set-ld_library_path-profile-etc-profile.html
Thank you so much for your help!