Skip to main content

Spectral Playground

In [28]:
sampleo = 48000
rec = grabar(duracion=15,
             sampleo=sampleo)

display(
    Audio(
        stereo2mono(
            rec[sampleo:]), rate=sampleo
    ) 
)
Recording Audio...
Audio recording complete.
In [33]:
plot_multiple(stereo2mono(rec[sampleo:]), fs=sampleo)

faune

Con un poco de atención, podemos observar, del gráfico superior al inferior:

  • El vibrato de la flauta
  • El tono de la obra (C# ~554hz, Prélude à l'après-midi d'un faune)
  • La melodía

😃🤟

Oops! https://www.youtube.com/watch?v=vabZ4H1NCeQ

In [1]:
#!conda install -c conda-forge python-sounddevice

#Librería para grabar
import sounddevice as sd

#Para reproducir audio en la Jupyter N.
from IPython.display import Audio, display

#Funciones para señales
import scipy.signal

#Herramientas numéricas
import numpy as np

#Para plotear
import matplotlib.pyplot as plt

#Para hacer una pausa en el programa
from time import sleep

#'inline' para evitar el o de "plt.show()"
#'notebook' para que sea también interactivo
%matplotlib notebook
In [1]:
def grabar(sampleo = 44100, 
           duracion = 5, 
           play = False):
    '''Graba audio y devuelve la data como array de numpy.
    sampleo, hz
    duracion en s'''
    
    rec = sd.rec(duracion * sampleo, samplerate=sampleo, channels=2,dtype='float64')
    print("Recording Audio...")    
    sd.wait()
    
    print("Audio recording complete.")
    if play:
        sd.play(rec, sampleo)
        sd.wait()
        print("Playing audio...")
    return rec
In [32]:
def plot_multiple(w, fs = 44100):
    '''Plotea primero la onda en dominio de tiempo, luego el espectro (FFT) y luego el espectrograma'''
    
    #Creo el espacio para plotear, una "figura" vacia
    plt.figure(figsize=(15,15))

    #Dividido en 3 filas y 1 columna, ploteo la onda en el 1er espacio
    plt.subplot(3, 1, 1)
    plt.plot(w)
    
    #Pongo titulo al eje y
    plt.ylabel('Amplitude')
    #Grilla de fondo
    plt.grid()
    
    #FFT
    n = len(w)
    Y = np.fft.rfft(w) / n 
    freqs = np.fft.fftfreq(n, d= 1/fs)
    
    #Plot FFT
    plt.subplot(3, 1, 2)
    #Ploteo las frecuencias positivas y sus valores, con un color RGBA
    plt.plot(freqs[:10000], abs(Y[:10000]), c = [0.9, 0.2, 0.1, 0.8])
    plt.xlabel('Freq (Hz)')
    
    #Marco en el eje X ciertos valores incluyendo la frecuencia de máximo valor
    plt.xticks(np.sort(np.append(freqs[:10000:1000], freqs[np.argmax(abs(Y[:10000]))])), rotation = 60)
    plt.ylabel('|Y(freq)|')

    #Espectrograma
    plt.subplot(3, 1, 3)
    Pxx, freqs, bins, im = plt.specgram(w, Fs=fs, NFFT=1024, cmap= 'coolwarm')
    plt.ylim(0, 4000)
    plt.ylabel('Freq')
    plt.xlabel('Time')
    plt.show()
In [6]:
def stereo2mono(s : np.array): return (s[:,0] + s[:,1]) / 2

Comments

Comments powered by Disqus
Share Share