Friday 23 December 2011

scilab: analysing .wav #2

scilab でちょっと前にやった,(主に声の録音を想定して).wav から有声部を判定するのを,
もうちょっと整備して一つの関数の形にした.主な変更点は
  • 関数の形にした.
  • 読み込む音声ファイルを入力して選べるように改善.
  • ステレオ・モノラル両方に対応
  • プログラム実行の進捗状況を逐次報告するように変更.
  • 閾値,音声ファイルの何分の一を「近傍」とするかを入力して指定するように変更.
  • 変数名を幾つか変更.
  • サンプリングレートを最初に表示する機能を追加.
で,以下が .sce.
function reader
    //23rd December 2011.copyright mutsuteru
    //(the author of the blog,http://lesguillemets.blogspot.com/ ,
    //and the one who is tweeting @exumbra_insolem)
    //all rights reserved.
    //Published for personal use only.
    //Sharing any outcome using this program or programs based on this
    //without explicit permission from the author is prohibited.
    //Well, I love this kind of statement.. lol
    a=input("INPUT 1 TO clf, OTHER VALUE TO CONTINUE WITHOUT clf")
    if a==1 then clf;
    end
    [sound1,fs,nbits] = wavread(input("FILE?"));
    printf("sampling rate = %d",fs);
    if size(sound1,"r")==2 then..
        sound2=sound1(2,:);
        sound1=sound1(1,:);//for stereo sound
    end
    disp("NOW PLOTTING THE WAV FILE....");
    plot2d(sound1);//this program fill handle sound1 only.
    a=input("INPUT 1 TO CONTINUE, OTHER VALUE TO RETURN");
    if a~=1 then return;
    end
    disp("CALCULATING THE 2ND POWER OF THE .WAV...")
    pow=sound1^2;
    disp("OK.")
    n=input("HOW MANY SLICES?")
    threshold=input("THE  THRESHOLD?")
    chop=length(pow)/n;
    judge=zeros(pow);   
    showjudge=max(sound1);
    disp("NOW JUDGEING....PLEASE WAIT....");
    for i=1:length(pow)
        if.. 
          mean(pow(max(i-chop/2,1):min(i+chop/2,length(pow))))..
          >threshold..
            then judge(1,i)=showjudge;
        end
    end
    disp("FINISHED. NOW PLOTTING.....")
    plot2d(judge);
endfunction
流石に,色分けも何も無いと読みにくくて仕方がないが.
今回前と同じファイルでやってみたらこんな感じ.まあ当然結果は似たようになる.
 この場合閾値は0.001ならいい感じ, 0.01 は大きすぎるみたい.
二乗してるのも効いてるだろう.
次は
  1. このアルゴリズムの根本的改善,
  2.  発声部と判断したところだけを抽出して新たな .wav を作るアルゴリズムの制作,
  3. 音の大きさ以外のところからの分析の方法 (fourier 変換とか使える)の策定
 辺りをやりたい.1. については,基本的に scilab は行列計算に特化していて,
for 文よりは行列で計算する方が 10~100 倍とか速いらしい (source はこちら <pdf> ) ので,
その点について特に色々考えたい.


<追記:16:19 ,閾値の適切な値の例示を修正(それぞれ 0.1 倍),さらにプログラムの一部変更.
具体的には15行目 付近.変更点にもその内容を追加.
ステレオ,モノラル両方に対応できるプログラムにした.>

No comments:

Post a Comment