9 Ekim 2014 Perşembe

SES BÖLÜTLEME

Merhaba arkadaşlar, bu yazımda size matlab ortamında dışarıdan alınan bir sesin enerji spectrumunu çıkartıktan sonra  sesli sessiz bölge tespiti yaparak konuşma içinde geçen kelimeleri ayrı ayrı bölütleme işlemini anlatacağım. Lafı daha fazla uzatmadan kodlara geçmek istiyorum.

[speech,fs,nbits]=wavread('ses.wav');  %Bölütlenecek ses dosyası okunuyor.
window_ms = 100;  % Örnekleme periyodu belirleniyor
threshold = 1;     % Sesli bölge eşik değeri belirleniyor
k_s=0;

% alinacak parcalarin sample sayisi
window = window_ms*fs/1000;  %alinacak parcalarin sample sayisi hesaplanıyor
speech2 = speech(1:(length(speech) - mod(length(speech),window)),1); % sinyal uzunlugu kontrolu
samples = reshape(speech2,window,length(speech2)/window); % yapılıyor.

energies = sqrt(sum(samples.*samples))'; % Mühendislik öğrencilerinin aşina olduğu bir formül ;
%sinyalin samplelarının karelerinin toplamı enerji değerini veriyordu. Burada da bu işlem yapılarak
%energies dizisine sesin enerji değerleri atıldı.
vuv = energies > threshold;% Bu satırda eşik değerimizi geçen örneklenmiş aralıkları 1 , eşik değerin
%altında kalan satırları 0 olarak atıyoruz.

 plot(energies); komutu ile hesapladığımız enerji dizisini çizdirip sesli  sessiz bölgeleri görme imkanı bulabiliyoruz. Kaydettiğim sesde 4 kelime bulunmakta. Bu grafikte bunu görebilmekteyiz.




plot(vuv) ; komutu ile eşik değerlerini belirlediğimiz diziyi çizdirdik. Bu grafikte sesli ve sessiz bölgeler net bir biçimde tespit edilmiş durumda. Şimdi basit bir algoritma geliştirerek seslerimizi bölütleyip 4 yeni ses dosyası halinde kaydedelim.



% Bölütlemede kullanılan algoritma ; seslerin hangi örnekleme aralığında başlayıp hangi örnekleme aralığında bittiğini belirleme üzerine çalışmaktadır.

z=length(energies);    %energies dizisinin uzunluğu belirleniyor.
a=1;
t=1;
%Bu döngüde  1 den sonra 0 gelen kaç örnekleme olduğunu tespit ediyoruz. Bu şekilde kaydımızda kaç kelime olduğunu anlıyoruz.Daha sonra bas ve son olmak üzere iki tane dizi tanımlıyoruz.
        for j=1:z;
            if((vuv(j)==1) && (vuv(j+1)==0));
                k_s=k_s+1;
            end  
        end
bas=zeros(1,k_s);
son=zeros(1,k_s); 

% Bu döngüde 0 dan sonra bir gelen örneklerin(sample) yeri tespit ediliyor ve örnekleme aralığı değerimiz(window_ms) olan 4800 ile çarpılarak kelimenin başlangıç noktası belirleniyor. Burada bas(i) i 'inci kelimenin başlama noktasını belirtiyor.
        for i=1:k_s
            for k=a:z
                if((vuv(k)==0) && (vuv(k+1)==1)); break;
                end
            end
            a=k+1;
            bas(i)=k*4800;
        end
%Bu döngüde 1 den sonra 0 gelen örneklerin (sample) yeri tespit ediliyor ve örnekleme aralığı olan window_ms değerimizle çarpılarak kelimenin biriş noktası belirleniyor. Burada son(e)  e' inci kelimenin bitiş noktasını belirtiyor.

        for e=1:k_s
            for r=t:z
                if((vuv(r)==1) && (vuv(r+1)==0)); break;
                end
            end
            t=r+1;
            son(e)=r*4800;
        end

% Bölütlenen kelimeleri her birini yeni bir ses dosyası halinde yazdırıyoruz. Bu yazdırma işlemini detaylı bir şekilde anlatmayacağım. Daha önceki yazılarımda buna detaylıca değinmiştim.
    k1=bas(1):son(1);
    wavwrite(y(k1),fs,'d1.wav');
    k2=bas(2):son(2);
    wavwrite(y(k2),fs,'d2.wav');
    k3=bas(3):son(3);
    wavwrite(y(k3),fs,'d3.wav');
    k4=bas(4):son(4);
    wavwrite(y(k4),fs,'d4.wav');

Örnek ses dosyasını vermiyorum arkadaşlar.Sizler de kendinizin kaydettiği birden fazla kelimeden oluşan bir ses dosyasını sisteminize tanıtarak bölütleme işlemini yapabilirsiniz.

3 yorum :

  1. abi kodu yazdık çalışmadı
    speech2=speech(1:(length(speech) - mod(length(speech),window)),1); komutunda hata veriyor bi yardım et

    YanıtlaSil
  2. okuduuun mektebin :)Hasan BABATİGİT..

    YanıtlaSil
  3. Gülüm tekrar kontrol et, yazım hatası vardır. Bizde çalışıyor

    YanıtlaSil