Kurs içeriği (6 / 10)
  1. 1 Raspberry Pi ile Tanışma ve Kurulum 80 dk
  2. 2 Makine Öğrenmesi Nedir? İlk Modelimiz 80 dk
  3. 3 Kamera ve Görüntü İşlemenin Temelleri 80 dk
  4. 4 Görüntü Veri Seti Hazırlama 80 dk
  5. 5 Görüntü Tanıma Modeli Eğitip Pi’de Çalıştırma 120 dk
  6. 6 Mikrofon ve Sesin Temelleri 80 dk
  7. 7 Ses Veri Seti Hazırlama 80 dk
  8. 8 Ses Tanıma Modeli ile Sesli Komutlar 120 dk
  9. 9 Yapay Zekâyı Donanıma Bağlama: LED, Buzzer ve Servo 80 dk
  10. 10 Mini Proje: Akıllı Geri Dönüşüm Kutusu 160 dk

Raspberry Pi ile Makine Öğrenmesi: Görüntü ve Ses Tanıma · Ders 6 / 10

Mikrofon ve Sesin Temelleri

Konu anlatımı ⏱ 80 dk

Sesin bir dalga olduğunu, frekans, genlik ve örnekleme hızı kavramlarını öğreniyoruz. USB mikrofonu Raspberry Pi’ye bağlayıp sounddevice ile kayıt yapıyor, kaydı WAV dosyası olarak saklıyoruz. NumPy ve matplotlib ile bir sesin dalga formunu ve spektrogramını çizip yorumluyoruz.

Bu derste

  • Sesin dalga olarak yapısını; frekans, genlik ve örnekleme hızı kavramlarını açıklar.
  • USB mikrofonu Raspberry Pi’ye bağlar ve arecord ile sounddevice üzerinden tanıtır.
  • sounddevice ile ses kaydedip WAV dosyası olarak saklar.
  • Bir WAV dosyasını NumPy ile okuyup süresini, genliğini ve ses düzeyini hesaplar.
  • Bir sesin dalga formunu ve spektrogramını çizip yorumlar.

Malzemeler

  • Raspberry Pi 5 veya 4
  • USB mikrofon
  • Kulaklık veya hoparlör (isteğe bağlı)
  • Thonny ve yzenv sanal ortamı
  • sounddevice, NumPy ve matplotlib

Kutumuzun gözleri hazır; şimdi sıra kulaklarında. Sesli komutları tanıyan bir model eğitmeden önce bilgisayarın sesi nasıl kaydettiğini ve “gördüğünü” anlamamız gerekiyor. Bu derste sesin içine bakacağız.

Dersin Amacı ve Kazanımlar

Bu dersin sonunda:

  1. Frekans, genlik ve örnekleme hızı kavramlarını açıklayabileceksiniz.
  2. USB mikrofonu Raspberry Pi’ye bağlayıp tanıtabileceksiniz.
  3. sounddevice ile ses kaydedip WAV dosyası olarak saklayabileceksiniz.
  4. Bir WAV dosyasının süresini, genliğini ve ses düzeyini hesaplayabileceksiniz.
  5. Bir sesin dalga formunu ve spektrogramını çizip yorumlayabileceksiniz.

Gerekli Malzemeler

Malzeme Açıklama
Raspberry Pi 5 veya 4 Ders 1’deki kurulum yapılmış olmalı. Pi’nin kendi mikrofonu yoktur.
USB mikrofon Basit bir USB mikrofon ya da mikrofonlu USB ses kartı yeterlidir. Mikrofonlu web kameraları da çoğunlukla çalışır.
Kulaklık veya hoparlör Kaydı dinlemek için; HDMI ekranın hoparlörü de olur.
sounddevice, NumPy, matplotlib Ders 1’de kuruldu (libportaudio2 sistem paketi dâhil).

💡 İpucu

Ses dersi sınıfta biraz gürültülü geçebilir. Kayıtları sırayla yapın ya da grupları sınıfın farklı köşelerine dağıtın. Mikrofonu ağzınıza 20–30 cm uzaklıkta tutun; çok yakından konuşmak sesi bozar.

Ses Nedir?

Ses, havadaki basınç değişimlerinin dalgalar hâlinde yayılmasıdır. Mikrofon bu basınç değişimlerini elektrik sinyaline çevirir. Bir ses dalgasının iki temel özelliği vardır:

  • Frekans: Dalganın bir saniyede kaç kez titreştiğidir, birimi hertz (Hz). Frekans yükseldikçe ses incelir (tizleşir). Piyanodaki “la” notası 440 Hz’dir; insan kulağı yaklaşık 20 Hz ile 20 000 Hz arasını duyar.
  • Genlik: Dalganın yüksekliğidir. Genlik büyüdükçe ses yükselir.

Bilgisayar sürekli bir dalgayı olduğu gibi saklayamaz. Bunun yerine dalganın değerini çok kısa aralıklarla ölçer. Buna örnekleme denir. Örnekleme hızı saniyedeki ölçüm sayısıdır. Konuşma tanımada genellikle 16 000 Hz yeterlidir; müzik CD’leri 44 100 Hz kullanır. Her ölçümü 16 bitlik bir tam sayı olarak (-32768 ile 32767 arası) saklarız.

Bir ses dalgasının örneklenmesi

Mikrofonu Tanıtma

USB mikrofonun Raspberry Pi’ye takılması

USB mikrofonu takın ve terminalde kayıt yapabilen cihazları listeleyin:

# Kayıt yapabilen ses kartlarını listele
arecord -l
**** List of CAPTURE Hardware Devices ****
card 2: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Bu çıktıda mikrofonumuz card 2, device 0. Bu bilgiyle terminalden üç saniyelik bir deneme kaydı yapıp dinleyebiliriz:

# card 2, device 0 → plughw:2,0  (kendi numaralarınızı yazın)
arecord -D plughw:2,0 -f S16_LE -r 16000 -c 1 -d 3 deneme.wav
aplay deneme.wav

Python’da sounddevice kütüphanesi de cihazları listeleyebilir. Listedeki numarayı kayıt programında kullanacağız:

# dosya: cihazlar.py
import sounddevice as sd
print(sd.query_devices())

Örnek çıktı: (Raspberry Pi 5 üzerinde örnek çıktı. Cihaz adları ve numaraları mikrofonunuza göre değişir. Satır başındaki * işareti varsayılan cihazı gösterir.)

  0 vc4-hdmi-0: MAI PCM i2s-hifi-0 (hw:0,0), ALSA (0 in, 2 out)
  1 USB PnP Sound Device: Audio (hw:2,0), ALSA (1 in, 0 out)
  2 pipewire, ALSA (64 in, 64 out)
* 3 default, ALSA (64 in, 64 out)

Python ile Ses Kaydetme

# dosya: ses_kaydet.py
import sounddevice as sd
import numpy as np
import wave

ORNEKLEME = 16000     # saniyede 16 000 ölçüm
SURE = 3              # saniye
CIHAZ = None          # None: varsayılan cihaz; ya da listedeki numara (ör. 1)

print("Kayıt başlıyor... Konuşun!")
kayit = sd.rec(int(SURE * ORNEKLEME), samplerate=ORNEKLEME,
               channels=1, dtype="int16", device=CIHAZ)
sd.wait()             # kayıt bitene kadar bekle
print("Kayıt bitti.")

with wave.open("kayit.wav", "wb") as f:
    f.setnchannels(1)          # mono
    f.setsampwidth(2)          # 16 bit = 2 bayt
    f.setframerate(ORNEKLEME)
    f.writeframes(kayit.tobytes())

print("Örnek sayısı:", len(kayit))
print("En yüksek genlik:", int(np.abs(kayit).max()), "/ 32767")

Örnek çıktı: (Raspberry Pi 5 ve USB mikrofonla örnek çıktı. Genlik değeri sesinizin yüksekliğine ve mikrofona uzaklığınıza göre değişir.)

Kayıt başlıyor... Konuşun!
Kayıt bitti.
Örnek sayısı: 48000
En yüksek genlik: 14873 / 32767

sd.rec() kaydı arka planda başlatır ve hemen döner; sd.wait() kayıt bitene kadar programı bekletir. Kayıt bir NumPy dizisi olarak gelir: 3 saniye × 16 000 = 48 000 sayı. wave modülü Python ile hazır gelir ve bu sayıları standart bir WAV dosyasına yazar.

Bazı USB mikrofonlar doğrudan 16 000 Hz’de kayıt yapmayı desteklemez ve “Invalid sample rate” hatası verir. Bu durumda CIHAZ değerini None bırakın: Varsayılan cihaz sesi sizin için dönüştürür. Olmazsa ORNEKLEME değerini 44100 ya da 48000 yapın.

Sesin İçine Bakmak

Mikrofonunuz yoksa ya da herkesin aynı sonucu görmesini istiyorsak, sesi kendimiz üretebiliriz. Aşağıdaki program beş parçalı bir deneme sesi oluşturur: 440 Hz’lik bir nota, sessizlik, bir oktav tiz nota, hışırtı ve gittikçe tizleşen bir ıslık.

# dosya: sentetik_ses.py  (mikrofonunuz yoksa deneme sesi üretir)
import numpy as np
import wave

ORNEKLEME = 16000
rng = np.random.default_rng(1)
t = np.arange(int(0.5 * ORNEKLEME)) / ORNEKLEME     # 0,5 saniyelik zaman ekseni

parcalar = [
    0.6 * np.sin(2 * np.pi * 440 * t),                       # 440 Hz (la notası)
    np.zeros_like(t),                                        # sessizlik
    0.6 * np.sin(2 * np.pi * 880 * t),                       # 880 Hz (bir oktav tiz)
    np.clip(0.15 * rng.normal(0, 1, len(t)), -0.6, 0.6),     # hışırtı (gürültü)
    0.5 * np.sin(2 * np.pi * (300 * t + 1500 * t ** 2)),     # tizleşen ıslık
]
ses = np.concatenate(parcalar)
ses = ses + 0.005 * rng.normal(0, 1, len(ses))               # hafif ortam gürültüsü
veri = (np.clip(ses, -1, 1) * 32767).astype(np.int16)

with wave.open("ornek_ses.wav", "wb") as f:
    f.setnchannels(1)
    f.setsampwidth(2)
    f.setframerate(ORNEKLEME)
    f.writeframes(veri.tobytes())
print("ornek_ses.wav hazır:", len(veri) / ORNEKLEME, "saniye")

Beklenen çıktı:

ornek_ses.wav hazır: 2.5 saniye

Şimdi bu sesi (ya da kendi kayit.wav dosyanızı) analiz edelim:

# dosya: ses_analiz.py
import wave
import numpy as np
import matplotlib.pyplot as plt

DOSYA = "ornek_ses.wav"       # kendi kaydınız için "kayit.wav" yazın

with wave.open(DOSYA, "rb") as f:
    ornekleme = f.getframerate()
    kanal = f.getnchannels()
    ham = f.readframes(f.getnframes())
ses = np.frombuffer(ham, dtype=np.int16).astype(np.float32) / 32768   # -1..1 aralığı

print("Kanal sayısı:", kanal)
print("Örnekleme hızı:", ornekleme, "Hz")
print("Süre:", round(len(ses) / ornekleme, 2), "saniye")
print("En yüksek genlik:", round(float(np.abs(ses).max()), 2))

# Her 0,5 saniyelik bölümün ses düzeyi (RMS)
parca = ornekleme // 2
for i in range(0, len(ses), parca):
    bolum = ses[i:i + parca]
    rms = np.sqrt(np.mean(bolum ** 2))
    print(f"  {i / ornekleme:.1f}-{(i + parca) / ornekleme:.1f} s  RMS: {rms:.3f}  " + "#" * int(rms * 60))

zaman = np.arange(len(ses)) / ornekleme
plt.figure(figsize=(10, 4))
plt.plot(zaman, ses, linewidth=0.5)
plt.title("Dalga formu")
plt.xlabel("Zaman (s)")
plt.ylabel("Genlik")
plt.tight_layout()
plt.savefig("dalga_formu.png", dpi=160)

plt.figure(figsize=(10, 4))
plt.specgram(ses, NFFT=512, Fs=ornekleme, noverlap=384, cmap="magma")
plt.title("Spektrogram")
plt.xlabel("Zaman (s)")
plt.ylabel("Frekans (Hz)")
plt.colorbar(label="Güç (dB)")
plt.tight_layout()
plt.savefig("spektrogram.png", dpi=160)
print("Grafikler kaydedildi.")

Beklenen çıktı:

Kanal sayısı: 1
Örnekleme hızı: 16000 Hz
Süre: 2.5 saniye
En yüksek genlik: 0.62
  0.0-0.5 s  RMS: 0.424  #########################
  0.5-1.0 s  RMS: 0.005  
  1.0-1.5 s  RMS: 0.424  #########################
  1.5-2.0 s  RMS: 0.150  ########
  2.0-2.5 s  RMS: 0.354  #####################
Grafikler kaydedildi.

RMS (karekök ortalama), bir bölümdeki ses düzeyinin ölçüsüdür. Satır sonundaki # işaretleri bunu küçük bir çubuk grafik gibi gösteriyor. 0,5–1,0 saniye arasındaki sessizlik bölümünde RMS neredeyse sıfır. Bu hesap, ileride kaydın içinde gerçekten ses olup olmadığını anlamak için de işimize yarayacak.

Dalga Formu

Dalga formu, genliğin zamanla nasıl değiştiğini gösterir. Sesin ne zaman yüksek ne zaman sessiz olduğunu kolayca görürüz; ama hangi frekansların bulunduğunu buradan anlamak zordur.

Deneme sesinin dalga formu

Spektrogram

Spektrogram, sesin “fotoğrafı”dır: Yatay eksen zamanı, dikey eksen frekansı, renk ise o anda o frekansın ne kadar güçlü olduğunu gösterir. Notalar tek bir yatay çizgi olarak görünür; 880 Hz’lik çizgi 440 Hz’likten iki kat yukarıdadır. Gürültü bütün frekanslara yayılmış bir bulut, ıslık ise yukarı doğru tırmanan bir çizgidir.

Deneme sesinin spektrogramı

Bu fikir çok önemli: Ses tanıma modelleri sesi çoğu zaman ham sayılar olarak değil, spektrograma benzeyen bir görüntü olarak inceler. Yani ses tanıma, bir bakıma görüntü tanımaya dönüşür. Ders 8’de kullanacağımız MFCC yöntemi de spektrogramın insan kulağına göre düzenlenmiş bir hâlidir.

⚠️ Önemli Not

Kayıtta en yüksek genlik 32767’ye çok yakınsa ses kırpılmış (clipping) demektir: Dalganın tepeleri kesilir ve ses cızırtılı olur. Böyle bir kayıtta mikrofondan biraz uzaklaşın ya da masaüstündeki ses ayarlarından mikrofon seviyesini düşürün. Tersine, genlik 1000’in altındaysa ses çok kısıktır ve model için yeterli bilgi taşımaz.

Sıra Sizde

  1. Kolay: ses_kaydet.py ile adınızı söylediğiniz bir kayıt yapın ve ses_analiz.py programında DOSYA değişkenini değiştirerek kendi sesinizin spektrogramını çizin.
  2. Orta: Aynı kelimeyi bir fısıltıyla, bir de yüksek sesle kaydedin. İki kaydın en yüksek genliğini ve spektrogramını karşılaştırın.
  3. Zor: ses_analiz.py programına, RMS değeri 0,02’nin altında kalan bölümleri “sessiz” olarak işaretleyen ve kaydın yüzde kaçının sessiz olduğunu yazan bir bölüm ekleyin.

Kendini Dene

  1. 16 000 Hz örnekleme hızıyla yapılan 2 saniyelik bir kayıtta kaç örnek bulunur?
  2. Bir sesin frekansı artarsa ses nasıl değişir?
  3. Spektrogramda yatay eksen, dikey eksen ve renk neyi gösterir?

Cevaplar

  1. 16 000 × 2 = 32 000 örnek.
  2. Ses incelir, yani tizleşir.
  3. Yatay eksen zamanı, dikey eksen frekansı, renk ise o anda o frekanstaki sesin gücünü gösterir.