私が持っている多くのMP3ファイルのサウンドを正規化する方法を探しています。音が小さいものもあれば大きいものもあるため、曲に応じて音量を上げたり下げたりする必要があります。すべてのファイルに対してこれを行う方法はありますか。私は特にターミナル経由でそれをしたいと思いますが、GUIの方法も受け入れられます。
Audacityを使用すると、簡単に バッチ処理 ファイルを作成して、リスト内の多くのファイルに変換または効果を適用できます。そのためには、まず、適用する効果を含む "Chain"を定義する必要があります。
これは "File-> Edit Chains ..."で行います。現在開いているウィンドウで、左下にあるAddボタンを押して、新しいチェーンを挿入します(わかりやすい名前を付けます)。
次に、エフェクトとそのパラメーターを選択して、チェーンに挿入します(ここでは、デフォルト値とノーマライズエフェクトを示しています)。
重要:エフェクトも常に追加する必要があります "Export MP3"(またはその他のエクスポート形式)変換結果をディスクに保存します。
完了したら、このウィンドウをOKのままにして開きます "File-> Apply Chain ..."。作成したばかりのチェーンを選択し、必要なすべてのファイルをロードします「ファイルに適用...」。開いたファイル選択から複数のファイルを選択できます。
処理されたファイルは、元のパスの新しいサブディレクトリ "cleaned"に保存されます。
バージョン> 14.3からは、コマンドラインでのオーディオの正規化またはバッチ処理にsoxフィルター--norm
を使用できます。
sox --norm infile outfile
MP3サポートが libsox-fmt-allでSoxに追加されます 。
ノーマライズオーディオよりも優れている@ mp3gainを見てください
mp3gain -r *.mp3
別の便利なバージョンは、多くのファイルに対して変更を行うかどうかを尋ねるのを防ぐ-cです。
mp3gain -c -r *.mp3
manページで述べたように:
mp3gainは、多くのノーマライザが行うように、ピークの正規化を行うだけではありません。代わりに、ファイルが実際に人間の耳に聞こえる音の大きさを判断する統計分析を行います。また、mp3gainによる変更は完全に無損失です。プログラムはデコードおよび再エンコードせずにmp3ファイルを直接調整するため、変更による品質の低下はありません。
注:そのパッケージは、ubuntu 15.04で意図的に 削除 でした。
Debianはpython-rgain
パッケージを代替として提案します(利点は、 'replaygain'はOgg Vorbis、Flac、WavPack、MP3などのいくつかのファイル形式をサポートすることです。また、これらのファイルの既存のReplay Gain情報を表示できます。タイプ)。インストール後、replaygain
を実行します。
ターミナルからpython-rgainをインストールするには、次のコマンドを実行します
Sudo apt-get install python-rgain
または、14.04(最新)の.deb
ファイルを here から取得します。通常どおりインストールします。その後、Sudo apt-get -f install
を実行して、いくつかの依存関係の問題を修正する必要があります。
このプロジェクトを使用します Normalize 、これはオーディオファイルを正規化するためのコマンドラインツールです。まさにあなたが必要とするものに見えます。バッチ処理ができ、中間形式へのリサンプリングは不要です。
Normalize-audio、Sudo apt-get install normalize-audio
としてパッケージリポジトリにあります。これはDebianによってアップストリームで維持されるビルドであるため、LTS以降である必要があり、mp3互換性(テスト済み)でビルドされます。オプションを調べるのに適したマンページman normalize-audio
がありますが、コマンドのデフォルトはうまく機能しているようです。バッチ処理(複数のファイルにまたがるボリュームを正規化する)の場合、normalize-audio -b *.mp3
を使用するか、ワイルドカードを使用する代わりに個々のファイル名を指定します。
より速くて簡単replaygain
:
このパッケージは、オーディオファイルの リプレイゲイン 値を計算し、値に従ってそれらのファイルのボリュームを正規化するPythonパッケージを提供します。これらの機能を活用する2つの基本的なスクリプトも同梱されています。
リプレイゲインは、オーディオファイル全体で音量が変化するという問題を解決するために設計された標準規格です。
インストール:Sudo apt install python-rgain
。
replaygain --force *.mp3
-f, --force
ファイルに既にゲイン情報が含まれている場合でも、リプレイゲインを再計算します。リプレイゲイン値の計算/変更のみであるため、高速です。平均的なPC(Intel i7-6500U、8GB RAM)では、レートは最大20ファイル/分でした。
そのために、2セントを投入します。まったく同じもの(oggファイルのみ)を探していて、Crunchbangフォーラムでスレッドを開始しました。ここで表示できます: Normalize-audioはmp3デコーダーを見つけることができません
基本的に私の解決策は、ポスト#8のスクリプトでした。 mp3、flac、およびoggの入力ファイル、おそらく他のファイルでも機能しますが、wavには使用できません。
ファイルを作成し(必要な名前を付けて、db_adjust_mp3という名前を付けます)、chmod + xを作成し、〜/ binフォルダーに貼り付けます。不足しているコーデックデータもすべて入力します。例:
元のファイル:16._This_Protector.mp3: Audio file with ID3 version 2.3.0, contains:
vs.
正規化されたファイル:16._This_Protector.mp3: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 192 kbps, 44.1 kHz, JntStereo
ここでnormalize-mp3を使用するようにスクリプトを変更したので、必要に応じて使用できます。
#!/bin/bash
find "$1" -iname "*.""$2" > $HOME/file_list
cat $HOME/file_list | while read line; do
# echo "$line"
orig_gain="$(normalize-mp3 -n "$line" | cut -d 'd' -f1)"
larger=$(echo "$orig_gain"'>'-12 | bc)
if [[ larger ]]
then
gain_difference=$(echo "$orig_gain"*-1-12 | bc)
else
gain_difference=$(echo "$orig_gain"-12 | bc)
fi
echo "Gain Difference will be: $gain_difference""db"
normalize-ogg --mp3 --bitrate "$3" -g "$gain_difference""db" -v "$line"
done
このスクリプトは、現在のdbレベルと-12dbの差を計算し、ゲイン調整を適用してゲインを正確に-12dbに設定します。再帰的であるため、多くのサブフォルダーで音楽コレクションやファイル全体を作成するのに最適です。別のdbレベルを設定する場合は、番号「12」の両方のインスタンスを、使用するdbレベルに変更します。 Crunchbangスレッドに投稿したとおり、使用方法は次のとおりです。
normalize-mp3 <directory> <file extenstion(with no leading dot)> <bitrate>
ただし、音楽ライブラリをmp3形式で保存していたときは、Philippeが提案したように、mp3gainも使用していました。それの死のシンプルさは素晴らしく、私はそれが本当に好きだった。ただし、normalize-audioの問題は、ファイルの再エンドコードをデコードするため、音質がいくらか低下することです。しかし、あなたがオーディオマニアで、mp3が高ビットレートでエンコードされていない限り、大きな違いに気付かないはずです。
Mp3gainで気付いたのは、どのオプションを試しても、コレクション内のすべてをまったく同じdbレベルにすることができなかったということです。次。このスクリプトはまさにそれを行います。長く巻き取られてすみません。お役に立てれば。
Neilの回答が最も好きでした。オーディオファイル間に相関関係が導入されないためです。ゲインレベルを1つ選択し、それに合わせてすべてを調整するだけです。
ただし、normalize-ogg
の出力をいくつかのファイルで解析する際に問題が発生しました。 bc
にも厄介な問題が1つあります。実際の丸めは行われず、切り捨てられるだけです。
結局、私はシェルスクリプト作成をあきらめ、Pythonに移行しました。
注1:exiftoolの部分は過剰かもしれませんが、元のビットレートが保持されることを100%確実にしたかったのです。
注2:これはオリジナルを上書きしますオリジナルを保存したい場合は、--backupを使用しますnormalize-oggの最後の呼び出し。しかし、コピーを別の安全なディレクトリに保存する方が実用的であることがわかりました。
注3:このソリューションはoggファイルを扱いますが、mp3に適合させるのは簡単で、「ogg」の出現を「mp3」に置き換えるだけです。
これが問題の私の見解です。最新バージョンはここにあります: regain.py
#!/usr/bin/python3
"""
Parallel normalize gains
"""
'
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'
# Absolute value, in dB for the desired gain of each file
TARGET_GAIN = -12
#
MAX_THREADS = 2
from subprocess import Popen, PIPE
from multiprocessing.dummy import Pool as ThreadPool
from os import listdir
import logging
def initlogger(logfile="log.log", mainlevel=logging.DEBUG,
filelevel=logging.DEBUG, consolelevel=logging.DEBUG):
'''initlogger'''
# create logger
logger = logging.getLogger()
logger.setLevel(mainlevel)
# create file handler which logs even debug messages
fh = logging.FileHandler(logfile)
fh.setLevel(filelevel)
# create console handler also logging at DEBUG level
ch = logging.StreamHandler()
ch.setLevel(consolelevel)
# create formatter and add it to the handlers
formatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
def logcommand(command=[]):
'''logcommand'''
if not isinstance(command, list):
return "", "", -1
logging.info("Command:\n" + " ".join(command) + "\n")
proc = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = proc.communicate()
output = output.decode("utf-8")
err = err.decode("utf-8")
logging.info("Output:\n" + output + "\n")
logging.info("Error:\n" + err + "\n")
logging.info("Return Code:\n" + str(proc.returncode) + "\n")
return output, err, proc.returncode
def regain(target):
'''regain'''
logging.info("============================ Start File ============================")
logging.warning(target["name"])
logging.info("Extracting gain info.\n")
commandgetlevels = ['normalize-ogg', '-n', target["name"]]
output, err, retcode = logcommand(commandgetlevels)
level = output.split()[0]
logging.debug("Level: " + level)
if "dBFS" in level:
level = level.split("dBFS")[0]
level = level.replace(',', '.')
level = int(round(float(level)))
delta = target["gain"] - level
logging.info("Required adjustment: " + str(delta) + "\n")
if delta is 0:
logging.warning(target["name"] + " is already at the correct level")
return 0
logging.info("Extracting average bitrate.\n")
commandgetinfo = ['exiftool', target["name"]]
output, err, retcode = logcommand(commandgetinfo)
bitrate = '0'
for line in output.split('\n'):
if 'Nominal Bitrate' in line:
bitrate = line.split(':')[1].split()[0]
break
logging.info("Average bitrate is: " + str(bitrate) + "\n")
if bitrate is '0':
logging.error("No valid bitrate found, aborting conversion.\n")
exit(-1)
logging.info("Re-normalizing.\n")
commandrenormalize = ['normalize-ogg', '--ogg', '--bitrate', bitrate,
'-g', str(delta) + 'db', target["name"]]
output, err, retcode = logcommand(commandrenormalize)
if retcode is not 0:
log.error("Output:\n" + output)
log.error("err:\n" + err)
exit(retcode)
return retcode
# function to be mapped over
def parallelregain(gain=TARGET_GAIN, threads=MAX_THREADS):
'''parallelregain'''
logging.info("Creating thread pool with " + str(threads) + " elements.\n")
pool = ThreadPool(threads)
targets = []
files_list = listdir(".")
files_list.sort()
counter = 0
for filename in files_list:
if filename.endswith("ogg"):
target = {
"name":filename,
"gain":gain,
}
targets.append(target)
counter = counter + 1
pool.map(regain, targets)
pool.close()
pool.join()
if __== "__main__":
initlogger(logfile="normalize.log", consolelevel=logging.WARNING)
parallelregain()