Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import matplotlib.pyplot as plt
- import sounddevice as sd
- import pywt
- import threading
- # PARAMETROS ---------------------------
- N_CELLS = 120
- FREQ_MIN = 100
- FREQ_MAX = 8000
- fs = 44100
- frame = 2048 # ~46ms
- center_freqs = np.logspace(np.log10(FREQ_MIN), np.log10(FREQ_MAX), N_CELLS)
- latest_audio = None
- lock = threading.Lock()
- def cochlea_waveletbank(frame, fs):
- wavelet = 'morl'
- fc = pywt.central_frequency(wavelet)
- scales = fc * fs / center_freqs
- coeffs, freqs = pywt.cwt(frame, scales, wavelet, sampling_period=1/fs)
- power = np.mean(np.abs(coeffs) ** 2, axis=1)
- # Converte energia para dB (escala logarítmica)
- power_db = 10 * np.log10(power + 1e-12)
- return power_db
- def audio_callback(indata, frames, time, status):
- global latest_audio
- mono = indata[:, 0]
- with lock:
- latest_audio = mono.copy() # só copia o frame, nada pesado
- plt.ion()
- fig, ax = plt.subplots(figsize=(14,5))
- larguras = np.diff(np.logspace(np.log10(FREQ_MIN), np.log10(FREQ_MAX), N_CELLS+1))
- bars = ax.bar(center_freqs,
- np.zeros(N_CELLS),
- width=larguras,
- bottom=-80, # <<--- faz as barras nascerem em -80 dB
- color="dodgerblue",
- alpha=0.7,
- align="edge")
- ax.set_xscale("log")
- ax.set_ylim(-80, 20) # de -80 dB (silêncio) até 0 dB (máximo)
- ax.set_xlabel("Frequência (Hz)")
- ax.set_ylabel("Intensidade (dB)")
- ax.set_title("Demonstração de Cóclea em Tempo Real")
- # LOOP PRINCIPAL ---------------------------------------------------
- with sd.InputStream(channels=1, samplerate=fs, blocksize=frame, callback=audio_callback):
- print("!! rodando em tempo real !!")
- while True:
- plt.pause(0.001)
- with lock:
- audio = latest_audio
- if audio is None:
- continue
- # wavelet
- ativ = cochlea_waveletbank(audio, fs)
- # atualiza grafico
- for b, h in zip(bars, ativ):
- b.set_height(h + 80)
- regions = [
- (3000, 6000, "#0f62fe"), # azul
- (0, 150, "#42be65"), # verde
- (1500, 3000, "#be95ff"), # roxo
- (150, 375,"#ff832b"), # laranja
- (375, 750,"#fa4d56"), # vermelho
- (750, 1500,"#ff7eb6"), # rosa
- (6000, 10000,"#08bdba") # ciano
- ]
- for b, f in zip(bars, center_freqs):
- for fmin, fmax, color in regions:
- if fmin <= f < fmax:
- b.set_color(color)
- break
- fig.canvas.draw()
- fig.canvas.flush_events()
Advertisement
Add Comment
Please, Sign In to add comment