LoginSignup
15
13

More than 5 years have passed since last update.

シェルスクリプトで音声ファイルの波形を画像化するやつ

Last updated at Posted at 2016-08-13

最近、ハイレゾ音源なのにダイナミックレンジを殺したミキシング・マスタリングで海苔波形が云々という文句をアニメ方面からよく聞くので、じゃあ自分が持ってる息の長いバンドの音源を見比べてみようかと思うも、音源を編集ツールに読ませてスクショするのは面倒でダサいし、かといって視覚的に出力するツールを知らないし、ということでそういうツールを自作することにしました…シェルスクリプトで。

ソース

sndvisual
#!/bin/sh -e
# License: CC0

# mktemp(1)はPOSIX外
tmp=$(mktemp -d)
clean() {
    rm -rf $tmp
}
trap clean EXIT

# オプション
# -v,-m 音量の基準線を追加する。
#       線の引く位置を -v はdB、-m はサンプルに対する倍率で指定
# -r    基準線に合わせて出力波形も拡大縮小する
level= reduce=
while getopts m:v:r sw
do
    case $sw in
    v)
        level=$(printf %.3f $(echo "e(($OPTARG/20)*l(10))"|bc -l))
        ;;
    m)
        level=$(printf %.3f $OPTARG)
        ;;
    r)
        reduce=t
        ;;
    *)
        cat <<heredoc >&2
usage:
    ${0##*/} [-v vol|-m mag] [-r] [sound]
heredoc
        exit 1
        ;;
    esac
done
shift $(($OPTIND - 1))

if [ -n "$reduce" -a -n "$level" ]
then reduce=$level
else reduce=1
fi

# 音声ファイルをモノラル8bit PCM化。要ffmpeg
# 要は音声データをLiner PCMに変換できてストリームの情報を得らればいいので
# soxとか自分の使いやすいソフトで代替するのも良いと思います
[ $# -eq 0 ] && input=- || input="$1"
ffmpeg -i "$input" -ac 1 -f s8 $tmp/samp.bin 2>$tmp/meta
sr=$(sed '/^Output #0, s8,/,/Stream #0:0/!d' $tmp/meta |sed '$!d; s/.* \([0-9]*\) Hz.*/\1/')
len=$(wc -c <$tmp/samp.bin)

# ここからSVG出力
cat <<heredoc
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 -144 2048 288">
<style type="text/css"><![CDATA[
polygon {
fill: #44f;
stroke: #00f;
stroke-width: 1;
}
]]></style>
<rect x="0" y="-144" width="2048" height="288" fill="#ddd"/>
<path d="M0,-128 H2048 M0,128 H2048" stroke="#444" stroke-width="1"/>
heredoc

# 1分毎に縦線を引くやつ
awk -v "sr=$sr" -v "len=$len" 'BEGIN{
    print "<path stroke=\"#777\" stroke-width=\"1\" d=\""
    for (m = sr * 60; m < len; m += sr * 60) {
        print "M" m * 2048 / len ",-144v288"
    }
    print "\"/>"
}'

# 区切り毎のサンプル最大・最小値を求める
# ここら辺、シェルスクリプトでもバイナリ処理頑張れるよってのを示したかっただけなので
# 実際使うなら遅いからバイナリを直接読める言語を使ったほうがいいよ……
od -tdC -v -An $tmp/samp.bin |sed 's/  */ /g; s/^ //; s/ $//;' |tr ' ' '
' |awk -v "len=$len" '
BEGIN{
    pos = 1
    posf = int(len / 2048)
    sampmax = 0
    sampmin = 0
    NR--
}
{
    if (NR < posf) {
        v = -$1
        if (sampmax < v) {
            sampmax = v
        }
        else if (sampmin > v) {
            sampmin = v
        }
    }
    else {
        print pos - 1, sampmax, sampmin
        pos++
        posf= int(pos * len / 2048)
        sampmax = 0
        sampmin = 0
    }
}
END {
    print pos - 1, sampmax, sampmin
}
' >$tmp/samp.txt

# 下半分多角形
echo '<polygon'
echo "transform='scale(1,$reduce)'"
echo 'points="0,0'
cut -f1,2 -d ' ' $tmp/samp.txt
echo '2048,0"/>'

# 上半分多角形
echo '<polygon'
echo "transform='scale(1,$reduce)'"
echo 'points="0,0'
cut -f1,3 -d ' ' $tmp/samp.txt
echo '2048,0"/>'

# 基準線追加
if [ -n "$level" ]
then
    levelf=$(echo "$level*128"|bc)
    echo "<path stroke='red' stroke-width='1' d='M0,$levelf H2048 M0,-$levelf H2048' stroke-dasharray='8' />"
fi

echo '</svg>'

最終的には画像形式をSVGにし、全体を2048等分して、その区間内での最小値・最大値を求めて折れ線で繋いでいくという処理になりました。これでこんな感じの画像が得られます。

result.png
(これはスプラトゥーンの「バトル 勝ちジングル」より)

元々はPCMサンプル毎にピクセルを出力していって出来た長大な画像を縮小するとか、SVGでサンプル毎に線を引くとかしてたけど、どちらもべらぼうに時間がかかる上にたいして綺麗じゃなかったのでやめました。44100 Hzのサンプルが5分続くと1000千万超えますしね…。

あとこれで作ったSVGをImageMagickでconvert(1)すると90秒ぐらい掛かるんだけど遅すぎない? batikのrasterizerだと2〜3秒しか掛からないのに。

画像一覧

まあそんなわけでめでたく波形の視覚化に成功したので、T‐スクェアの曲からいくつか挙げてみましょう。(これがやりたかっただけ)

※ 赤い線はノーマライズのためにEBU R128に基づくラウドネス測定の後-18 LUFSになるまで下げられる音量です。間隔が狭いほど元々の音が大きく感じます。

T‐スクェア

A FEEL DEEP INSIDE / LUCKY SUMMER LADY (1978、1987再販)
lucky summer lady@1.png

LICKIN’ IT / MIDNIGHT LOVER (1978、1990再販)
out.png

TEXAS KID / MAKE ME A STAR (1979、1987再販)
make me a star@7.png

TOMORROW’S AFFAIR / ROCKOON (1980、1990再販)
rockoon@3.png

CHOU CHOW / MAGIC (1981、1987再販)
out.png

LOVE’S STILL BURNIN’ / 脚線美の誘惑 (1982、1990再販)
out.png

君はハリケーン / うち水にRAINBOW (1983、1990再販)
out.png

ADVENTURES (EPILOGUE) / ADVENTURES (1984)
adventures@9.png

いとしのうなじ / STARS AND THE MOON (1984、2001リマスター)
stars and the moon@1.png

PRIME / R·E·S·O·R·T (1985)
resort@8.png

LEAVE ME ALONE / S·P·O·R·T·S (1986)
out.png

TRUTH / TRUTH (1987)
truth@5.png

GO FOR IT / YES, NO. (1988)
yes no@2.png

MORNING STAR / WAVE 上: (1989) 下: (1989、2001リマスター)
wave@1.png
wave vrcl-2114@1.png

WIND SONG / NATURAL (1990)
natural--1@3.png

ここから本田雅人
TRAVELERS / REFRESHEST (1991)
refreshest@9.png

MEGALITH / NEW‐S (1991)
out.png

FACES / IMPRESSIVE (1992)
impressive@1.png

明日への扉 / HUMAN (1993)
human@1.png

夏の蜃気楼 / 夏の惑星 (1994)
out.png

NO END RUN / SOLITUDE (1994)
solitude@3.png

CROWN AND ROSES / WELCOME TO THE ROSE GARDEN (1995)
out.png

WHO’S LICKIN’ IT / MISS YOU IN NEW YORK (1995)
miss you in new york@5.png

SUNSHINE SHOWER / B.C. A.D. (1996)
b.c. a.d.@8.png

SAMURAI METROPOLIS / BLUE IN RED (1997、2002リマスター)
out.png

ここから宮崎隆睦
DOWN TO EARTH / GRAVITY (1998)
gravity--1@6.png

JAPANESE SOUL BROTHERS / GRAVITY (1998)
gravity--2@1.png

SCRAMBLING / SWEET & GENTLE (1999)
sweet and gentle@5.png

MAN ON THE MOON / T‐SQUARE (2000)
out.png

ここから2人ユニット
SAFARI / FRIENDSHIP (2000)
friendship@2.png

TOYS / BRASIL (2001)
out.png

COME AND GET IT / NEW ROAD, OLD WAY (2002)
new road old way@7.png

EUROSTAR 〜RUN INTO THE LIGHT〜 / SPIRITS (2003)
spirits--1@3.png

DREAM WEAVER / GROOVE GLOBE (2004)
out.png

ここからバンド制復活
MORE THAN LEMONADE / PASSION FLOWER (2005)
out.png

REVENGE / BLOOD MUSIC (2006)
out.png

RONDO / 33 (2007)
33--1@1.png

ANTHEM / WONDERFUL DAYS (2008)
out.png

SURVIVOR / DISCOVERIES (2009)
discoveries@2.png

FANTASTIC STORY 〜時間旅行〜 / 時間旅行 (2010)
jikan ryoko@1.png

はやぶさ 〜THE GREAT JOURNEY: 奇跡の帰還〜 / NINE STORIES (2011)
nine stories@2.png

SUNSHOWER / WINGS (2012)
wings@4.png

TEMPS, 10 P.M. / SMILE (2013)
smile@5.png

YOU’RE THE ONE / NEXT (2014)
next@1.png

KNOCK ME OUT / PARADISE (2015)
paradise@7.png

7‐6‐5 / TREASURE HUNTER (2016)
treasure hunter@5.png

T‐スクェアはまぁポップやロックとはジャンルが違うし最近の曲は大体Hybrid SACDでリリースされているだけあってそこまでどぎつく海苔海苔しくなっているわけではありませんね。

T‐スクェア以外で気になったやつ

塩谷哲 - SETEMBRO (BRAZILIAN WEDDING SONG) / WISHING WELL (1998)
se.png
原曲はIvan Lins、Quincy Jonesによるカバーが有名な曲です。これは塩谷哲によるピアノのカバーなんですが、バラードらしくしっとりと始まり、終盤の盛り上がるところで音がドーンと力強く迫ってくる感じが本当に良い。ジャズ録音斯くあるべしといった感じ。

本田雅人 - SEVEN / SAXES STREET (2015)
上はハイレゾ配信版、下はCD版
out.png
out.png
最初CDを買ったところとても気に入ったので、音質の向上を期待しつつ、あとお布施のつもりでハイレゾ版も買ってみたのですが、サンプリングレートとビット深度が増えただけで内容が一緒、その容れ物に見合ったミキシング・マスタリングがなされていないことにとてもショックを受けてしまいました。フュージョンは今やジャズとは距離のあるジャンルとはいえ流通上はジャズと一緒に扱われるのだからもう少し気を遣えないものなんでしょうか? もうハイレゾ買う気がしない…。

Skrillex - Rock n’ Roll (Will Take You to the Mountain) / Scary Monsters and Nice Sprites
out.png
自分のライブラリに入っているやつ(vorbis限定)で一番うるさかったやつで、ReplayGainで-12.99 dBも下げられる。海苔。
これをReplayGainを有効にしつつ再生した時の波形は以下のようになります。
out.png

まとめ

T‐スクェア40周年おめでとうございます。

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13