Subsections

3 音ファイルの扱い

3.1 LibSndFile

GitHubのJuliaAudio organization(https://github.com/JuliaAudio/)にJuliaで音を扱うための様々なライブラリが公開されています。それらの中に、LibSndFile(http://mega-nerd.com/libsndfile/)というWAVファイルやAIFFファイルを読み書きするためのライブラリのJulia用ラッパー(https://github.com/JuliaAudio/LibSndFile.jl)があります。

インストールは簡単で、Juliaのコマンドラインから

julia> Pkg.add("LibSndFile")
と入力するだけです(Julia 0.6まで)。

Julia 0.7以降はパッケージ管理システムがPkg3に変わりましたので、Pkgモードに入ってインストールします。juliaプロンプトにおいて]とタイプすると、pkgプロンプトに入りますので、そこでadd LibSndFileとします。1

julia> ]
(v1.0) pkg> add LibSndFile
インストールは一度やれば、次からはこの部分は不要です。

使用するにはパッケージの読み込みを行います。

julia> using FileIO: load, save
julia> import LibSndFile
初回はプリコンパイルなどで少し時間がかかるかもしれませんが、エラーなくJuliaプロンプトに戻れば使用準備が整ったことになります。このusing文はJuliaを起動するたびに行う必要があります。

3.2 音ファイルの読み込み

音ファイルの読み込みにはload()を使います。現時点のLibSndFileでは、WAV以外にFLACとOgg/Vorbisにも対応しています。

JuliaのREPLではいろいろな情報を表示してくれます。以下ではCDから抜粋した15秒ほどのWAVファイルを読み込んでいますが、1チャンネルあたり587,264サンプルあり、それが2チャンネルあること、全体で約13.3秒、サンプリング周波数は44,100 Hzなどの情報に加えて、波形をプリティプリントまでしてくれます(波形そのものではなく振幅のdB表示です→SampledSignals.jlの機能です https://github.com/JuliaAudio/SampledSignals.jl)。

julia> x = load("gershwin_piano_concerto.wav")
587264-frame, 2-channel SampleBuf{FixedPointNumbers.Fixed{Int16,15}, 2}
13.316643990929705s sampled at 44100.0Hz

図: WAVファイルを読み込むと様々な情報を表示してくれる。
Image audio_load_soundfile

こういった情報が表示されるのが邪魔な場面では、最後にセミコロン(;)をつけると表示の抑制が行われます。

julia> x = load("gershwin_piano_concerto.wav");

3.3 音データの構造

データが格納されている変数xSampledSignals.SampleBuf型で、datasamplerateの二つのフィールドを持っています。変数名のとおりdataには各サンプルのデータ値が、samplerateにはサンプリング周波数が入っています。

julia> x.data   # 各サンプル値(2chファイルなので2列です)
587264×2 Array{FixedPointNumbers.Fixed{Int16,15},2}:
 -3.0e-5Q0f15    0.0Q0f15
  0.0Q0f15       3.0e-5Q0f15
 -3.0e-5Q0f15    3.0e-5Q0f15
 -3.0e-5Q0f15    3.0e-5Q0f15
 -3.0e-5Q0f15    6.0e-5Q0f15
  ⋮
  6.0e-5Q0f15   -6.0e-5Q0f15
  0.0Q0f15       3.0e-5Q0f15
 -6.0e-5Q0f15    3.0e-5Q0f15
 -6.0e-5Q0f15    6.0e-5Q0f15
 -6.0e-5Q0f15    6.0e-5Q0f15
 -6.0e-5Q0f15    3.0e-5Q0f15

julia> x.samperate   # サンプリング周波数
44100.0

音の加工などをする前に波形を見てみましょう。PythonのmatplotlibをJuliaで使えるようにしたPyPlotを使います。(初めて使うときは「Pkg.add("PyPlot")」でインストールします)

x1 = x.data[:, 1];   # チャンネル1のみ抜き出し
t = (0 : length(x1)-1) / x.samplerate;   # 各サンプルの時刻を求める

using PyPlot
plot(t, x1);
ylim(-1, +1);
grid();
title("Music Excerpt")
xlabel("Time (s)")
ylabel("Amplitude")

図: 音データの波形表示
Image audio_plot_waveform

3.4 音ファイルの書き出し

音はSampleBuf型にしてからsave()します。SampleBuf型はマルチチャンネルに対応しており、$n\times c$の配列にすると$n$サンプル・$c$チャンネルのファイルに保存できます。

フォーマットはsave()にわたす拡張子によって自動的に面倒を見てくれますが、2018年5月25日時点ではWAV、FLAC、OGGのみに対応しているようです。また、FLACは16ビット整数型でしか保存できません。

using SampledSignals
samplerate = 44100;
whitenoise = rand(samplerate, 2) - 0.5;   # 一様乱数でホワイトノイズを作る

# WAVファイルへの書き出し
buf = SampleBuf(whitenoise, samplerate);   # SampleBuf型に変換
save("hoge.wav", buf);

# FLACファイルへの書き出し
x = map(PCM16Sample, whitenoise);   # FLACは16ビット整数にする必要がある
buf = SampleBuf(x, samplerate);
save("hoge.flac", buf);



脚注

... 0.7以降はパッケージ管理システムがPkg3に変わりましたので、Pkgモードに入ってインストールします。juliaプロンプトにおいて]とタイプすると、pkgプロンプトに入りますので、そこでadd LibSndFileとします。1
2018年10月1日時点ではまだJulia 1.0対応版が正式公開になっていないので、add Unitfuladd SampledSignals#masteradd LibSndFile#masterとして開発版を使用しました。


MARUI Atsushi
2022-04-20