Sunday 25 December 2011

scilab analysing .wav #4

この前の関数に手を加え,区切られた音ごとにデータを取り出すところまで伸ばした.
取り出されたデータはそれぞれ別にウィンドウ開いて波形が表示される(スキップも可能).
ただこれ全部一つの行列に収めたから,
音として区切られた部分の中で一番長いの以外は最後に0が意味なく並んだ部分ができる.
これも後で切りたいなぁ.


ついでに重要変数を global 化して,関数実行の後も使えるように.
さらに global 化したことによって,手順ごとに別の関数に分けることができるようになったので,
それも行った.また,「近傍」の長さを秒数で指定することもできるようにした.だいぶ良い感じ.
これが実際音を区切ったりするのに最終的に使えるかは別にして,
やってて楽しいし,少なくとも幾許かの練習にはなった.
あとは,取り出した音の分析とかをやりたいところですね.
今回のメモとしては,
  • global a b c d; で global 変数 a,b,c,dを宣言できる.
  • scf(i); で i 番目のグラフィックウィンドウで描画.
  • global の宣言は関数外でしないと無効(?)
あたりかな.では以下ソース.145行に及ぶので注意.

    //________________________________________________________
    //25th 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
    //___________________________________________________________
    //
    // README:
    // the global variables are as follows:
    //   i) defined in function wavreader
    //     sound1   : the .wav file, read by wavread command.
    //     fs       : the sampling rate of the .wav file.
    //     pow      : = sound1^2 .
    //  ii) defined in function wavjudger
    //      judge   : a vector.
    //                its components correspond to those of sound1.
    //                0 for silence, nonzero for sound.
    // iii) defined in function wavcutter
    //      syllable: records each 'syllable'.
    //____________________________________________________________
global sound1 fs time pow judge syllable;
function wavreader
    a=input("INPUT 1 TO clf, OTHER VALUE TO CONTINUE WITHOUT clf")
    if a==1 then clf;
    end
    [sound1,fs,nbits] = wavread(input("FILE?"));
    time=length(sound1)/fs;
    printf("sampling rate = %d",fs);
    printf("the length of the file in second = %f",time);
    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.
    disp("CALCULATING THE 2ND POWER OF THE .WAV...")
    pow=sound1^2;
    disp("OK.END OF FUNCTION.")
endfunction
//_______________________________________
function wavjudger
    //this function judges the sound+ areas.
    //requires sound1, fs, time, pow as global variables.
    //those are defined in function wavreader.
    //defines judge as a global variable.
    a=input("INPUT 1 TO CONTINUE(DEFAULT), 2 TO clf THEN CONTINUE ..
    3 TO clf, plot sound1 AND CONTINUE");
    select a,
        case 2 then clf;
        case 3 then..
            clf;
            disp("PLOTTING sound1....")
            plot2d(sound1);
    end
    printf("NOW WE NEED THE DEFINITION OF <NEIGHBOUR>.\n..
        SELECT THE WAY TO SPECIFY.\n..
              INPUT 1 TO SPECIFY BY TIME.\n..
              INPUT 2 TO SPECIFY BY THE RATIO TO THE WHOLE .WAV.");
    while %T,..       
        a=input("INPUT?")
        select a,
            case 1 then..
                printf("THE SAMPLING RATE IS %d\n",fs);
                printf("THE LENGTH OF THE FILE IS %f sec\n",time);
                s=input("INPUT THE TIME (IN SEC) WIDTH OF NEIGHBOUR.")
                chop=fs*s;
                break;
            case 2 then..
                printf("THE SAMPLING RATE IS %d\n",fs);
                printf("THE LENGTH OF THE FILE IS %f sec\n",time);
                n=input("HOW MANY CUTS? PLEASE INPUT.")
                chop=length(pow)/n;
                break;
            else..
                disp("UNEXPECTED VALUE.PLEASE INPUT AGAIN.")
        end
    end   
    threshold=input("THE  THRESHOLD?")
    judge=zeros(pow);   
    showjudge=max(sound1);
    disp("NOW JUDGING....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);
    disp("OK. END OF FUNCTION.");
endfunction
//____________________________________________________
function wavcutter
    //requires sound1, judge as global variables.
    //produces syllable as a global variable.
    cuten=[0,judge];
    cutpoint=[];
    disp("NOW FINDING THE CUTPOINT....")
    for i=2:length(cuten)
        if  cuten(1,i-1)==0 & cuten(1,i)~=0 then..
            cutpoint($+1,1)=i-1;
        elseif cuten(1,i-1)~=0 & cuten(1,i)==0 then..
            cutpoint($,2)=i-1;   
        end
    end
    if cutpoint($,2)==0 then cutpoint($,2)=length(judge);
    end
    disp(cutpoint);
    disp("NOW CONTINUE. I WILL GET THE DATA FOR YOU.")
    disp("THE DATA WILL BE COLLECTED IN VARIABLE syllable.")
    a=input("OK? IF NOT, INPUT 0.")
    if a==0 then return;
    end
    disp("OK.PRODUCING syllable....");
    syllable=[];
    for i=1:size(cutpoint,"r")
        syllable($+1,1:1+(cutpoint(i,2)-cutpoint(i,1)))..
        =sound1(cutpoint(i,1):cutpoint(i,2));
    end
    disp("NOW PLOT EACH SYLLABLE. OK ? ");
    a=input("INPUT 0 TO RETURN.");
    if a==0 then return;
    end
    for i=1:size(syllable,"r")
        scf(i);
        plot2d(syllable(i,:));
    end
    disp("END OF FUNCTION.")
endfunction
function wavreadjudgecut
    wavreader;
    a=input("INPUT 1 to CONTINUE");
    if a~=1 then return;
    end
    wavjudger;
    a=input("INPUT 1 TO CONTINUE.");
    if a~=1 then return;
    end
    wavcutter;
endfunction
scf(i) 使った for 文の所で, グラフィックウィンドウが次々開くのはなかなか壮観である.
ちなみに,切れたやつを
playsnd(syllable(i,:),fs)
で再生していくと,割合母音に対応して切れてて楽しかった.

No comments:

Post a Comment