Classificatore audio ML su microcontrollore — inferenza C senza OS

Solutions Hub · Elettronica embedded / IoT industriale

Classificatore audio ML su microcontrollore — inferenza C senza OS

Riconoscimento sonoro locale su microcontrollore: un modello Random Forest addestrato in Python, esportato in C puro e compilato direttamente nel firmware — senza cloud, senza dipendenze, senza RTOS.

Settore: Elettronica embedded / IoT industriale Pubblicato: 02/04/2026
  • Python
  • C99
  • scikit-learn
  • librosa
  • RandomForest
  • MFCC
  • ESP32
  • STM32
  • ESP-IDF
Richiedi una consulenza tecnica Prenota Audit 90 minuti

Contesto

La soluzione nasce dall'esigenza di rilevare eventi sonori direttamente su un microcontrollore, senza dipendere da connettività di rete, server remoti o sistemi operativi. In molti prodotti IoT il riconoscimento audio viene delegato al cloud, introducendo latenza, costi operativi e dipendenze difficili da gestire in produzione.

L'obiettivo è portare l'intelligenza artificiale audio direttamente sul device: un modello addestrato in Python che viene esportato come codice C statico, compilato insieme al firmware e capace di girare su bare-metal senza malloc, filesystem o RTOS.

L'approccio privilegia la semplicità dell'integrazione e la prevedibilità del comportamento a runtime. Il modello non è un componente opaco: è codice C leggibile, verificabile e ricompilabile ogni volta che il dataset viene aggiornato.

Pipeline end-to-end dal microfono all'inferenza su MCU

Esigenze progettuali

Il sistema deve rispondere a vincoli tipici di un contesto embedded professionale, dove le risorse sono limitate e l'affidabilità è un requisito non negoziabile.

Le principali esigenze progettuali includono la possibilità di classificare suoni in tempo reale su un singolo core, l'assenza di dipendenze da librerie C esterne, la riproducibilità del processo di training e la possibilità di rigenerare il modello dopo ogni nuovo dataset senza modificare il firmware manualmente.

Un approccio basato su librerie ML precompilate per embedded è spesso difficile da portare su architetture diverse. La priorità è quindi generare codice C portatile, compatibile con qualsiasi toolchain — GCC, Clang, IAR, ARMCC — e integrabile in qualsiasi progetto senza dipendenze aggiuntive.

Struttura tecnica

La soluzione è organizzata in due layer distinti: un layer Python per il training e l'export, e un layer C per l'inferenza su microcontrollore. I due livelli comunicano attraverso i file generati dallo script di export, che contengono l'intero modello serializzato come array statici.

Il layer Python si occupa di raccogliere campioni audio, estrarre le feature con finestre scorrevoli da 300ms e addestrare un RandomForestClassifier con normalizzazione tramite StandardScaler. Lo script export_c_model.py serializza poi ogni albero della foresta — nodi, soglie, indici di feature, valori foglia — e i parametri dello scaler direttamente in header e sorgenti C.

Il layer C espone una API minimale: tre funzioni pubbliche che ricevono il vettore di feature da 36 float e restituiscono la classe predetta, le probabilità per classe e il nome stringa dell'etichetta. Non è richiesta alcuna inizializzazione di heap o strutture dinamiche.

Feature extraction — 36 descrittori per finestra

Per ogni finestra da 300ms il frontend audio calcola sei famiglie di descrittori, di cui vengono estratti media e deviazione standard. Il vettore da 36 valori risultante è identico sia in fase di training che in fase di inferenza, garantendo coerenza tra modello Python e comportamento su MCU.

  • MFCC (26 feature): 13 Mel-Frequency Cepstral Coefficients, media e std. Catturano timbrica e contenuto spettrale in modo compatto.
  • RMS (2 feature): energia del segnale, utile per distinguere suoni impulsivi dal rumore di fondo.
  • ZCR (2 feature): zero crossing rate, indice di percussività e presenza di componenti ad alta frequenza.
  • Spectral centroid, rolloff, bandwidth (6 feature): caratterizzano la distribuzione dell'energia nelle bande di frequenza e la "brillantezza" del suono.
Mappa delle 36 feature audio: MFCC, RMS, ZCR, Spectral

Modalità operative

Il sistema supporta due configurazioni. In modalità multiclasse il modello distingue tra tutte le etichette presenti nel dataset — ad esempio clap, double_clap, knock, whistle, background. In modalità detect/no-detect è possibile indicare una o più etichette positive e collassare tutte le altre in una singola classe negativa, ideale per trigger o rilevatori di eventi specifici con soglia configurabile a runtime.

Architettura orientata alla portabilità

Il codice C generato non dipende dall'architettura target. Lo stesso modello compilato su un ESP32 può essere ricompilato su un STM32, un nRF52 o qualsiasi altro MCU supportato dalla toolchain. La sola parte da adattare è il frontend DSP, che calcola le feature audio usando la libreria disponibile sul target — CMSIS-DSP, ESP-DSP o un'implementazione custom.

Metodologia di sviluppo

Lo sviluppo segue un ciclo iterativo che parte dalla raccolta dei campioni audio e arriva all'integrazione nel firmware, con ogni fase verificabile in modo indipendente. Il processo è ripetibile: aggiornare il dataset e rigenerare il modello richiede l'esecuzione di due comandi.

La raccolta dati avviene direttamente da microfono tramite CLI, con durata e etichetta configurabili per ogni sessione di registrazione. I campioni vengono salvati in cartelle separate per classe e usati in training con finestramento automatico per file lunghi.

# Registrazione campioni
python main.py record --label knock --seconds 4
python main.py record --label background --seconds 6
 
# Training e validazione
python main.py train
 
# Export C per il firmware
python tools/export_c_model.py \
  --model models/sound_model.joblib \
  --out-dir embedded

La qualità del modello è direttamente proporzionale alla varietà dei campioni. Si raccomanda di registrare in ambienti e a distanze diverse, con almeno 30 campioni per classe (ottimale 80+) e una classe background rappresentativa delle condizioni operative reali, per ridurre i falsi positivi.

L'integrazione nel firmware richiede di aggiungere i file generati al progetto, implementare il calcolo delle feature nel frontend DSP e richiamare le API di inferenza nel loop di acquisizione audio.

Output

Il risultato è un set di file C pronti per essere inclusi in qualsiasi progetto firmware, accompagnati da un'API documentata e da un template di integrazione.

  • File sound_model.h e sound_model.c con il modello serializzato
  • File audio_frontend.h e audio_frontend.c con il template di feature extraction
  • API C stabile: predict, predict_proba, class_name
  • Script Python per training, validazione e rigenerazione del modello
  • Pipeline CLI completa per raccolta dati, training e inferenza su file

Integrazione nel firmware

Il contratto tra firmware e modello è minimale e stabile. L'unica funzione da implementare sul target è af_compute_frame_descriptors(), che calcola i descrittori audio frame per frame usando la libreria DSP del target. Il template gestisce automaticamente finestramento, accumulo e costruzione del vettore mean/std.

/* Esempio di loop di inferenza su MCU */
Flusso di inferenza C su microcontrollore
float feats[AF_FEATURES_COUNT];
af_extract_features(&g_af, pcm_q15, feats);
 
float probs[SOUND_MODEL_NUM_CLASSES];
sound_model_predict_proba(feats, probs);
 
/* Soglia configurabile a runtime */
if (probs[detect_idx] >= 0.60f) {
    /* evento rilevato */
}

Casi d'uso verificati

La soluzione è applicabile a qualsiasi scenario in cui sia necessario rilevare un evento acustico in modo locale, con reazione immediata e consumo energetico controllato: controllo gestuale senza contatto, rilevamento anomalie su macchinari, wake-word custom per attivare il sistema da uno stato di basso consumo.

Applicazione del metodo

L'approccio utilizzato per questa soluzione non è legato a un singolo tipo di suono o a una specifica piattaforma hardware. La stessa pipeline — raccolta, training, export C — può essere applicata a qualsiasi problema di classificazione audio su embedded, variando solo le classi del dataset e il frontend DSP del target.

Il modello può essere rigenerato ogni volta che il contesto operativo cambia: nuovi ambienti, nuove varianti del suono da rilevare, nuove classi da distinguere. Il firmware non richiede modifiche strutturali — basta ricompilare con i nuovi file C.

In questo modo è possibile realizzare soluzioni di riconoscimento audio su misura, pronte per crescere insieme al prodotto e adattarsi a requisiti che evolvono nel tempo.

Progetti correlati

← Torna al Solutions Hub