diff --git a/process b/process index 5e468e9..22d3832 100755 --- a/process +++ b/process @@ -6,14 +6,19 @@ import numpy as np import matplotlib.pyplot as plt import soundfile import scipy.signal -from scipy.fft import fft, fftfreq +from scipy.fft import rfft, rfftfreq import shutil RECORDINGS_DIR = "recordings" PROCESSED_RECORDINGS_DIR = "recordings/processed" DETECTIONS_DIR = "events" -DETECT_FREQUENCY_FROM = 208 -DETECT_FREQUENCY_TO = 214 + +DETECT_FREQUENCY = 211 +DETECT_FREQUENCY_TOLERANCE = 2 +DETECT_FREQUENCY_FROM = DETECT_FREQUENCY - DETECT_FREQUENCY_TOLERANCE +DETECT_FREQUENCY_TO = DETECT_FREQUENCY + DETECT_FREQUENCY_TOLERANCE +ADJACENCY_FACTOR = 2 + CLIP_SECONDS = 3 THRESHOLD_BASE = 0.1 OCTAVE_FACTOR = 0.1 @@ -21,31 +26,50 @@ CLIP_PADDING_BEFORE = 1 CLIP_PADDING_AFTER = 6 -def process_chunk(filename): +def process_recording(filename): print('processing', filename) + + # get ISO 8601 nanosecond recording date from filename + date_string_from_filename = os.path.splitext(filename)[0] + recording_date = datetime.datetime.strptime(date_string_from_filename, "%Y-%m-%d_%H-%M-%S.%f%z") + + # get samplerate and blocksize path = os.path.join(RECORDINGS_DIR, filename) info = soundfile.info(path) samplerate = info.samplerate blocksize = int(CLIP_SECONDS * samplerate) - print(info) - + # iterate blocks for num, block in enumerate(soundfile.blocks(path, blocksize=blocksize, overlap=int(blocksize*0.8))): - strengths = fft(block) - labels = fftfreq(len(block), d=1/samplerate) - # get the frequency with the highest strength - max_freq = labels[np.argmax(np.abs(strengths))] + complex_amplitudes = rfft(block) + amplitudes = np.abs(complex_amplitudes) + labels = rfftfreq(len(block), d=1/samplerate) + + # get amplitudes only between 100 and 1000 Hz + adjacent_amplitudes = amplitudes[(labels >= DETECT_FREQUENCY_FROM/ADJACENCY_FACTOR) & (labels <= DETECT_FREQUENCY_TO*ADJACENCY_FACTOR)] + adjacent_labels = labels[(labels >= DETECT_FREQUENCY_FROM/ADJACENCY_FACTOR) & (labels <= DETECT_FREQUENCY_TO*ADJACENCY_FACTOR)] + + # get the frequency with the highest amplitude + max_amplitude = max(adjacent_amplitudes) + max_amplitude_index = np.argmax(adjacent_amplitudes) + max_freq = adjacent_labels[max_amplitude_index] + if DETECT_FREQUENCY_FROM <= max_freq <= DETECT_FREQUENCY_TO: - print(f'{num}: {max_freq:.1f}') + print(f'{recording_date + datetime.timedelta(seconds=num * CLIP_SECONDS)}: {max_amplitude:.2f}rDB @ {max_freq:.2f}Hz') + breakpoint() + + + + def main(): os.makedirs(RECORDINGS_DIR, exist_ok=True) os.makedirs(PROCESSED_RECORDINGS_DIR, exist_ok=True) - for file in os.listdir(RECORDINGS_DIR): - if file.endswith(".flac"): - process_chunk(file) + for filename in os.listdir(RECORDINGS_DIR): + if filename.endswith(".flac"): + process_recording(filename) if __name__ == "__main__": diff --git a/record b/record index 7cad6a1..834d5d7 100755 --- a/record +++ b/record @@ -5,20 +5,10 @@ mkdir -p recordings while true do # get date in ISO 8601 format with nanoseconds - - OS=$(uname) - - if [ "$OS" = "Darwin" ]; then - DATE=$(gdate --iso-8601=ns) - elif [ "$OS" = "Linux" ]; then - DATE=$(date --iso-8601=ns) - else - echo "Unsupported OS: $OS" - exit 2 - fi + PROGRAMM=$(test $(uname) = "Darwin" && echo "gdate" || echo "date") + DATE=$($PROGRAMM "+%Y-%m-%d_%H-%M-%S.%6N%z") # record audio using ffmpeg - ffmpeg \ -y \ -f pulse \