Analisi Armonica
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:
- Inizializzazione - Strutture dati in
first.orc
- Analisi in tempo reale - Monitoraggio in
Analizzatore.orc
- 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:
- Reset dei contatori per ottave e registri
- Scansione di tutti gli eventi attivi
- Aggiornamento dei contatori per ciascun evento attivo
- 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:
- Distribuzione spettrale - Come sono distribuiti gli eventi nello spazio delle frequenze
- Densità - Quanta attività c’è in diverse regioni dello spettro
- 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:
- Retroazione diretta delle metriche armoniche nella selezione delle ottave e dei registri
- Utilizzo della densità armonica per guidare l’evoluzione strutturale della composizione
- 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.