!7 cmodule ListenOnNoise > DynPrintLogAndEnabled { switchable double threshold = 50; // volume percentage switchable double minDurationAfterNoise = 1.5; // seconds switchable double maxDuration = 10.0; // seconds switchable bool verbose; transient float lastVolume; transient long lastNoise; // in sysNow time JPanel makeControlArea() { ret centerAndEastWithMargin( centerAndEastWithMargin( dm_calculatedLabel(() -> "Threshold: " + formatDouble(threshold, 1) + "%"), jPopDownButton_noText("Set threshold...", r { dm_doubleFieldSetterDialog threshold() })), super.makeControlArea()); } start { dm_watchField enabled(r { if (!enabled) dm_call(dm_quickAudioRecordModuleOpt(), 'stopRecording); }); dm_addAudioListener(voidfunc(short[] data) enter { if (!enabled) ret; if (verbose) printWithTime("Got audio data"); // Quickly calculate the volume float vol = shortSamplesToPercentVolume(data); short[] clonedBuf = vol >= threshold && lastVolume < threshold ? cloneShortArray(data) : null; dm_q(r { S recorder = dm_quickAudioRecordModuleOpt(); long recordingSince = cast dm_call(recorder, 'recordingSince); bool noise = vol >= threshold; bool isRecording = recordingSince != 0; if (noise) lastNoise = sysNow(); if (isRecording) { // stop if max duration reached or no recent noise if (elapsedSeconds(recordingSince) >= maxDuration || elapsedSeconds(lastNoise) > minDurationAfterNoise) { print("Stopping"); dm_call(recorder, 'stopRecording); } } else { // start recording if (noise) { sleep(10); // avoid audio listener race condition print("Starting"); dm_call(recorder, 'startRecording, clonedBuf); } } }); }); } }