Örnekleme oranı \(44100\) Hz olsun. Yani oluşturacağınız sinyallerin bir saniyesindeki veri sayısı bu olsun. Ses bilgi için [1] numaralı kaynağa bakabilirsiniz.
Bir sinüs sinyali oluşturun. Frekansı 440 Hz, süresi 5 saniye olsun.
Bir sinüs sinyali oluşturun. Frekansı 880 Hz, süresi 5 saniye olsun.
Bu iki sinyali başka bir değişkende toplayın.
Tüm sinyalleri alt alta çizdirin.
Tüm sinyalleri 0.01 saniyeye kadar olan kısmını alt alta çizdirin.
Tüm değişkenleri oranlayın wav dosyası kaydetmek üzere değişkene atayın (scaling).
Tüm değişkenleri write("<dosya_adi>.wav", örneklemeOranı, <degisken>) ile kaydedin.
Şimdi bu adımları kodlayalım.
################################################import osimport sys# Bu dosyanın bulunduğu dizini alcurrent_dir = os.path.abspath('')# 3 üst dizine çık + sesler klasörüsesler_dir = os.path.join(os.path.abspath(os.path.join(current_dir, os.pardir, os.pardir, os.pardir)), 'sesler')# Bu klasör var mı? Yoksa oluşturifnot os.path.exists(sesler_dir):# Oluştur os.makedirs(sesler_dir)# Linux/MacOS için# Eğer OS Linux/Unix iseif sys.platform =="linux"or sys.platform =="linux2"or sys.platform =="darwin": sesler_dir = sesler_dir +"/"# Eğer OS, Windows iseelif sys.platform =="win32": sesler_dir = sesler_dir +"\\"################################################import numpy as npimport matplotlib.pyplot as pltimport scipy.io.wavfile as wavfile# Veriyi oluşturorneklemeOrani=44100# 1 saniyede kaç tane veri var?sure=5# s# Zamant= np.linspace(0, sure, orneklemeOrani* sure)# Sinüs dalgalarıveri1_440Hz= np.sin(2*np.pi*440*t)veri2_880Hz= np.sin(2*np.pi*880*t)veri3= veri1_440Hz + veri2_880Hz# Çizfig, axs= plt.subplots(3,1)axs[0].plot(t, veri1_440Hz)axs[0].set_title("440Hz")axs[0].set_xlim([0, 0.01])axs[1].plot(t, veri2_880Hz)axs[1].set_title("880Hz")axs[1].set_xlim([0, 0.01])axs[2].plot(t, veri3)axs[2].set_title("440Hz + 880Hz")axs[2].set_xlim([0, 0.01])plt.tight_layout()plt.show()# Normalizasyon için [-32767, 32767] kullacağız.# Çünkü 16 bitlik ses dosyaları bu aralıkta değer alır.veri1_440Hz = np.int16((veri1_440Hz/ np.max(np.abs(veri1_440Hz)))*32767)veri2_880Hz = np.int16((veri2_880Hz/ np.max(np.abs(veri2_880Hz)))*32767)veri3 = np.int16((veri3/ np.max(np.abs(veri3)))*32767)# Dosyları wav formatında, ../../../sesler klasörüne kaydetwavfile.write(sesler_dir+"sin1_440Hz.wav", orneklemeOrani, veri1_440Hz)wavfile.write(sesler_dir+"sin2_880Hz.wav", orneklemeOrani, veri2_880Hz)wavfile.write(sesler_dir+"sin3_440Hz880Hz.wav", orneklemeOrani, veri3)
Nota Silme
scipy.io.wavfile modülünü çağırın.
Bir önceki bölümde kaydettiğiniz toplam sinüs dalgası ses dosyasını wavfile.read() ile okuyun.
Ses dosyasının ilk 0.01 saniyesinin grafiğini çizdirin.
Ses dosyasının Fourier analizini yapın.
scipy.fft.fftfreq(len(veri), 1/orneklemOrani) ile frekansları bulun.
Ses dosyasındaki frekansları (HFD) çizdirin.
500 Hz’den büyük tüm frekansları sıfırlayın.
Ters Fourier dönüşümü yapın.
Ses dosyasının ilk 0.01 saniyesini gösterin.
Ters dönüşüm ile elde ettiğiniz ses dosyasını kaydedin.
Şimdi bu adımları kodlayalım.
################################################import osimport sys# Bu dosyanın bulunduğu dizini alcurrent_dir = os.path.abspath('')# 3 üst dizine çık + sesler klasörüsesler_dir = os.path.join(os.path.abspath(os.path.join(current_dir, os.pardir, os.pardir, os.pardir)), 'sesler')# Bu klasör var mı? Yoksa oluşturifnot os.path.exists(sesler_dir):# Oluştur os.makedirs(sesler_dir)# Linux/MacOS için# Eğer OS Linux/Unix iseif sys.platform =="linux"or sys.platform =="linux2"or sys.platform =="darwin": sesler_dir = sesler_dir +"/"# Eğer OS, Windows iseelif sys.platform =="win32": sesler_dir = sesler_dir +"\\"################################################import numpy as npimport matplotlib.pyplot as pltimport scipy.io.wavfile as wavfileimport scipy.fft as fft# sin3_440Hz880Hz.wav dosyasını okuorneklemOrani, veri = wavfile.read(sesler_dir+"sin3_440Hz880Hz.wav")# Süresure=len(veri)/ orneklemOrani# Zaman dizisit= np.linspace(0, sure, len(veri))plt.plot(t, veri)plt.xlim([0,0.01])plt.ylabel("Genlik")plt.xlabel("Zaman (s)")plt.show()plt.close()# HFDveriHFD= fft.fft(veri)# FrekanslarveriHFDFrek= fft.fftfreq(len(veri), 1/orneklemOrani)# Çizplt.plot(veriHFDFrek, np.abs(veriHFD))plt.xlim([-1000,1000])plt.ylabel("|X(f)|")plt.xlabel("Frekans (Hz)")plt.show()plt.close()# 500 Hz'den büyük tüm frekansları sıfırla# (Low Pass Filter)veriHFD[veriHFDFrek >500] =0#veriHFD[veriHFDFrek > 500] = veriHFD[veriHFDFrek > 500]* 0.5veriHFD[veriHFDFrek <-500] =0#veriHFD[veriHFDFrek < -500] = veriHFD[veriHFDFrek < -500]* 0.5 # Çizplt.plot(veriHFDFrek, np.abs(veriHFD))plt.xlim([-1000,1000])plt.ylabel("|X(f)| (Filtreli)")plt.xlabel("Frekans (Hz)")plt.show()plt.close()# THFDveriTHFD_filtreli= fft.ifft(veriHFD)# ZamantTHFD_filtreli=\ np.linspace(0, sure, len(veriTHFD_filtreli))# Çizplt.plot(tTHFD_filtreli, np.real(veriTHFD_filtreli))plt.xlim([0,0.01])plt.ylabel("Genlik")plt.xlabel("Zaman (s)")plt.show()plt.close()# Normalizasyon# Gerek yok ama yine de yapalımveriTHFD_filtreli = np.int16((np.real(veriTHFD_filtreli)/ np.max(np.abs(veriTHFD_filtreli)))*32767)# Dosyları wav formatında kaydetwavfile.write(sesler_dir+"sin3_440Hz880Hz_filtreliLowPass500.wav", orneklemOrani, veriTHFD_filtreli)
Alıştırma 1
Yukarıda yapılan örnekte 500’den küçük frekansları sıfırlayın ve tüm adımları tekrarlayın.
Gürültü ve Ses Dosyası Analizi
Örnekleme oranını 44100 Hz olarak belirleyin.
Toplam 5 saniye olacak şekilde bir zaman dizisi oluşturun.
5 saniyelik rastgele bir sinyal gürültüsü oluşturun. np.rand.randn(arrayBoyutu) kullanabilirsiniz.
5 saniyelik bir sinüs sinyali oluşturun. Frekansı 170 Hz olsun.
Gürültü ve sinüs sinyalini toplayın ve yeni bir değişkene atayın.
Tüm değişkenleri oranlayın (scaling) ve write("<dosya_adi>.wav", örneklemeOranı, <oranli-degisken>) ile kaydedin.
Sinüs, gürültü ve toplam sinyallerinin ilk 0.1 saniyesini aynı grafikte alt alta çizdirin.
3 adet sinyalin hızlı Fourier dönüşümünü (scipy.fft.fft()) yapın.
3 adet sinyalin frekanslarını (scipy.fft.fftfreq(len(veri), 1/orneklem_orani)) hesaplayın. Frekans miktarı verinizden bağımsız olacaktır. Sadece verinizin örnekleme oranı (verinin büyüklüğü) ve saniyede kaç örnekleme yaptığınız önemlidir.
Frekans uzayını, 3 adet alt alta grafik olacak şekilde çizdirin.
Toplam sinyalden gürültü frekansını silin.
Filtrelenmiş sinyalin Fourier dönüşümünü, karşılaştırmalı olarak çizdirin.
Ters Fourier dönüşümü yapın ve filtrelenmiş sinyalin ilk 0.1 saniyesi ile filtrelenmemiş sinyalin ilk 0.1 saniyesini grafik üzerinde karşılaştırın.
Filtrelenmiş sinyali wav dosyası olarak kaydedin.
################################################import osimport sys# Bu dosyanın bulunduğu dizini alcurrent_dir = os.path.abspath('')# 3 üst dizine çık + sesler klasörüsesler_dir = os.path.join(os.path.abspath(os.path.join(current_dir, os.pardir, os.pardir, os.pardir)), 'sesler')# Bu klasör var mı? Yoksa oluşturifnot os.path.exists(sesler_dir):# Oluştur os.makedirs(sesler_dir)# Linux/MacOS için# Eğer OS Linux/Unix iseif sys.platform =="linux"or sys.platform =="linux2"or sys.platform =="darwin": sesler_dir = sesler_dir +"/"# Eğer OS, Windows iseelif sys.platform =="win32": sesler_dir = sesler_dir +"\\"################################################import numpy as npimport matplotlib.pyplot as pltimport scipy.io.wavfile as wavfileimport scipy.fft as fft# Veriyi oluşturorneklemeOrani=44100sure=5# s# Zamant= np.linspace(0, sure, orneklemeOrani* sure)# Sinüs dalgalarıveri4_170Hz= np.sin(2*np.pi*170*t)veri5_Gurultu= np.random.rand(len(t))veri6_topla= veri4_170Hz+ veri5_Gurultu# Çizfig, axs= plt.subplots(3,1)axs[0].plot(t, veri4_170Hz)axs[0].set_title("170Hz")axs[0].set_xlim([0, 0.01])axs[1].plot(t, veri5_Gurultu)axs[1].set_title("Gürültü")axs[1].set_xlim([0, 0.01])axs[2].plot(t, veri6_topla)axs[2].set_title("Gürültü+170Hz")axs[2].set_xlim([0, 0.01])plt.tight_layout()plt.show()plt.close()# Wav dosyası olarak kaydetwavfile.write(sesler_dir+"sin4_170Hz.wav", orneklemeOrani, np.int16((np.real(veri4_170Hz)/ np.max(np.abs(veri4_170Hz)))*32767))wavfile.write(sesler_dir+"gurultu.wav", orneklemeOrani, np.int16((np.real(veri5_Gurultu)/ np.max(np.abs(veri5_Gurultu)))*32767))wavfile.write(sesler_dir+"sin4_170Hz_gurultulu.wav", orneklemeOrani, np.int16((np.real(veri6_topla)/ np.max(np.abs(veri6_topla)))*32767))# HFDhfd_veri4_170Hz= fft.fft(veri4_170Hz)hfd_veri5_Gurultu= fft.fft(veri5_Gurultu)hfd_veri6_topla= fft.fft(veri6_topla)# Frekanslarhfd_veri4_170HZ_frek= fft.fftfreq(len(veri4_170Hz), 1/orneklemeOrani)hfd_veri5_Gurultu_frek= fft.fftfreq(len(veri5_Gurultu), 1/orneklemeOrani)hfd_veri6_topla_frek= fft.fftfreq(len(veri6_topla), 1/orneklemeOrani)# Çizfig, axs= plt.subplots(3,1)axs[0].plot(hfd_veri4_170HZ_frek, np.abs(hfd_veri4_170Hz))axs[0].set_title("HFD-170Hz")axs[0].set_xlim([-1000, 1000])axs[1].plot(hfd_veri5_Gurultu_frek, np.abs(hfd_veri5_Gurultu))axs[1].set_title("HFD-Gürültü")axs[1].set_xlim([-1000, 1000])axs[2].plot(hfd_veri6_topla_frek, np.abs(hfd_veri6_topla))axs[2].set_title("HFD-Toplam")axs[2].set_xlim([-1000, 1000])plt.tight_layout()plt.show()plt.close()# Toplam sinyalden gürültüyü çıkarhfd_veri7_topla_filtre= hfd_veri6_topla - hfd_veri5_Gurultu# Çizfig, axs= plt.subplots(2,1)axs[0].plot(hfd_veri6_topla_frek, np.abs(hfd_veri6_topla))axs[0].set_title("HFD-Toplam")axs[0].set_xlim([-1000, 1000])axs[1].plot(hfd_veri6_topla_frek, np.abs(hfd_veri7_topla_filtre))axs[1].set_title("HFD-Toplam-Gürültüsüz")axs[1].set_xlim([-1000, 1000])plt.tight_layout()plt.show()plt.close()# Ters HFDveri7_topla_filtre= fft.ifft(hfd_veri7_topla_filtre)# Çizfig, axs= plt.subplots(2,1)axs[0].plot(t, np.abs(veri6_topla))axs[0].set_title("Toplam-Veri")axs[0].set_xlim([0, 0.01])axs[1].plot(t, np.real(veri7_topla_filtre))axs[1].set_title("Toplam-Veri-Gürültüsüz")axs[1].set_xlim([0, 0.01])plt.tight_layout()plt.show()plt.close()# Wav dosyası olarak kaydetwavfile.write(sesler_dir+"sin4_170Hz_gurultulu_filtreli.wav", orneklemeOrani, np.int16((np.real(veri7_topla_filtre)/ np.max(np.abs(veri7_topla_filtre)))*32767))
Observation of Gravitational Waves from a Binary Black Hole Merger başlığına tıklayınız. Burada hem Hanford hem de Livingston merkezlerinden alınan veriler bulunmaktadır.
Bu dosyaları pandas kütüphanesini kullanarak okuyun, pandas.read_csv("<LINK>, skiprows=1, sep=" ", header=None") .
Verilerin grafiğini üst üste çizdirin.
Verileri wav dosyası olarak kaydedin. (https://www.youtube.com/watch?v=TWqhUANNFXw)
Verilerin Fourier dönüşümünü yapın ve grafiklerini çizdirin.
Problem 2
Gürültü Silme
Gürültü filtreleme işlemini problem2-gurultulu-sinyal.wav dosyası için yapın. Dosyaya bu linkten ulaşabilirsiniz. Bu dosya C akoru ve G akorunu ardı ardına eklenerek oluşturulmuştur.
Ses dosyasını tam ortadan ikiye ayırın.
İlk yarısına hfd yapın. Bu frekansların 261.63 Hz, 329.63 Hz ve 392.0 Hz olduğunu göreceksiniz.
Bu frekanslar dışındaki tüm frekansları sıfırlayın.
İkinci yarısına hfd yapın. Bu frekansların 392.0 Hz, 493.88 Hz ve 293.66 Hz olduğunu göreceksiniz.
Bu frekanslar dışındaki tüm frekansları sıfırlayın.
Ardından bu iki dosyanın ters hfd’sini alın ve birleştirin.
Filtrelenmiş ses dosyasını problem2-gurultusuz-sinyal.wav olarak kaydedin.
Problem 3
/sesler/ klasörünün içerisinde bulunan DeepPurple_SmokeOnTheWaterIntro.wav dosyasını orneklemOrani, data = wavfile.read() olacak şekilde okuyun. Bu kayıt stereo bir dosyadır ve data değişkeninin ilk sütununu almanız yeterlidir. Bu işlem ile stereo ses kaydının sadece bir tarafını alıyorsunuz.
Sinyali 4’e ayırın. Bunun için aşağıda verilen tablodaki süreleri kullanın. Yardım: t zaman arrayiniz olsun. \(t=2\) saniyeye karşılık gelen argümanı bulmak için arg1=np.argmin(np.abs(t- 2)) komutunu kullanabilirsiniz. Yani arg1 değişkeni 100 gibi bir değer olursa t[arg1] değeri \(2\) saniye olacaktır.
Ayrılan riffleri zamana göre fig, axs= plt.subplots(4, 1) komutunu kullanarak 4 ayrı grafikte çizdirin. axs[0].plot() komutunu kullanın. Güzel gözükmesini istiyorsanız grafiği göstermeden önce fig.tight_layout() komutunu kullanabilirsiniz.
Ayırdığınız riffleri ayrı ayrı wav dosyası olarak kaydedin.
Tüm rifflerin Fourier dönüşümlerini alın ve frekanslarını belirleyin.
Tüm rifflerin pozitif frekans uzaylarını alt alta çizdirin. axs[0].set_xlim(0, 1000) komutunu kullanarak x-eksenini \(0\) ile \(1000\) arasında limitleyebilirsiniz.
ilk riff verisinin pozitif frekans uzayında gördüğünüz tepe (peak) değerleri hangi frekansa denk geliyor, bulun, ekrana yazdırın ve Fourier dönüşümü grafiğinde gösterin (plt.axvline(x= hfdfrek_riff1_tepeler_pozitif[0], color= "red", lw= 0.5, ls= "--")). Yardım: “fft verisinde hangi değerler fft > 9e6 koşulunu sağlanıyor?” sorusuna cevap olacak şekilde bir komut yazabilirsiniz.