!7 cmodule SpeechCorrelator1 > DynPrintLog { switchable bool react; // react to new recording long audioReceived; // timestamp S startTime /*, endTime*/; switchable int correlationTimeout = 100; switchable S actionWhenCorrelated; // however we interpret this new L interpretations_raw; transient L interpretations; //Interpretation bestInterpretation; transient new RestartableCountdown countdown; srecord Interpretation(S text, S info, long received) {} start { ownResource(countdown); interpretations = dm_synchroList(interpretations_raw); dm_registerAs_direct speechCorrelator(); dm_vmBus_answerToMessage dontApplyRecognizedSpeech(() -> react); dm_onNewRecording(voidfunc(File f) enter { if (!react) ret; print("Have WAV: " + f); //print(renderFileDateWithSeconds(f)); setStartTime(extractYMDminusHMS(fileName(f))); triggerSpeechRecognitions("wav", f); }); dm_vmBus_onMessage_q newMP3Recording(voidfunc(File f) enter { print("Have MP3: " + f); setStartTime(extractYMDminusHMS(fileName(f))); triggerSpeechRecognitions("mp3", f); }); dm_vmBus_onMessage_q speechRecognized_raw(voidfunc(Map map) enter{ // module := module(), +info, +text, audioFile := f) File f = cast map.get("audioFile"); S date = f == null ? ymdMinusHms() : extractYMDminusHMS(fileName(f)); if (f == null) setStartTime(date); // e.g. for Chrome recognizer if (!eq(date, startTime)) ret with print("Ignoring speech result for time " + date); Interpretation i; interpretations.add(i = nu Interpretation( text := map.get("text"), info := map.get("info"), received := now()-audioReceived )); printWithMillis("New interpretation (total: " + l(interpretations) + "): " + i); }); } visual centerAndSouthWithMargins(super, westCenterAndEastWithMargin( withLabel("Correlation timeout:", jMinWidth(75, dm_textIntField correlationTimeout())), dm_textFieldWithLabel actionWhenCorrelated(), dm_checkBox react())); // unused. type = "mp3" or "wav" void triggerSpeechRecognitions(S type, File audioFile) { } void setStartTime(S startTime) { if (setField(+startTime)) { print(+startTime); setField(audioReceived := now()); clear(interpretations); // TODO: Fire existing one? countdown.start(correlationTimeout, r fireCorrelation); } } swappable Interpretation chooseInterpretation() { ret first(interpretations); } void fireCorrelation enter { Interpretation i = chooseInterpretation(); if (i != null) { printWithMillis("Speech correlated: " + i.text); vmBus_send speechCorrelated(module(), startTime, i.text); } } }