!7 module CorrectRecognizedSpeech > DynPrintLog { transient Map> corrections = syncCIMap(); bool autoCorrect = true; start { ownResource(watchStructureLog_fromStart(speechConfirmationLogFile(), voidfunc(O o) { if (o cast Map) { S heard = getString(o, 'heard), corrected = getString(o, 'corrected); if (empty(heard) || empty(corrected) || eqic(heard, corrected)) ret; MultiSet ms; synchronized(corrections) { ms = corrections.get(heard); if (ms == null) corrections.put(heard, ms = new MultiSet); } ms.add(corrected); } })); ownResource(onSpeechRecognized_withoutMyUtterancesAndTyped(voidfunc(fS s) enter { S corrected = getCorrection(s); if (nempty(corrected)) infoBox("Proposing correction: " + corrected); })); } visualize { ret withRightAlignedButtons(super.visualize(), dm_fieldCheckBox('autoCorrect), "Show Corrections Database", rThread { showText("Speech Recognition Corrections", formatDoubleArrowMap(mapValues(corrections, f msMostPopularEntry))); }); } // API S getCorrection(S s) { ret msMostPopularEntry(corrections.get(s)); } S getAutoCorrection(S s) { ret autoCorrect ? getCorrection(s) : null; } }