Tracciamento Armonico in Analizzatore
Tracciamento Armonico in Delta-Engine: Analisi Completa
1. Introduzione al Tracciamento Armonico
Il tracciamento armonico è un componente fondamentale dell’Analizzatore
in Delta-Engine, che monitora la distribuzione delle frequenze e le caratteristiche spettrali della composizione in tempo reale. Questo sistema opera su due diverse scale temporali:
- Analisi veloce (10 Hz): Calcola lo stato armonico istantaneo della composizione
- Analisi lenta (1 Hz): Memorizza e classifica questi stati nel tempo
Insieme, questi due livelli di analisi forniscono a Delta-Engine una “percezione armonica” completa che guida le decisioni compositive e le transizioni di stato.
2. Tracciamento Armonico nell’Analisi Veloce (10 Hz)
L’analisi veloce è responsabile del rilevamento diretto delle caratteristiche armoniche in tempo reale.
2.1. Inizializzazione e Reset
All’inizio di ogni ciclo di analisi, i contatori vengono azzerati:
; Reset dei contatori armonici
kOctIdx = 0
while kOctIdx < $OTTAVE do
tabw 0, kOctIdx, gi_active_octaves
kOctIdx += 1
od
kRegIdx = 0
while kRegIdx < $REGISTRI do
tabw 0, kRegIdx, gi_active_registers
kRegIdx += 1
od
kMatrixIdx = 0
while kMatrixIdx < ($OTTAVE * $REGISTRI) do
tabw 0, kMatrixIdx, gi_octave_register_matrix
kMatrixIdx += 1
od
Questo reset è essenziale per garantire che ogni analisi rifletta solo gli eventi attualmente attivi, senza influenze dalle analisi precedenti.
2.2. Identificazione delle Caratteristiche Armoniche degli Eventi
Per ogni evento attivo, l’Analizzatore estrae l’informazione armonica:
; Per ogni evento attivo
if kAttackTime <= kCurrentTime && kAttackTime + kDuration >= kCurrentTime then
kActiveEventsCount += 1
; Raccogli il valore ritmico per il calcolo del movimento spaziale
kRhythm tab kEventIdx, gi_eve_hr
kSumInverseRhythms += (1/kRhythm)
; Identifica ottava e registro dell'evento attivo
kBehaviorId tab kEventIdx, gi_eve_comportamento
if kBehaviorId >= 0 && kBehaviorId < gi_NUMComportamenti then
kOctave tab kBehaviorId, gi_comp_OTTAVA
kRegister tab kBehaviorId, gi_comp_REGISTRO
; Incrementa i contatori
if kOctave >= 0 && kOctave < $OTTAVE then
kOctCount tab kOctave, gi_active_octaves
tabw kOctCount + 1, kOctave, gi_active_octaves
endif
if kRegister >= 0 && kRegister < $REGISTRI then
kRegCount tab kRegister, gi_active_registers
tabw kRegCount + 1, kRegister, gi_active_registers
endif
; 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
endif
endif
Logica armonica implementata:
- Ogni evento attivo ha un’ottava (0-9) e un registro (0-9) che definiscono la sua posizione nello spazio armonico
- L’ottava rappresenta la banda di frequenza principale (scala più ampia)
- Il registro rappresenta variazioni all’interno di un’ottava (scala più fine)
- La matrice ottava/registro (10×10) rappresenta una “mappa termica” della distribuzione armonica
2.3. Calcolo delle Metriche Armoniche Aggregate
Dopo aver analizzato tutti gli eventi, vengono calcolate metriche aggregate:
; Calcola metriche armoniche
kActiveOctaves = 0
kActiveRegisters = 0
kWeightedOctaveSum = 0
kTotalOctaveEvents = 0
; Conta ottave attive e calcola centroide
kOctIdx = 0
while kOctIdx < $OTTAVE do
kOctCount tab kOctIdx, gi_active_octaves
if kOctCount > 0 then
kActiveOctaves += 1
kWeightedOctaveSum += kOctIdx * kOctCount
kTotalOctaveEvents += kOctCount
endif
kOctIdx += 1
od
; Calcola metriche armoniche
if kTotalOctaveEvents > 0 then
kHarmonicDensity = kActiveOctaves / $OTTAVE
kOctaveSpread = 1 - (kActiveOctaves / $OTTAVE)
kSpectralCentroid = kWeightedOctaveSum / kTotalOctaveEvents
else
kHarmonicDensity = 0
kOctaveSpread = 0
kSpectralCentroid = 0
endif
; Calcola il movimento spaziale medio
kCurrentSpatialMovement = (kActiveEventsCount > 0) ? kSumInverseRhythms / kActiveEventsCount : 0
Le metriche calcolate includono:
- Densità armonica (kHarmonicDensity)
- Frazione di ottave attive simultaneamente (0-1)
- Valore alto = distribuzione ampia delle frequenze
- Valore basso = concentrazione delle frequenze
- Dispersione ottave (kOctaveSpread)
- Complemento della densità armonica (1 - densità)
- Misura di quanto è “sparsa” la distribuzione delle ottave
- Centroide spettrale (kSpectralCentroid)
- Media pesata delle ottave attive
- Indica il “centro di gravità” armonico (ottave alte vs. basse)
- Movimento spaziale (kCurrentSpatialMovement)
- Derivato dai valori di ritmo degli eventi attivi
- Valori alti = maggiore movimento nello spazio sonoro
2.4. Aggiornamento delle Variabili Globali
Infine, i valori calcolati vengono memorizzati in variabili globali:
; Aggiorna variabili globali
gk_current_overlap = kActiveEventsCount
gk_current_harmonic_density = kHarmonicDensity
gk_current_octave_spread = kOctaveSpread
gk_current_spectral_centroid = kSpectralCentroid
gk_current_spatial_movement = kCurrentSpatialMovement
Queste variabili globali sono accessibili a tutto il sistema, in particolare al controller di transizione che le utilizzerà per prendere decisioni sulla evoluzione compositiva.
3. Tracciamento Armonico nell’Analisi Lenta (1 Hz)
L’analisi lenta si occupa principalmente di memorizzare l’evoluzione delle caratteristiche armoniche nel tempo e di classificarle in stati discreti.
3.1. Memorizzazione dell’Evoluzione Armonica
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 i dati armonici nella "memoria compositiva"
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
tabw gk_current_spatial_movement, kMemIdx, gi_memory_spatial_movement
Caratteristiche chiave:
- Riutilizza i valori già calcolati dall’analisi veloce (non ricalcola)
- Li memorizza in tabelle che rappresentano l’evoluzione temporale
- L’indice (kMemIdx) rappresenta la posizione nel tempo all’interno della composizione
3.2. Classificazione in Stati Armonici Discreti
Un aspetto fondamentale dell’analisi lenta è la classificazione dei valori continui in stati discreti:
; Determina lo stato corrente
iCurrentDensity = i(gk_current_overlap)
iCurrentRegister = i(gk_current_octave_spread)
iCurrentMovement = i(gk_current_spatial_movement)
iDensityState, iRegisterState, iMovementState determineCurrentState iCurrentDensity, iCurrentRegister, iCurrentMovement
L’opcode determineCurrentState
in determineState.udo
utilizza tabelle di soglie per questa classificazione:
; Determine register state
iRegisterIdx = 0
while iRegisterIdx < ftlen(gi_register_thresholds)-1 do
iLowerBound tab_i iRegisterIdx, gi_register_thresholds
iUpperBound tab_i iRegisterIdx+1, gi_register_thresholds
if iRegisterSpread >= iLowerBound && iRegisterSpread < iUpperBound then
iRegisterState = iRegisterIdx
igoto register_done
endif
iRegisterIdx += 1
od
Le soglie sono definite come:
gi_register_thresholds ftgen 0, 0, 4, -2, 0, 0.3, 0.7, 1.001 ; Low, Mid, High
Questo significa che il valore di dispersione ottave (octave_spread) viene classificato in:
- Stato 0 (Low): octave_spread < 0.3 (distribuzione concentrata)
- Stato 1 (Mid): octave_spread tra 0.3 e 0.7 (distribuzione media)
- Stato 2 (High): octave_spread > 0.7 (distribuzione molto sparsa)
3.3. Memorizzazione degli Stati Armonici
L’analisi lenta mantiene due tipi di memoria per gli stati:
; Aggiorna la cronologia degli stati usando il buffer circolare
kNextIndex = (gk_state_history_index + 1) % gi_state_history_size
; Memorizza il nuovo stato nella posizione corrente del buffer
tabw iRegisterState, kNextIndex, gi_state_history_register
; Aggiorna l'indice globale del buffer
gk_state_history_index = kNextIndex
; Memorizza lo stato nella cronologia temporale completa
tabw iRegisterState, kMemIdx, gi_memory_state_register
- Buffer circolare (
gi_state_history_register
)- Mantiene solo gli ultimi
gi_state_history_size
(tipicamente 10) stati - Permette analisi delle tendenze recenti
- Mantiene solo gli ultimi
- Cronologia completa (
gi_memory_state_register
)- Traccia l’evoluzione degli stati per l’intera composizione
- Supporta l’analisi e la visualizzazione a lungo termine
4. Interazione tra Analisi Veloce e Lenta
I due livelli di analisi armonica interagiscono in modi complementari:
┌───────────────┐
│ Analisi Veloce │◄─────┐
└───────────────┘ │
│ │
▼ │
┌───────────────┐ │
│Variabili Globali│ │
└───────────────┘ │
│ │
▼ │
┌───────────────┐ │
│ Analisi Lenta │──────┘
└───────────────┘
│
▼
┌───────────────┐
│ Memoria e │
│Classificazione │
└───────────────┘
- L’analisi veloce calcola lo stato armonico istantaneo e lo memorizza in variabili globali
- L’analisi lenta riutilizza questi valori per:
- Memorizzarli nella cronologia compositiva
- Classificarli in stati discreti
- Registrare l’evoluzione degli stati nel tempo
5. Utilizzo del Tracciamento Armonico per Decisioni Compositive
5.1. Per Analisi Compositiva Retrospettiva
; 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)
; Inizializza contatori
iSumHarmonicDensity = 0
iSumOctaveSpread = 0
iMaxHarmonicDensity = 0
iCount = 0
; Analizza il range temporale
iIdx = iStartIdx
while iIdx <= iEndIdx do
iHarmonicDensity table iIdx, gi_memory_harmonic_density
iOctaveSpread table iIdx, gi_memory_octave_spread
iSumHarmonicDensity += iHarmonicDensity
iSumOctaveSpread += iOctaveSpread
iMaxHarmonicDensity = max(iMaxHarmonicDensity, iHarmonicDensity)
iCount += 1
iIdx += 1
od
; Calcola valori aggregati
iAvgHarmonicDensity = (iCount > 0) ? iSumHarmonicDensity / iCount : 0
iAvgOctaveSpread = (iCount > 0) ? iSumOctaveSpread / iCount : 0
xout iAvgHarmonicDensity, iMaxHarmonicDensity, iAvgOctaveSpread, iCount
endop
Questo opcode analizza un periodo temporale specifico per determinare caratteristiche armoniche aggregate, utili per adattare nuovi eventi al contesto.
5.2. Per Decisioni di Transizione di Stato
; In transControllerUtils.udo
opcode recordCurrentState, 0, 0
; Read current state from global variables populated by Analizzatore
iCurDensity = i(gk_current_overlap)
iCurRegister = i(gk_current_octave_spread)
iCurMovement = i(gk_current_spatial_movement)
; Determine the current state using the existing determineCurrentState opcode
iDensityState, iRegisterState, iMovementState determineCurrentState iCurDensity, iCurRegister, iCurMovement
; Update controller's knowledge of current state
gi_tc_current_density = iDensityState
gi_tc_current_register = iRegisterState
gi_tc_current_movement = iMovementState
endop
Il TransitionController
utilizza questi stati per determinare le future transizioni compositive.
5.3. Per la Generazione di Nuovi Comportamenti
; In TransitionController.orc (tramite BehaviorGenerator)
iInterpolatedRegister interpolateParameter gi_tc_source_register, gi_tc_target_register, iProgress, 0
; Ottava e registro mappati in base al parametro di stato
iMinOctave, iMaxOctave mapStateToParameter iInterpolatedRegister, "register"
Il sistema di transizione utilizza i parametri di stato armonico per guidare la generazione di nuovi comportamenti durante le transizioni.
6. Logica del Sistema Armonico in Delta-Engine
La logica del tracciamento armonico in Delta-Engine si basa su alcuni principi fondamentali:
6.1. Rappresentazione Multi-dimensionale dello Spazio Armonico
- Dimensione verticale (ottave): Rappresenta la distribuzione delle frequenze in bande ampie
- Dimensione orizzontale (registri): Rappresenta variazioni più fini all’interno di ciascuna ottava
- Matrice bi-dimensionale: Fornisce una “mappa termica” completa della distribuzione armonica
6.2. Metriche Complementari
- Densità armonica: Misura quante ottave sono attive simultaneamente
- Dispersione ottave: Misura quanto è sparsa la distribuzione (spesso usata per decisioni di stato)
- Centroide spettrale: Indica il centro di gravità armonico (grave vs acuto)
- Movimento spaziale: Correlato alle caratteristiche ritmiche e alla loro percezione spaziale
6.3. Sistema di Classificazione a Stati Discreti
Semplifica lo spazio continuo delle caratteristiche armoniche in un sistema a stati discreti:
- 3 stati di densità × 3 stati di registro × 3 stati di movimento = 27 stati possibili
- Questa discretizzazione facilita le decisioni di transizione e la modellazione dell’evoluzione compositiva
6.4. Memoria a Due Livelli
- Memoria recente (buffer circolari): Per decisioni a breve termine e analisi di tendenze immediate
- Memoria storica (array completi): Per analisi a lungo termine e coerenza compositiva globale
7. Conclusione
Il tracciamento armonico in Delta-Engine rappresenta un sofisticato sistema di “percezione musicale” che combina:
- Analisi istantanea attraverso il monitoraggio ad alta frequenza (10 Hz)
- Memoria temporale attraverso la memorizzazione a bassa frequenza (1 Hz)
- Classificazione discretizzata attraverso il sistema di stati
- Informazione armonica multi-dimensionale attraverso ottave, registri e loro interazioni
Questa architettura consente a Delta-Engine di “ascoltare” la propria composizione in sviluppo, analizzarne le caratteristiche armoniche e prendere decisioni informate sulla sua evoluzione, creando una struttura musicale che bilancia coerenza e varietà nello spazio delle frequenze.