Python ile Müzik Yapalım

Sıddık Açıl
Jul 20, 2017 · 5 min read

Merhabalar. Öncelikle ilk yazıma duyduğunuz ilgi için teşekkür ederim.

Python’da yapabileceğimiz en eğlenceli şeylerden biri de müzik yapmak. Müzik yapmak için bize ses dalgalarının temelinde yatan matematiksel ilişkileri koda aktarmak için NumPy, dalgaları görselleştirmek için Matplotlib ve oluşturduğumuz dalgaları saklamak için Python’ın kendi içinde bulunan “wave” modülünü kullanacağız.

Teorik Arka Plan

Yazıda kullanılacak temel kavramları açıklayalım.

Dalga Boyu(Wavelength)

Bir dalganın iki tepe noktası arasında kalan uzaklığa denir.

Frekans(Frequency)

Bir dalganın saniyede katettiği dalga boyu sayısının ölçüsüdür. Frekans arttıkça, dalga boyu azalır; dalga boyu arttıkça, frekans azalır.

Genlik(Amplitude)

Bir dalgada tepenin çukura olan uzaklığının yarısına denir.

Sample Rate

Bildiğiniz gibi bilgisayarlar bilgiyi ayrık -discrete- parçalar halinde tutarlar. Fakat ses dalgaları süreklidir -continuous-. Bunu bir bilgisayarın görselleri saklamasına benzetebiliriz. Biz etrafımıza baktığımızda cisimlerden gelen renkleri sürekli bir şekilde görürüz ama bilgisayar için bir görsel iki boyutlu bir renkler arrayinden ibarettir.

Sampling olayının amacı sürekli bir nokta kümesinden bilgisayarda ifade edilebilecek cinste sonlu -eleman sayısı sonsuz olmayan- bir array oluşturmaktır. Sample rate ise bir saniyelik bir sesten kaç sample alacağımızın ölçüsüdür. Endüstride ses için genelde 44100 ve 48000 sampling rate kullanılır.

Nyquist’in Sampling Teoremi

Eski bir bilim adamı amca olan Nyquist bir sampling yapılıyorsa
Sample Rate o dalga içinde bulunan en büyük frekansın iki katından büyük olmalıdır der. İnsanın duyabileceği en yüksek frekansın 20000 civarında olduğunu göz önünde bulundurursak Nyquist’in teoremine göre bu dalgayı en az 40000 Sample Rate ile ‘sample’lamalıyız.

Superposition

Dalgaların üst üste bindirilerek toplanması olayıdır.

Ses Dalgası

Ses kaynaklarının atmosferi sıkıştırmasıyla oluşan periyodik dalgalardır. Her periyodik dalga Sinüzoidal Dalgaların toplamı şeklinde ifade edilebilir.

Sinüzoidal Dalga

Genel ifadesi A * sin(wt) olan dalgalara denir.

  • w = Açısal frekans = 2 * Pi * Frekans
  • t = Zaman
  • A = Genlik

Müzik Yapalım

Yukarıda ses dalgasının sinüzoidalların toplamı olduğunu söyledik. Sinüzoidal dalganın formülünün ses dalgası oluşturmadaki kullanımını aşağıda gözlemleyelim.

İlk Dalgamızı Oluşturup Grafiğini Çizelim

Parametrelerimizi atadıktan sonra NumPy’ın linspace fonksiyonu X ekseninde 0 ile 1 arasını 48000 eşit parçaya böldük. Aşağıdaki satırda ise her X ekseninde elde ettiğimiz her noktayı sinüzoidal formülünde yerine koyduk ve dalganın grafiğini çizdirdik.

NumPy’a yabancı olan arkadaşlar np.sin fonksiyonu her nokta için nasıl çağrıldı anlamamış olabilirler. Bu NumPy’ın “Broadcast” özelliğinden geliyor. NumPy öğrenmek ve ya bilgilerini tazelemek için aşağıdaki linki takip edebilirsiniz.

Bir La Notası Oluşturup Grafiğini Çizelim

Yukarıdaki kod parçasında frekansı 440 olarak değiştirirsek La notasını elde ediyoruz.

La ile Mi Notaları Superpose Olduğunda: La Beşli Akoru

Kod mantığını sınıf yapısı içine alarak okunabilirliği arttırdık. Fakat matematiksel olarak değişen hiç bir şey yok. Sınıfımıza ‘superpose’ metodu ekledik. Superpose işlemini aşağıdaki örnekle pekiştirelim:

10 metre yüksekliğindeki iki dalga birbiri üstüne binip 20 metre yüksekliğe erişiyorlar. 10 metre yüksekliğinde bir dalga ile 5 metre derinliğinde bir dalga birbirini götürüp 5 metre yüksekliğinde kalıyorlar.

La ve Mi notalarını beraber çalarak rock ve metal müzikte sıkça kullanılan Beşli akor -Power Chord- oluşturduk.

Müziğimizi Kaydedelim

Müzik dosyaları ‘binary’ dosyalardır. ‘WB’ modunda bir dosya açıp kodda ayrıntılarını açıkladığım .WAV formatına ait parametreleri atadık.

Kanal sayisi burda sesin mono mu stereo mu olduğunu belirliyor. Bitwidth ise her sample içinde bulunan verinin kaç bitlik yer tutacağını ayarlamak için kullanılan bir parametre. Eski sistemlerde 8-bit sesler kullanılıyordu -atari oyunlarından hatırlayacağımız üzere :)- günümüzde ise 16 ve ya 32 bitlik sesler ile çalışıyoruz.

Kod içi yorumlarda ayrıntılarıyla açıkladığım ‘gensin’ fonksiyonu ise sinyallerimizi alıp onları dosyaya yazılabilecek hale getiriyor.

Kaynak:

Tını ve Ton(Tone) Kavramları (Opsiyonel)

Tını bir enstrümanı bir diğerinden ayırt edebilmemize yarayan özelliktir. Tını kavramını anlamak için öncelikle Ton(tone) ve Overtone kavramını kavrayalım.

Ton: Bir enstrümanda bir nota çalındığında aslında bir çok nota aynı anda titrer. Bunlar arasında kulağımızın algıladığı nota tondur. Tondan daha yüksek frekanslı olan diğer notalara ise overtone denir.

Tını: Farklı enstrümanlarda aynı tona sahip seslerin farklı duyulmasının sebebidir. Ton harici kalan sinüzoidalların genlikleri her enstrüman için farklı farklıdır. Bu yüzden bir gitarın sesi piyanonunkinden farklıdır.

Biz burada sadece temel tona ait sinüzoidallardan müzik oluşturduğumuzdan kulağa yavan gelmesi doğal. Yaptığımız müzik aslında farklı frekanslarda titreyen diyapozonlara vurarak oluşturulan müzikle aynı. Bunun sebebi diyapozonda overtoneların var olmamasıdır.

Daha Anlaşılır Bir Gösterim: Fourier Dönüşümü (Opsiyonel)

İki notayı superpose edip grafiğini çıkartınca her ne kadar göze hoş gözükse de bizim için çok bir anlam ifade etmiyor. Okul müfredatı ses dalgalarını sadece Zaman-Genlik açısından ele alıyor. Fakat bir sinyale Frekans-Genlik ilişkisi açısından bakmak bizim için daha anlaşılır ve bir çok durumda çok çok daha kullanışlı.

Aşağıda NumPy.fft ile yapılmış bir Fourier dönüşümünü ve Frekans-Genlik grafiğini inceleyelim:

Tempo Ekleyelim

Müziksel ölçüler hakkında bilgi sahibi değilseniz aşağıdaki özeti okuyabilirsiniz.

Tempo(BPM) bir dakikadaki beat sayısıdır. 4/4'lük ölçüsü olan bir şarkıda her beat bir 4'lük notaya denk gelir. Tempomuz 60 ise her saniyede bir 4'lük nota çalınır. 60 tempo için ölçülerin saniye cinsinden süreleri aşağıdaki gibidir:

  • 1 : 4s
  • 2 : 2s
  • 4 : 1s
  • 8 : 0.5s
  • 16 : 0.25s
  • 32 : 0.125s

‘measure_to_seconds’ fonksiyonu tempo ve ölçü bilgilerini alarak bunu saniyeye çevirirken yukarıdaki yapıtı kullanıyor.

Özet

Buraya kadar geldiyseniz öncelikle tebrikler. Şu anda eski Nokia telefonlarda bulunan Besteleyici programını yapabilecek kadar bilgi sahibisiniz. Burada bulunanlardan başka notaların frekans tablolarını aşağıdaki kaynaktan bulabilirsiniz. Akorların içerdiği notaların da listesi de keza internette bir çok yerde mevcut. Bu konuda daha ileri düzey bir çalışma yapmak için Besteleyici klonu yazabilirsiniz.

Ekstra

Bu yazının ekstralar kısmında yukarıda kısaca bahsettiğimiz FFT’ye değinmek istiyorum.

FFT Kullanarak Sesi Gürültüden Arındırma

FFT’nin kullanım alanlarından biri de sesi gürültüden arındırmaktır. Burada gürültüden kasıt Genlikleri çok küçük olan sinüzoidallardır. Bu gürültüler genelde kayıt ortamından, kaydın gerçekleştiği elektronik devreden ve ya ara aktarma kablolarından kaynaklanmakta olup sesin kalitesini düşürürler. Böyle durumlarda elimizdeki sinyalin Frekans-Genlik gösteriminde genlik değeri belirli bir eşik değerinin(threshold) altında olan sinüzoidalların genliklerini 0(sıfır) yapmak suretiyle sesi gürültüden arındırıp kalitesini arttırabiliriz

IFFT

Nasıl Zaman-Genlik gösteriminden Frekans-Genlik gösterimine geçiyorsak tersi de Inverse Fourier Transform(Tersine Fourier Dönüşümü) ile mümkün. Yukarıdaki gürültü örneğinde gürültüden arındırılmış ses Zaman-Genlik gösterimine geri getirilip kaydedilebilir.

)

Sıddık Açıl

Written by

ITU CS Graduate. Ericsson Türkiye

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade