6 minute read

Analisi Armonica in Delta-Engine

Questo documento analizza l’implementazione dell’analisi armonica nel sistema delta-engine, evidenziando come viene monitorata e utilizzata l’attività spettrale durante la generazione compositiva.

1. Panoramica del Sistema

Il sistema delta-engine implementa un meccanismo di analisi armonica che monitora la distribuzione delle frequenze e l’attività spettrale durante l’esecuzione. Il sistema è principalmente implementato in tre componenti:

  1. Inizializzazione - Strutture dati in first.orc
  2. Analisi in tempo reale - Monitoraggio in Analizzatore.orc
  3. Analisi storica - Funzioni in calcDurationFactor.udo

2. Strutture Dati per l’Analisi Armonica

Il sistema utilizza diverse tabelle globali per tracciare l’attività armonica, definite in first.orc:

; Tabelle per tracciamento armonico
gi_active_octaves ftgen 0, 0, $OTTAVE, -2, 0    ; Conteggio eventi attivi per ottava
gi_active_registers ftgen 0, 0, $REGISTRI, -2, 0  ; Conteggio eventi attivi per registro
gi_octave_register_matrix ftgen 0, 0, $OTTAVE * $REGISTRI, -2, 0  ; Matrice ottava/registro

; Tabelle per storia armonica 
gi_memory_harmonic_density ftgen 0, 0, gi_memory_size, -2, 0  ; Densità armonica nel tempo
gi_memory_octave_spread ftgen 0, 0, gi_memory_size, -2, 0  ; Dispersione delle ottave
gi_memory_spectral_centroid ftgen 0, 0, gi_memory_size, -2, 0  ; Centroide spettrale
; Tabella per tracciamento armonico cumulativo
gi_cumulative_octave_register_matrix ftgen 0, 0, $OTTAVE * $REGISTRI, -2, 0  

Queste strutture memorizzano:

  • Conteggio di eventi attivi per ogni ottava
  • Conteggio di eventi attivi per ogni registro
  • Matrice che mappa la combinazione ottava/registro
  • Misure temporali di densità armonica, dispersione e centroide spettrale
  • Dati cumulativi per analisi finale

3. Metriche Armoniche

Il sistema calcola tre principali metriche armoniche:

3.1. Densità Armonica

La densità armonica misura la porzione dello spazio spettrale occupato, calcolata come:

kHarmonicDensity = kActiveOctaves / $OTTAVE

Questo valore rappresenta la percentuale di ottave attualmente occupate da eventi sonori, dove:

  • 0.0 rappresenta nessuna attività
  • 1.0 rappresenta attività in tutte le ottave disponibili

3.2. Dispersione delle Ottave

La dispersione delle ottave è il complemento della densità armonica:

kOctaveSpread = 1 - (kActiveOctaves / $OTTAVE)

Questo valore rappresenta quanto è “sparsa” l’attività nello spazio delle ottave:

  • 0.0 indica attività in tutte le ottave (nessuna dispersione)
  • 1.0 indica attività concentrata in una sola ottava (massima dispersione)

3.3. Centroide Spettrale

Il centroide spettrale è la media ponderata delle ottave attive:

kWeightedOctaveSum += kOctIdx * kOctCount
kTotalOctaveEvents += kOctCount
kSpectralCentroid = kWeightedOctaveSum / kTotalOctaveEvents

Questo valore rappresenta il “centro di gravità” spettrale della composizione.

4. Il Processo di Analisi in Tempo Reale

L’analisi armonica in tempo reale viene eseguita dall’istrumento Analizzatore, che opera a 10Hz:

instr Analizzatore
    ; Analisi della sovrapposizione di eventi - eseguita a k-rate 
    kTrig metro 10  ; 10 Hz per avere una buona risoluzione temporale
    if kTrig == 1 then
        ; Reset dei contatori armonici...
        
        ; Analisi delle tabelle di eventi
        kEventIdx = 0
        while kEventIdx < gi_Index do
            ; Verifica se l'evento è attualmente attivo...
            
            if kAttackTime <= kCurrentTime && kAttackTime + kDuration >= kCurrentTime then
                ; Identifica ottava e registro dell'evento attivo...
                
                ; Incrementa i contatori...
            endif
            
            kEventIdx += 1
        od
        
        ; Calcola metriche armoniche
        ; ...
    endif

Il processo comprende questi passaggi:

  1. Reset dei contatori per ottave e registri
  2. Scansione di tutti gli eventi attivi
  3. Aggiornamento dei contatori per ciascun evento attivo
  4. Calcolo delle metriche basate sui contatori aggiornati

5. Memorizzazione Temporale

Il sistema memorizza le metriche armoniche nel tempo con una frequenza di campionamento definita da gi_memory_resolution:

kMemTrig metro 1/gi_memory_resolution
if kMemTrig == 1 then
    kCurrentTime timeinsts
    kMemIdx = int(kCurrentTime / gi_memory_resolution)
    
    if kMemIdx >= 0 && kMemIdx < gi_memory_size then
        ; Memorizza anche i dati armonici
        tabw gk_current_harmonic_density, kMemIdx, gi_memory_harmonic_density
        tabw gk_current_octave_spread, kMemIdx, gi_memory_octave_spread
        tabw gk_current_spectral_centroid, kMemIdx, gi_memory_spectral_centroid
    endif
endif

6. Analisi Storica

Il sistema fornisce anche funzioni per analizzare i dati armonici storici, come implementato in calcDurationFactor.udo:

opcode analyzeHarmonicMemory, iiii, ii
    iStartTime, iEndTime xin
    
    ; Calcola indici nella tabella di memoria
    iStartIdx = int(iStartTime / gi_memory_resolution)
    iEndIdx = int(iEndTime / gi_memory_resolution)
    
    ; ... calcolo delle metriche aggregate ...
    
    xout iAvgHarmonicDensity, iMaxHarmonicDensity, iAvgOctaveSpread, iCount
endop

Questa funzione permette di analizzare un periodo specifico della memoria compositiva per estrarre:

  • Densità armonica media
  • Densità armonica massima
  • Dispersione media delle ottave

7. Mapping Ottava/Registro

Un aspetto interessante è la matrice che mappa la combinazione ottava/registro:

; Incrementa la matrice ottava/registro
kMatrixIdx = kOctave * $REGISTRI + kRegister
if kMatrixIdx >= 0 && kMatrixIdx < ($OTTAVE * $REGISTRI) then
    kMatrixVal tab kMatrixIdx, gi_octave_register_matrix
    tabw kMatrixVal + 1, kMatrixIdx, gi_octave_register_matrix
    ; Aggiorna anche la matrice cumulativa
    kCumulativeVal tab kMatrixIdx, gi_cumulative_octave_register_matrix
    tabw kCumulativeVal + 1, kMatrixIdx, gi_cumulative_octave_register_matrix
endif

La matrice viene rappresentata come un array unidimensionale, con l’indice calcolato come: ottava * numero_registri + registro. Questo permette di tracciare efficacemente quali combinazioni di ottava e registro sono più attive durante la composizione.

7.1. Rappresentazione Visuale della Matrice

La matrice ottava/registro può essere visualizzata come segue:

                Registri
      | 0 | 1 | 2 | ... | 9 |
    --+---+---+---+-----+---+
    0 | * | * | * | ... | * |
    --+---+---+---+-----+---+
    1 | * | * | * | ... | * |
O   --+---+---+---+-----+---+
t   2 | * | * | * | ... | * |
t   --+---+---+---+-----+---+
a   . |   |   |   |     |   |
v   . |   |   |   |     |   |
e   . |   |   |   |     |   |
    --+---+---+---+-----+---+
    9 | * | * | * | ... | * |
    --+---+---+---+-----+---+

Ogni cella * della matrice contiene un contatore incrementato quando un evento con quella specifica combinazione di ottava e registro è attivo. Per esempio, un evento attivo all’ottava 3, registro 4 incrementerebbe il contatore nella cella corrispondente.

Nel codice, questa matrice bidimensionale viene linearizzata in un array unidimensionale per efficienza. La formula di mapping:

indice_array = ottava * numero_registri + registro

Permette di accedere alla specifica cella. Ad esempio, per accedere alla cella (ottava 3, registro 4) con 10 registri per ottava:

indice = 3 * 10 + 4 = 34

Questo approccio permette di monitorare quali aree dello spazio frequenziale sono più attive durante la composizione e identifica potenziali pattern o preferenze emergenti.

8. Esportazione e Visualizzazione dei Dati

Al termine dell’esecuzione, lo strumento AnalisiFinale esporta i dati armonici in diversi file CSV:

; Esporta i dati armonici in CSV
SHarmonicFile = "docs/analysis/harmonic_data.csv"
fprints SHarmonicFile, "time,harmonic_density,octave_spread,spectral_centroid\n"

; ... altre esportazioni per distribuzioni e matrici ...

I file esportati includono:

  • Serie temporali di densità armonica, dispersione e centroide
  • Distribuzione delle attività per ottava
  • Distribuzione delle attività per registro
  • Matrice ottava/registro

Questi dati vengono poi visualizzati utilizzando script Python come visualize_harmony.py.

9. Utilizzo nell’Algoritmo Compositivo

Importante notare che, sebbene il sistema raccolga dati dettagliati sull’attività armonica, l’utilizzo diretto di questi dati nel processo compositivo è limitato. Attualmente, la retroazione principale è nel calcolo della durata degli eventi:

; Dal file comportamento.orc
iLookbackTime = max(0, iCurrentTime - 30)
i_OverlapFactor = suggestDurationFactor(iLookbackTime, iCurrentTime, i_RitmoCorrente)
i_DurEvento = (i_DurataArmonica/i_RitmoCorrente) * i_OverlapFactor

Qui il sistema utilizza una funzione suggestDurationFactor che considera principalmente la sovrapposizione di eventi, ma non sfrutta direttamente le metriche armoniche.

10. Peculiarità del Sistema

Un aspetto distintivo di questo sistema è la mancanza di un’analisi armonica convenzionale. Non c’è alcun concetto di accordi, progressioni armoniche o tensione/risoluzione. Il sistema si concentra invece su aspetti più “spaziali” dell’armonia:

  1. Distribuzione spettrale - Come sono distribuiti gli eventi nello spazio delle frequenze
  2. Densità - Quanta attività c’è in diverse regioni dello spettro
  3. Centroide - Dove si concentra maggiormente l’energia spettrale

Questo approccio tratta l’armonia come un fenomeno emergente dalla distribuzione spaziale degli eventi sonori, piuttosto che come un sistema di regole predefinite.

11. Conclusioni e Potenziali Sviluppi

Il sistema implementa un sofisticato meccanismo di monitoraggio dell’attività armonica, ma attualmente utilizza solo una piccola parte di queste informazioni nel processo compositivo. Potenziali estensioni potrebbero includere:

  1. Retroazione diretta delle metriche armoniche nella selezione delle ottave e dei registri
  2. Utilizzo della densità armonica per guidare l’evoluzione strutturale della composizione
  3. Implementazione di obiettivi armonici basati sul centroide spettrale

Il codice mostra chiaramente l’intenzione di estendere queste funzionalità in futuro, come evidenziato nel diagramma harmonic_analysis.md che include alcune funzionalità potenziali non ancora implementate.


E questa è la versione del reporitory allo stato di lavoro del diario.