Your approach seems very expensive. You are attempting to do things which seem both unnecessary and possibly problematic to do - though I am not an expert on Sphinx4
I have written an application which did exactly the same thing (except it listened for space instead of shift). My approach was completely different and, I think, pretty lightweight.
config.xml:
<component name="keyPressedSpeechClassifier"
type="package.KeyPressedSpeechClassifier">
</component>
<component name="epFrontEnd" type="edu.cmu.sphinx.frontend.FrontEnd">
<propertylist name="pipeline">
<item>microphone</item>
<item>speechClassifier</item>
<item>keyPressedSpeechClassifier</item>
<item>speechMarker</item>
<item>nonSpeechDataFilter</item>
<item>premphasizer</item>
<item>windower</item>
<item>fft</item>
<item>melFilterBank</item>
<item>dct</item>
<item>liveCMN</item>
<item>featureExtraction</item>
</propertylist>
</component>
KeyPressedSpeechClassifier:
public class KeyPressedSpeechClassifier extends BaseDataProcessor {
static KeyPressedSpeechClassifier _instance;
public static KeyPressedSpeechClassifier getInstance() {return _instance;}
LinkedList<Data> queue;
volatile boolean isRecognitionEnabled = false;
public KeyPressedSpeechClassifier() {
queue = new LinkedList<Data>();
_instance = this;
System.out.println("KeyPressedSpeechClassifier created");
}
@Override
public Data getData() throws DataProcessingException {
Data data = getPredecessor().getData();
if (data instanceof DoubleData) {
DoubleData dd = (DoubleData) data;
queue.push(new SpeechClassifiedData(dd, isRecognitionEnabled));
} else if (data instanceof SpeechClassifiedData) {
((SpeechClassifiedData) data).setSpeech(isRecognitionEnabled);
queue.push(data);
} else {
queue.push(data);
}
if (queue.isEmpty()) {
return null;
} else {
return queue.pop();
}
}
public void setRecognitionEnabled(boolean enabled) {
this.isRecognitionEnabled = enabled;
}
}