ROBOTICA

video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori

links

 

Papers
meccanica
sistemi
documents

Capitolo 26° Aggiungere fonti sonore Capitolo 28°

Vediamo ora brevemente cosa possiamo fare per rendere ancora più realistico il nostro mondo.

Un mondo senza suoni e rumori dovrebbe sembrarci abbastanza innaturale. Vediamo allora come ovviare a questa mancanza.

Vrml offre diverse possibilità per inserire fonti sonore. In particolare offre supporto per files in formato MIDI e WAV. Supporta inoltre audio MPEG1 e quindi consente sincronizzazione tra video e sonoro.

Costruire un mondo pieno di suoni potrebbe essere allettante. Allo stato attuale però ci si deve scontrare con l’occupazione di questi files. Mentre i files MIDI risultano di dimensioni abbastanza contenute, i files WAV hanno dimensioni difficilmente gestibili in rete, se non per piccoli effetti (oppure sottocampionando di molto il segnale sonoro).

Files MIDI possono essere indicati come musiche di background. Viceversa files wav potrebbero essere utili per piccoli spezzoni di parlato o piccoli effetti sonori.

Vrml consente inoltre di localizzare la fonte sonora nello spazio 3D, in modo da avere suoni direzionali. Ovviamente si gestiscono fattori di attenuazione con l’allontanamento dalla fonte sonora.

Vediamone un semplice utilizzo, abbinato all’esempio dei paragrafi precedenti. Vogliamo che quando si preme l’interruttore e il cubo inizia a ruotare (o si ferma) venga prodotto un segnale sonoro simile ad un laser.

Per prima cosa mi seleziono il file WAV che mi serve. Nel nostro caso sono riuscito a trovarne uno di dimensioni molto piccole (1.8Kb); essendo un po’ corto provvederò a ripetere il segnale per 3 volte consecutive creando un discreto effetto.

Per inserire fonti sonore in vrml ci serve il nodo Sound. Questo nodo contiene diversi campi, ma tutti con dei valori di default. Vediamo solo quelli che ci interessano; per gli altri si rimanda alle specifiche o ad approfondimenti in linea. In particolare, abbiamo un campo location che localizza la fonte sonora. Abbiamo poi un campo direction che ne specifica la direzione, quattro campi (maxBack, minBack, maxFront, minFront) che specificano la regione in cui il suono è udibile e intensity che determina l’intensità del suono. Il campo spatialize serve per indicare se vogliamo un suono direzionale o uno di background. Ponendo a FALSE questo parametro avremo un sonoro di sottofondo.

L’ultimo campo che vediamo è il campo source. Questo campo contiene un nodo AudioClip che consente di specificare il file da usare e come farlo girare. AudioClip contiene infatti un campo url per indicare il nome del file da usare, un campo loop, uno startTime e uno stopTime.

Vediamo allora brevemente come mettere insieme il tutto. La cosa fondamentale da osservare è che vogliamo che il suono si attivi solo alla pressione dell’interruttore usato per far girare il cubo. Per cui dovremo legarci all’evento in uscita dal nodo TouchSensor.

Se non avessimo questa complicazione il funzionamento del nodo Sound sarebbe banale ; per una musica di sottofondo basterebbe infatti fare :

Sound {
  minFront -10
  maxFront 10
  minBack -10
  maxBack 10
  spatialize FALSE
  source AudioClip {
     description “bla bla bla”
     loop TRUE
     startTime 1
     url “mozart.mid”
  }
}

e il gioco è fatto, non dovendo interagire con eventi esterni. 

Qui invece il sonoro parte in conseguenza di una azione dell’utente. Vediamo allora in dettaglio come funziona AudioClip. L’attivazione è molto simile a quella del nodo TimeSensor : quando startTime viene raggiunto (c’è un orologio globale come abbiamo visto, rappresentato dal campo time) il nodo si attiva e si ferma quando raggiunge stopTime. Se stopTime viene impostato ad un valore inferiore a quello di startTime e loop è posto a TRUE il nodo rimane sempre attivo.

Dato che vogliamo un suono costituito da 3 impulsi del laser contenuto nel file laser.wav, dobbiamo imporre il campo loop a TRUE e impostare stopTime in modo tale da consentire 3 loops. Dato infine che il sonoro si attiva alla pressione dell’interruttore dovremo impostare startTime al valore della pressione e regolare di conseguenza stopTime.

Per riuscirci dobbiamo fare ricorso ad uno script.

Vediamo allora il sorgente da aggiungere all’esempio dei paragrafi precedenti.

Sound {
  location 0 1.25 -2
  minFront -10
  minBack -10
  maxFront 10
  maxBack 10
  spatialized TRUE
  source DEF laser AudioClip {
    description “laser all’avvio del cubo”
    loop TRUE
    startTime 0    #inizialmente e’ disattivato
    url “laser.wav”
  }
}
DEF accendi_spegni Script {
  eventIn SFBool clicked
  eventOut SFBool click_changed
  field SFBool active FALSE
  field SFTime duration
  eventIn SFTime set_duration
  eventOut SFTime SoundstopTime
  eventOut SFTime SoundstartTime
  url “ vrmscript :
    function clicked(button_pos, ts)
      if (button_pos == 0) {
        if (active == 0)
          active = 1 ;
        else
          active = 0 ;
        click _changed = active ;
        soundstartTime = ts ;
        soundstopTime = ts + duration ;
      }
    }
 function set_duration(value) {
    duration = value * 3;
  }
“
}
# riporto anche gli altri comandi di ROUTE in modo da  rendere più chiaro il processo.
ROUTE  interruttore.isActive TO accendi_spegni.clicked
ROUTE accendi_spegni.click_changed TO tempo.enabled
ROUTE tempo.fraction_changed TO orient_cubo.set_fraction
ROUTE orient_cubo.value_changed TO cubo.set_rotation
ROUTE suono.duration_changed TO accendi_spegni.set_duration
ROUTE accendi_spegni.soundstartTime TO suono.set_startTime
ROUTE accendi _spegni.soundstopTime TO suono.set_stopTime

Riporto ora il mondo completo, dove aggiungo dell'arredamento in modo da renderlo molto piu' realistico.

Stanza completa

Rimane da spiegare come ricavo la durata di un singolo loop. Questo valore viene esportato dal campo duration_changed del nodo AudioClip. Catturo l’evento in ingresso e lo setto al field interno duration in modo che lo possa usare in futuro (valore che moltiplico per 3 per avere l’effetto desiderato).