SoX(Sound eXchange)で音声ファイルの長さの差をとる

前の関連記事:SoX(Sound eXchange)で音声感知録音:その1

1.wavファイルにさらに録音を追加した2.wavファイルがあるとき、2.wavから1.wavと重なる部分を除去したいと思います。やることは1.wavから2.wavの長さの部分をtrimするだけです。SoXで扱えるファイル形式ならwavの部分を他の形式に置き換えるだけで応用できます。

wavファイルの長さを得る

sox --i -d 1.wav
C:\wav>sox --i -d 1.wav
00:19:58.59

これで秒数が得られます。

1.wavから2.wavの長さの部分をtrimする

sox 2.wav outfile.wav trim 00:19:58.59  -0
これで2.wavから1.wavと重複する部分である先頭から19分58.59秒までを除いた部分がoutfile.wavに得られます。

これを1行のコマンドにします。
for /F %p in ('sox --i -d 1.wav') do sox 2.wav outfile.wav trim %p -0
これでできましたが、いちいちコマンドにファイル名を入力するのは面倒ですね。

長い方のwavファイルの先頭から短い方のwavファイルの長さの分を削除するバッチファイル


@echo off
echo ドロップされた2つのファイルの長さの差部分を出力します。
rem 引数のファイルがあるディレクトリに移動。
cd "%~dp1"
rem soxの設定
path %PATH%;C:\Program Files (x86)\sox-14-4-2
set AUDIODRIVER=waveaudio
rem 引数の音声ファイルの長さを入れる変数を初期化
set TIME1=0
set TIME2=0
rem 音声ファイルの長さの整数部分のみ取得。変数は整数しか扱えない。
for /F "tokens=1 delims=." %%p in ('sox --i -D %~nx1') do set TIME1=%%p 
for /F "tokens=1 delims=." %%p in ('sox --i -D %~nx2') do set TIME2=%%p 
rem 音声ファイルのいずれかの長さが0のときは処理を中止する。
set /A flg=%TIME1%*%TIME2%
cls
if %flg% EQU 0 (
echo 音声ファイルを二つドロップしてください。
goto EXIT
) 
rem 音声ファイルの長いほうから短いほうを引く。
echo 2つの音声ファイルの差を出力中です。
if %TIME1% LSS %TIME2% (
for /F %%p in ('sox --i -d %~nx1') do (sox %~nx2 %~n2_diff%~x2 trim %%p -0)
cls
echo %~n2_diff%~x2に出力完了しました。
) else (
for /F %%p in ('sox --i -d %~nx2') do (sox %~nx1 %~n1_diff%~x1 trim %%p -0)
cls
echo %~n1_diff%~x1に出力完了しました。
)
:EXIT
pause
wav_diff.batというファイル名で保存してそれに長さの差を取りたい音声ファイル(soxで扱える音声ファイル)を2つドロップすると元のファイルの場所に「長い方のファイル名_diff」というファイル名で出力されます。

ファイルの拡張子はチェックしていませんのでwavファイルに限らずmp3でも動作すると思います。

ただしmp3の場合は編集のために伸展後再圧縮になるので音質劣化を生じると思います。

バッチファイルは整数しか扱えないので長さの比較は1秒以下は切り捨てて行っていますが、差をとるときはfor /Fでsox --iの有効桁数すべてを引き渡しています。

波形の重複部分を除いているわけではなく単に長さの差をとっているだけです。

入力ファイルの大きさが500MBぐらいになると読み込むだけで結構時間がとられます。

参考にしたサイト


For - DOS コマンド一覧
for /Fコマンドはコマンドを入れ子にしたいときに非常に役立ちます。

If - DOS コマンド一覧
数値の比較は整数のみ可能なようです。

次の関連記事:SoX(Sound eXchange)でMP3を扱う

PR

0 件のコメント:

コメントを投稿