!7 // TODO: pause while speaking module ListenOnNoise > DynPrintLogAndEnabled { double minLevel = 20; // percent double maxPause = 1; // pause allowed while we keep recording, seconds double minDuration = 0.6; // min seconds of complete recording to submit double maxDuration = 10; // always stop after this many seconds transient int interval = 100; transient long noiseSince, lastNoise; transient L buffer = synchroList(); start { dm_addAudioListener(voidfunc(short[] data) { if (noiseSince == 0) clear(buffer); buffer.add(cloneShortArray(data)); }); doEvery(interval, r { if (noiseSince != 0 && elapsedSeconds(noiseSince) >= maxDuration-0.05) { // too long, discard, maybe it's constant noise print("Recording too long (" + maxDuration + " s), discarding"); noiseSince = 0; clear(buffer); } float volume = dm_inputVolumeLevel(); //print("Volume: " + volume); if (volume >= minLevel) { // got noise lastNoise = sysNow(); if (noiseSince == 0) noiseSince = lastNoise; } else if (noiseSince != 0) { // got no noise, but am recording if (elapsedSeconds(lastNoise) > maxPause-0.05) { double duration = toSeconds(lastNoise-noiseSince+250); if (duration >= minDuration-0.05) { print("Keeping recording of " + formatDouble(duration, 1) + " seconds"); if (enabled) { L chunks = cloneList(buffer); // drop last silent chunks int len = lengthLevel2_shortArrays(chunks); int wantedLengthInSamples = iround(duration*44100*2); int dropped = 0; while (len-l(last(chunks)) >= wantedLengthInSamples) { len -= l(last(chunks)); popLast(chunks); ++dropped; } //print("Dropped " + n2(dropped, "chunk")); File wavFile = anonymousWAVEFile(); multiShortArraysToWAVE(chunks, wavFile); //printFileInfo(wavFile); vmBus_send('newRecording, wavFile); } } else print("Discarding recording of " + formatDouble(duration, 1) + " seconds"); noiseSince = 0; clear(buffer); } } }); } }