Realizzare un analizzatore di spettro audio con il Raspberry Pi

Ciao a tutti, oggi vi mostreremo come realizzare un analizzatore di spettro audio con il Raspberry Pi.

Ho già parlato del Raspberry Pi nell’articolo “Raspberry Pi: Introduzione e primi passi”, puoi trovarlo qui.

 

Prima di tutto: cosa è un analizzatore di spettro?

Un analizzatore di spettro è uno strumento che permette di eseguire l’analisi dello spettro audio dei segnali posti al suo ingresso.

Lo spettro sonoro è un grafico che si utilizza nell’analisi di un suono, dove vi sono riportati i livelli sonori in funzione della frequenza.

Questo grafico riporta sull’asse delle ascisse (x) la frequenza in Hertz, mentre sulle ordinate (y) l’ampiezza espressa in decibel.

I picchi sul grafico mostrano quali sono le frequenze che più contribuiscono al segnale totale.

Il punto più alto del grafico ci dà la frequenza fondamentale del suono, i picchi via via più bassi sono le armoniche.

Spiegato molto molto semplicemente, il nostro programma dovrà acquisire dei dati audio, dalla musica in riproduzione nel nostro player, applicare ai dati audio una trasformata di Fourier veloce (FFT) ed estrarre i livelli di ampiezza media per gli intervalli di frequenza specificati.

I dati sulla frequenza cosi ottenuti, vengono formattati e visualizzati nella matice LED.

Adesso, vediamo nel dettaglio di cosa abbiamo bisogno per realizzare un analizzatore di spettro audio con il Raspberry Pi.

Cosa ci serve (Hardware)

  • Ovviamente un Raspberry Pi;
  • Una matrice LED 8×8 montata su modulo con controller MAX 7219;
  • Cavetti jumper;
  • Casse audio.

 

Cosa ci serve (Software)

  • Python DEV, Python Imaging e Python SMBUS;
  • Libreria audio ALSA di Python;
  • Libreria MAX7219 di Python;
  • VLC media player installato sul Raspberry Pi.

 

Schema e collegamenti

Per prima cosa colleghiamo la matrice ai GPIO del Raspberry Pi seguendo questo schema:

Realizzare un analizzatore di spettro audio con il Raspberry Pi - Circuito

Fatti tutti i collegamenti passiamo alla scrittura del nostro programma.

Raspberry Pi (off)

Programma python

Possiamo scrivere il nostro programma direttamente sull’IDE di Python, o anche in un normale editor di testo.

Per prima cosa importiamo le librerie.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import alsaaudio as aa
import wave
from struct import unpack, calcsize
import numpy as np

import re
import argparse

from random import randint
from luma.led_matrix.device import max7219
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.core.virtual import viewport
from luma.core.legacy import text, show_message
from luma.core.legacy.font import proportional, CP437_FONT, TINY_FONT, SINCLAIR_FONT, LCD_FONT

Creiamo e inizializziamo la matrice LED come device.

serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=1, block_orientation=0, rotate=0)
print("Created device")

Definiamo tre vettori.

matrix = [0,0,0,0,0,0,0,0] 
power = []
weighting = [2,8,8,16,16,32,32,64] 
  • Nel vettore matrix verrano inseriti i valori di ampiezza corrispondenti alle frequenze dell’audio campionato.
  • In power verranno inseriti i valori della trasformata di Fourier.
  • Mentre in weighting sono contenuti i valori di ponderazione.

Adesso passiamo alle impostazioni audio.

sample_rate = 44100
chunk = 640

print "##############################"
print "# Waiting for a song to play #"
print "##############################"

input = aa.PCM(aa.PCM_CAPTURE, aa.PCM_NORMAL, 'hw:Loopback,1,0')
output = aa.PCM(aa.PCM_PLAYBACK, aa.PCM_NORMAL, 'plughw:0,0')

input.setchannels(2)
input.setrate(sample_rate)
input.setformat(aa.PCM_FORMAT_S16_LE) #2 byte per Canale
input.setperiodsize(chunk)

output.setchannels(2)
output.setrate(sample_rate)
output.setformat(aa.PCM_FORMAT_S16_LE)
output.setperiodsize(chunk)
  • sample_rate è la frequenza di campionamento.
  • chunk è un multiplo di 8 e serve per determinare la lunghezza dei frame audio da acquisire, per volta.

In questo caso la lunghezza dei frame è data da chunk * 2 (numero di canali) * 4Byte (del formato PCM_FORMAT_S16_LE).

Il resto sono le impostazioni di ALSA.

Adesso creiamo le funzioni.

def piff(val):
    return int(2*chunk*val/sample_rate)

def calculate_levels(data, chunk,sample_rate):
    global matrix

    data = unpack("%dH"%(len(data)/2),data) # len(data)=chunk*(2 byte [perché formato audio 16 bit] * n_canali) 
    data = np.array(data, dtype='h')

    fourier = np.fft.rfft(data)
    fourier = np.delete(fourier,len(fourier)-1)

    power = np.abs(fourier)
    matrix[0] = int(np.mean(power[piff(0)    :piff(156):1]))
    matrix[1] = int(np.mean(power[piff(156)  :piff(313):1]))
    matrix[2] = int(np.mean(power[piff(313)  :piff(625):1]))
    matrix[3] = int(np.mean(power[piff(625)  :piff(1250):1]))
    matrix[4] = int(np.mean(power[piff(1250) :piff(2500):1]))
    matrix[5] = int(np.mean(power[piff(2500) :piff(5000):1]))
    matrix[6] = int(np.mean(power[piff(5000) :piff(10000):1]))
    matrix[7] = int(np.mean(power[piff(10000):piff(20000):1]))

    matrix = np.divide(np.multiply(matrix,weighting),1000000)
    matrix = matrix.clip(0,8)

    return matrix
  • piff() ritorna un indice del vettore power corrispondente a una determinata frequenza (passata tramite val). calculate_level invece restituisce l’elenco delle ampiezze medie di frequenza da visualizzare.
  • unpack converte i dati audio grezzi in un formato compatibile per creare un vettore NumPy.

In questo punto del codice viene applicata la trasformata di fourier ai dati audio e calcolata l’ampiezza media per ogni intervallo di frequenza (in Hz).

I valori ottenuti vengono ridimensionati per poterli visulizzare nella matrice LED.

Tutto questo è fatto direttamente da NumPy.

E infine:

while True:
    l,data = input.read()
    
    if data!='':
        try:
            matrix=calculate_levels(data, chunk,sample_rate)
            
            with canvas(device) as draw:
                for y in range (0,8):
                    for x in range(0, matrix[y]):
                        draw.point((x,y),fill="white")
        except():
            print "Program Closed" 
            break

Il file audio viene letto e per ogni frame calcolato il livello di ampiezza delle frequenze e visualizzato nella matrice LED.

 

Avvio dell’analizzatore di spettro

Fatti tutti i collegamenti e scritto il nostro programma passiamo subito all’esecuzione.

Per prima cosa aprimao il terminale e digitiamo sudo modprobe snd-aloop per creare una scheda audio virtuale.

quindi ancora da terminale digitiamo sudo python <NOMEPROGRAMMA>.py (importante: bisogna essere posizionati nella cartella dove abbiamo salvato il nostro programma).

Se non ci sono errori, apprira:

“##############################”
“# Waiting for a song to play #”
“##############################”

Realizzare un analizzatore di spettro audio con il Raspberry Pi - terminale

Adesso apriamo VLC, ma prima di avviare la riproduzione andiamo su Audio->Dispositivo Audio e scegliamo uno tra quelli Loopback.

Realizzare un analizzatore di spettro audio con il Raspberry Pi - VLC Dispositivi audio

Se tutto sarà andato a buon fine, avviata la riproduzione, nella matice LED vedremo comparire lo spettro audio della nostra canzone!

E questo è come realizzare un analizzatore di spettro audio con il Raspberry Pi.

Realizzare un analizzatore di spettro audio con il Raspberry Pi - Raspberry Pi (on)

Conclusioni

Questi sono alcuni link da cui abbiamo preso delle idee sulla realizzazione del codice:

Questi invece sono i link per scaricare le librerie necessarie, sicuramente Python DEV, Python Imaging e Python SMBUS saranno già installate, comunque sono facilissime da trovare su internet:

Pubblicato da Matlio

Beh, in realtà non c’è molto da dire. Potrei cominciare dicendo che odio le bio! Di fatto anche i miei profili social ne sono pressoché sprovvisti. Comunque sia, sono appassionato di informatica e tecnologia in generale. Questo è il mio campo di studio da praticamente tutta la vita. Amo condividere le cose che, con il tempo e lo studio, ho imparato. Mi piace spaziare con gli argomenti e ho moltissimi interessi. Su questo blog mi troverete a scrivere ora una guida su come installare un sistema operativo, ora un articolo sull’ultimo videogioco della Bethesda, ora uno sull’ultimo film della Marvel. Mi auguro solo che i miei articoli possano aiutare qualcuno di voi a risolvere i piccoli problemi che avrete con il vostro PC. Mmmh, immagino che questo possa bastare.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *