کاهش نویز با استفاده از sox

SoX

SoX ابزاری برای ویرایش فایل‌های صوتی است که روی گنو/لینوکس، مک و ویندوز در دسترس است. روی اندروید هم می‌توانید در محیط termux از آن استفاده کنید.

در این پست نخست با استفاده از SoX نویز یک فایل صوتی را کاهش می‌دهیم و سپس یک اسکریپت برای کاهش نویز فایل‌های صوتی و تصویری، با استفاده از Sox و FFmpeg را بررسی می‌کنیم.

کاهش نویز با استفاده از SoX

اگر یک فایل صدا به نام audio.wav داشته باشیم که در ابتدای آن بخش کوچکی سکوت یا درست‌تر بنویسم «صدای محیط» ضبط شده باشد، میتوانیم آن بخش را با استفاده از SoX جدا کنیم:

# sox in.ext out.ext trim {start: s.ms} {duration: s.ms}
sox audio.wav noise.wav trim 0 0.900

در اینجا SoX فایل audio.wav را به عنوان ورودی دریافت و تا ثانیه 0.9 آن را جدا کرده و با نام noise.wave ذخیره می‌کند.

اکنون با استفاده از این بخش یک فایل از ویژگی‌های نویز محیط به نام noise.prof می‌سازیم:

sox noise.wav -n noiseprof noise.prof

در پایان کاهش نویز را بر اساس پروفایل ساخته شده انجام می‌دهیم. برای تنظیم اندازه کاهش نویز از یک ضریب استفاده می شود که بر اساس این منبع عددی بین 0.2 تا 0.3 بهترین خروجی‌ها را خواهد داشت:

sox audio.wav audio-clean.wav noisered noise.prof 0.21

اسکریپتی برای کاهش نویز فایل‌های صوتی و تصویری با FFmpeg و SoX

این اسکریپت دو مسیر، -نخست فایل ورودی و سپس فایل خروجی- را می‌گیرد ($1 و $2). در صورتی که فایل ورودی تصویری باشد با استفاده از FFmpeg صدای آن را جدا می‌کند. سپس مشابه آنچه که در بخش پیش دیدیم نویز فایل صوتی را کاهش می‌دهد و در پایان اگر ورودی فایل تصویری باشد دوباره با استفاده از FFmpeg صدا و تصویر را به هم می‌چسباند.

#!/usr/bin/sh

usage ()
{
    printf "Usage : noisereduce <input video file> <output video file>\n"
    exit
}

# Tests for requirements
ffmpeg -version >/dev/null || { echo >&2 "We require 'ffmpeg' but it's not installed. Install it by 'sudo apt-get install ffmpeg' Aborting."; exit 1; }
sox --version >/dev/null || { echo >&2 "We require 'sox' but it's not installed. Install it by 'sudo apt-get install sox' Aborting."; exit 1; }

if [ "$#" -ne 2 ]
then
  usage
fi

if [ ! -e "$1" ]
then
    printf "File not found: %s\n" "$1"
    exit
fi

if [ -e "$2" ]
then
    printf "File %s already exists, overwrite? [y/N]\n: " "$2"
    read -r yn
    case $yn in
        [Yy]* ) ;;
        * ) exit;;
    esac
fi

inBasename=$(basename "$1")
inExt="${inBasename##*.}"

isVideoStr=$(ffprobe -v warning -show_streams "$1" | grep codec_type=video)
if [ -n "$isVideoStr" ]
then
    isVideo=1
    printf "Detected %s as a video file\n" "$inBasename"
else
    isVideo=0
    printf "Detected %s as an audio file\n" "$inBasename"
fi

printf "Sample noise start time [00:00:00]: "
read -r sampleStart
if [ -z "$sampleStart" ] ; then sampleStart="00:00:00"; fi
printf "Sample noise end time [00:00:00.900]: "
read -r sampleEnd
if [ -z "$sampleEnd" ] ; then sampleEnd="00:00:00.900"; fi
printf "Noise reduction amount [0.21]: " 
read -r sensitivity
if [ -z "$sensitivity" ] ; then sensitivity="0.21"; fi


tmpVidFile="/tmp/noiseclean_tmpvid.$inExt"
tmpAudFile="/tmp/noiseclean_tmpaud.wav"
noiseAudFile="/tmp/noiseclean_noiseaud.wav"
noiseProfFile="/tmp/noiseclean_noise.prof"
tmpAudCleanFile="/tmp/noiseclean_tmpaud-clean.wav"

printf "Cleaning noise on %s...\n" "$1"

if [ $isVideo -eq "1" ]; then
    ffmpeg -v warning -y -i "$1" -qscale:v 0 -vcodec copy -an "$tmpVidFile"
    ffmpeg -v warning -y -i "$1" -qscale:a 0 "$tmpAudFile"
else
    cp "$1" "$tmpAudFile"
fi
ffmpeg -v warning -y -i "$1" -vn -ss "$sampleStart" -t "$sampleEnd" "$noiseAudFile"
sox "$noiseAudFile" -n noiseprof "$noiseProfFile"
sox "$tmpAudFile" "$tmpAudCleanFile" noisered "$noiseProfFile" "$sensitivity"
if [ $isVideo -eq "1" ]; then
    ffmpeg -v warning -y -i "$tmpAudCleanFile" -i "$tmpVidFile" -vcodec copy -qscale:v 0 -qscale:a 0 "$2"
else
    cp "$tmpAudCleanFile" "$2"
fi

printf "Done"

لینک‌های بیشتر

اگر هم که دیدن ویدیوی آموزشی برایتان آسانتر است یا می‌خواهید تفاوت فایل خروجی و ورودی را ببینید:

دیدگاه‌ها

می‌توانید دیدگاه‌های این پست را در ماستودون و اینجا ببینید. برای نوشتن دیدگاه خود روی لینک زیر کلیک کنید.

نوشتن دیدگاه‌

دیدن دیدگاه‌ها