!7 module CorrectRecognizedSpeech > DynPrintLog { transient Map> corrections = syncCIMap(); bool autoCorrect = true, verbose; S switchableFields() { ret "autoCorrect verbose"; } start { ownResource(watchSpeechConfirmations_fromStart(voidfunc(S heard, S corrected) { MultiSet ms; synchronized(corrections) { ms = corrections.get(heard); if (ms == null) corrections.put(heard, ms = new MultiSet); } ms.add(corrected); if (verbose) print("Learned correction: " + heard + " => " + corrected); })); ownResource(onSpeechRecognized_withoutMyUtterancesAndTyped(voidfunc(fS s) enter { S corrected = getCorrection(s); if (nempty(corrected)) infoBox("Proposing correction: " + corrected); else if (verbose) print("No correction found for: " + s); })); } visualize { ret withRightAlignedButtons(super.visualize(), toolTip("Correct all recognized speech", dm_fieldCheckBox('autoCorrect)), "Show Corrections Database", rThread { showText("Speech Recognition Corrections", formatDoubleArrowMap(mapValues(corrections, f msMostPopularEntry))); }); } // API S getCorrection(S s) { ret l(s) < 2 ? null : msMostPopularEntry(corrections.get(s)); } S getAutoCorrection(S s) { ret autoCorrect ? getCorrection(s) : null; } }