Skip to content

[OPTIMIZATION] recorder v2 #6

Description

@MarcoRavich

Since we've introduced some complexities (exFAT+ available space + audio device dynamic probing), semplifications/optimizations of the script code are needed.

1st attempt (deepseek):

#!/bin/sh
#
# (updated warranty formula)

MNT=/tmp/mnt
recorder=""

trap 'true' SIGHUP
trap 'cleanup' SIGTERM

cleanup() {
    [ -n "$recorder" ] && kill $recorder 2>/dev/null
    umount -l "$MNT" 2>/dev/null
    exit
}

sleep infinity &
dummy=$!

while true; do
    [ -n "$recorder" ] && wait $recorder || wait $dummy
    
    # Check for audio card
    card=$(arecord -l | grep '^card') || continue
    
    # Find single exFAT partition
    disk=$(lsblk -o NAME,FSTYPE -nr | awk '$2=="exfat"{print "/dev/"$1}' | head -1)
    [ -e "$disk" ] || continue
    
    # Cleanup if recorder died
    if [ -n "$recorder" ] && [ ! -e "/proc/$recorder" ]; then
        recorder=""
        umount -l "$MNT"
    fi
    
    # Skip if already recording
    [ -n "$recorder" ] && continue
    
    # Mount disk
    mkdir -p "$MNT"
    mount "$disk" "$MNT" || continue
    
    # Check disk space (minimum 100MB)
    avail_mb=$(df -m "$MNT" | awk 'NR==2 {print $4}')
    [ "$avail_mb" -gt 100 ] || {
        umount -l "$MNT"
        sleep 5
        continue
    }
    
    # Generate unique filename
    name=$(date +%s)
    logfile="${MNT}/${name}.log"
    [ -e "$logfile" ] && { sleep 1; continue; }
    
    # Audio device probing
    device_info=$(arecord -l | awk '/List of CAPTURE/,/^$/')
    card=$(echo "$device_info" | awk -F: '/card [0-9]/{split($1,a," "); print a[2]}')
    device=$(echo "$device_info" | awk -F: '/device [0-9]/{split($1,a," "); print a[2]}')
    [ -z "$card" ] || [ -z "$device" ] && continue
    
    inputhw="${card},${device}"
    arecord_output=$(arecord -D "hw:$inputhw" --dump-hw-params 2>&1)
    
    max_channels=$(echo "$arecord_output" | awk -F'[][]' '/CHANNELS:/{print $2}' | awk '{print $NF}')
    bitformat=$(echo "$arecord_output" | awk '/^FORMAT:/{print $NF}')
    buffer_time_max=$(echo "$arecord_output" | awk -F'[][]' '/BUFFER_TIME:/{print $2}' | awk '{print $NF}')
    buffer_size_max=$(echo "$arecord_output" | awk -F'[][]' '/BUFFER_SIZE:/{print $2}' | awk '{print $NF}')
    max_rate=$(echo "$arecord_output" | awk -F'[][]' '/RATE:/{print $2}' | awk '{print $NF}')
    [ "$max_rate" -gt 48000 ] && max_rate=48000
    
    # Start recording
    filename="${name}_${max_channels}-${max_rate}-${bitformat}"
    arecord -D "hw:$inputhw" \
        -c "$max_channels" \
        -t raw \
        -f "$bitformat" \
        -r "$max_rate" \
        --buffer-time="$buffer_time_max" \
        --buffer-size="$buffer_size_max" \
        > "${MNT}/${filename}.raw" 2> >(ts -s >&2) &
    
    recorder=$!
done

GH-Copilot further (style) refinements:

#!/bin/sh

MNT=/tmp/mnt
recorder=""

trap ':' SIGHUP
trap cleanup SIGTERM

cleanup() {
    [ -n "$recorder" ] && kill "$recorder" 2>/dev/null
    umount -l "$MNT" 2>/dev/null
    exit
}

sleep infinity &
dummy=$!

while :; do
    if [ -n "$recorder" ]; then
        wait "$recorder"
    else
        wait "$dummy"
    fi

    # Check for audio card and exFAT disk
    card=$(arecord -l | grep '^card') || continue
    disk=$(lsblk -o NAME,FSTYPE -nr | awk '$2=="exfat"{print "/dev/"$1; exit}')
    [ -n "$disk" ] && [ -e "$disk" ] || continue

    # Cleanup if recorder died
    [ -n "$recorder" ] && ! kill -0 "$recorder" 2>/dev/null && {
        recorder=""
        umount -l "$MNT"
    }

    [ -n "$recorder" ] && continue

    mkdir -p "$MNT"
    mount "$disk" "$MNT" || continue

    avail_mb=$(df -Pm "$MNT" | awk 'NR==2{print $4}')
    [ "${avail_mb:-0}" -gt 100 ] || {
        umount -l "$MNT"
        sleep 5
        continue
    }

    name=$(date +%s)
    logfile="$MNT/$name.log"
    [ -e "$logfile" ] && name="$name-$$" # fallback to PID if collision (rare)
    logfile="$MNT/$name.log"

    # Audio device probing
    device_info=$(arecord -l | awk '/List of CAPTURE/,/^$/')
    cardnum=$(echo "$device_info" | awk -F: '/card [0-9]/{split($1,a," "); print a[2]}' | head -1)
    devnum=$(echo "$device_info" | awk -F: '/device [0-9]/{split($1,a," "); print a[2]}' | head -1)
    [ -n "$cardnum" ] && [ -n "$devnum" ] || continue

    inputhw="$cardnum,$devnum"
    arecord_output=$(arecord -D "hw:$inputhw" --dump-hw-params 2>&1)

    max_channels=$(echo "$arecord_output" | awk -F'[][]' '/CHANNELS:/{print $2}' | awk '{print $NF}')
    bitformat=$(echo "$arecord_output" | awk '/^FORMAT:/{print $NF}')
    buffer_time_max=$(echo "$arecord_output" | awk -F'[][]' '/BUFFER_TIME:/{print $2}' | awk '{print $NF}')
    buffer_size_max=$(echo "$arecord_output" | awk -F'[][]' '/BUFFER_SIZE:/{print $2}' | awk '{print $NF}')
    max_rate=$(echo "$arecord_output" | awk -F'[][]' '/RATE:/{print $2}' | awk '{print $NF}')
    [ "${max_rate:-0}" -gt 48000 ] && max_rate=48000

    filename="${name}_${max_channels}-${max_rate}-${bitformat}"

    arecord -D "hw:$inputhw" \
        -c "$max_channels" \
        -t raw \
        -f "$bitformat" \
        -r "$max_rate" \
        --buffer-time="$buffer_time_max" \
        --buffer-size="$buffer_size_max" \
        > "$MNT/$filename.raw" 2> >(ts -s >&2) &

    recorder=$!
done

Real world tests needed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions