This commit is contained in:
CroneKorkN 2025-06-01 13:06:43 +02:00
parent 98b15597bc
commit a363d12c61
Signed by: cronekorkn
SSH key fingerprint: SHA256:v0410ZKfuO1QHdgKBsdQNF64xmTxOF8osF1LIqwTcVw
2 changed files with 40 additions and 26 deletions

52
process
View file

@ -6,14 +6,19 @@ import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import soundfile import soundfile
import scipy.signal import scipy.signal
from scipy.fft import fft, fftfreq from scipy.fft import rfft, rfftfreq
import shutil import shutil
RECORDINGS_DIR = "recordings" RECORDINGS_DIR = "recordings"
PROCESSED_RECORDINGS_DIR = "recordings/processed" PROCESSED_RECORDINGS_DIR = "recordings/processed"
DETECTIONS_DIR = "events" 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 CLIP_SECONDS = 3
THRESHOLD_BASE = 0.1 THRESHOLD_BASE = 0.1
OCTAVE_FACTOR = 0.1 OCTAVE_FACTOR = 0.1
@ -21,31 +26,50 @@ CLIP_PADDING_BEFORE = 1
CLIP_PADDING_AFTER = 6 CLIP_PADDING_AFTER = 6
def process_chunk(filename): def process_recording(filename):
print('processing', 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) path = os.path.join(RECORDINGS_DIR, filename)
info = soundfile.info(path) info = soundfile.info(path)
samplerate = info.samplerate samplerate = info.samplerate
blocksize = int(CLIP_SECONDS * 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))): for num, block in enumerate(soundfile.blocks(path, blocksize=blocksize, overlap=int(blocksize*0.8))):
strengths = fft(block) complex_amplitudes = rfft(block)
labels = fftfreq(len(block), d=1/samplerate) amplitudes = np.abs(complex_amplitudes)
# get the frequency with the highest strength labels = rfftfreq(len(block), d=1/samplerate)
max_freq = labels[np.argmax(np.abs(strengths))]
# 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: 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(): def main():
os.makedirs(RECORDINGS_DIR, exist_ok=True) os.makedirs(RECORDINGS_DIR, exist_ok=True)
os.makedirs(PROCESSED_RECORDINGS_DIR, exist_ok=True) os.makedirs(PROCESSED_RECORDINGS_DIR, exist_ok=True)
for file in os.listdir(RECORDINGS_DIR): for filename in os.listdir(RECORDINGS_DIR):
if file.endswith(".flac"): if filename.endswith(".flac"):
process_chunk(file) process_recording(filename)
if __name__ == "__main__": if __name__ == "__main__":

14
record
View file

@ -5,20 +5,10 @@ mkdir -p recordings
while true while true
do do
# get date in ISO 8601 format with nanoseconds # get date in ISO 8601 format with nanoseconds
PROGRAMM=$(test $(uname) = "Darwin" && echo "gdate" || echo "date")
OS=$(uname) DATE=$($PROGRAMM "+%Y-%m-%d_%H-%M-%S.%6N%z")
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
# record audio using ffmpeg # record audio using ffmpeg
ffmpeg \ ffmpeg \
-y \ -y \
-f pulse \ -f pulse \