!7 sclass Analyzer { static int baseSize = 1024; S word1, word2; Rect rect; // in baseSize*baseSize float threshold; S analyze(BWImage img) { Rect r = rescaleRect(rect, baseSize, baseSize, img.getWidth(), img.getHeight()); double b = clipBWImage(img, r).averageBrightness(); //print(r + " => " + b); ret b >= threshold ? word1 : word2; } } static LPair images = new L; sS word1 = "yes", word2 = "no"; p-exp { L files = audioRecordingsWithSingleClip(); for (File f : allRecordings()) { S word = wordFromAudioFileName(f); if (!eqicOneOf(word, word1, word2)) continue; images.add(pair(word, bwAutoContrast(audio_clipFromLastEntryPoint(audioFileToFrequencyImage(f))))); print(fileName(f)); } showImage(second(random(images))); findBestAnalyzer(); } svoid findBestAnalyzer { final new Best best; final new AIStrategy_RandomWithVariation strategy; strategy.random = func -> Analyzer { randomAnalyzer() }; strategy.submit = func(final Analyzer a) -> double { new Scorer scorer; for (Pair img : images) scorer.add(eqic(img.a, a.analyze(img.b))); if (best.put(a, scorer!)) print(scorer + " / " + struct(a)); ret scorer!; }; thread { while licensed { strategy.go(); } } } static Analyzer randomAnalyzer() { bool flip = tossCoin(); ret nu(Analyzer, word1 := flip ? word1 : word2, word2 := flip ? word2 : word1, rect := randomRect(Analyzer.baseSize, Analyzer.baseSize), threshold := randomFloat()); }