SCILABで音声ファイルを切断する

WAV形式の音声ファイルが有ります。このファイルはミュート区間が大変多いため、全体を聞いていると時間がかかって仕方有りません。そこで、無音区間が一定時間以上続くと、無音区間の前段部分を別ファイルに書き出すスクリプトSCILABで作成してみました。

 

 mute_threshold=2.5;
 [Old_sound,Fs,bits]=wavread("test.wav");
 sound_section=%T;
 nsample=length(Old_sound);
 start_sample=1; end_sample=1;seq=0;
 for sample=mute_threshold*Fs+1:Fs/10:nsample
  x=Old_sound(sample-mute_threshold*Fs:sample);
  if x*x' < 1 & sound_section then
    end_sample=sample;
    sound_section=~sound_section;
    New_sound=Old_sound(start_sample:end_sample);
    if length(New_sound)>Fs*10 then,
     seq=seq+1;
     outfile=sprintf("wavfiles/out%03d.wav",seq);
     savewave(outfile,New_sound,Fs,bits);
     printf("%s %d %d\n",outfile,start_sample,end_sample);
    end;
  end;
  if x*x' > 1 & ~sound_section then,
    start_sample=sample;
    sound_section=~sound_section;
  end;
 end;
 exit;

変数 mute_threshold で無音区間の長さ(秒)を決定します。2.5秒以上無音が続くと、その前の部分を書き出します。

test.wav というファイル名の音声ファイルをwavread関数で読み込みます。

0.1秒ごとにx*x'を計算して、2.5秒間無音が続いているか判定しています。判定に引っかかると、そのサンプル値をend_sample に登録して、start_sampleからend_sampleの音声をNew_sound配列にコピーします。そして、ブーリアン変数sound_sectionをfalseにします。

余り短い音声はノイズだと考え、10秒以上の長さのNew_sound配列のみをoutfileという名前のファイルにsavewave関数を用いて書き出します。

一方、変数sound_sectionがfalseの場合は無音区間が続いているということですから、再びx*x'が大きな値を取れば音声区間に復帰したものと判定し、ブーリアン変数sound_sectionをtrueにするとともに、そのサンプル値を start_sampleに登録します。

 

このスクリプトにより作成された複数のwav形式音声ファイルを ffmpeg で連結したところ、もとの音声の約3分の2の時間となりスムーズに聞き取ることができるようになりました。