Vai al contenuto principale

Virtual Reality: Acustica. Un sistema prototipo per la simulazione del suono

Denis TumpicCTO • Chief Ideation Officer • Grand Inquisitor
Denis Tumpic serves as CTO, Chief Ideation Officer, and Grand Inquisitor at Technica Necesse Est. He shapes the company’s technical vision and infrastructure, sparks and shepherds transformative ideas from inception to execution, and acts as the ultimate guardian of quality—relentlessly questioning, refining, and elevating every initiative to ensure only the strongest survive. Technology, under his stewardship, is not optional; it is necessary.
Fai clic per visualizzare la copertina originale, l'abstract, la prefazione, ecc.

Amiga è un marchio registrato di Commodore-Amiga Inc.

"dbx" è un marchio registrato di dbx, Newton, Massachusetts, USA, una divisione di BSR NA Ltd.

Dolby A, B, C, S, Sr sono marchi registrati di Dolby Laboratories Inc., San Francisco, California

Dolby Surround è un marchio registrato di Dolby Laboratories Inc., San Francisco, California

Dipartimento di Scienze dell'Informazione Università di Lund S-221 00 Lund, Svezia ©1994 di Denis Tumpic

Lund University LUP Student Papers, Virtual Reality: Acustica. Un sistema prototipo per la simulazione del suono

LaTeX\LaTeX versione ©2008 di Denis Tumpic

Versione Docusaurus, traduzione italiana realizzata da LLM e modificata manualmente nel tempo ©2025 di Denis Tumpic

Till mina nära och kära

Abstract svedese

Al momento, i ray-tracer video sono molto diffusi sui computer personali, ma i ray-tracer audio non esistono in eguale varietà. Sul mercato commerciale non ne sono disponibili di accessibili a prezzi ragionevoli. Questo fatto, unito all'aumentato interesse odierno per gli ambienti VR, indica un forte bisogno di un ray-tracer audio che sia al contempo veloce e facile da usare. La visualizzazione presente in tutti i ray-tracer video dovrebbe avere un'equivalente acustica nel ray-tracer audio, e questa viene chiamata audibilizzazione (auralizzazione).

Inoltre, un programma di ray-tracing audio può essere uno strumento molto utile per migliorare l'acustica di ambienti già esistenti. Per un tale strumento non sono richiesti i medesimi requisiti di feedback in tempo reale che si presentano quando si desidera un ambiente VR di alta qualità. Questa relazione costituisce un'approfondita analisi del criterio acustico - 3D-Audio - nella definizione di ambienti VR avanzati. Un'introduzione breve al suono, alla percezione uditiva e all'elaborazione audio funge da premessa. Infine, definisco e riassumo gli ambienti VR. Nella sezione conclusiva discuto il lavoro svolto sul 3D-Audio in relazione a questi aspetti, nonché all'efficacia dell'interazione uomo-macchina e agli algoritmi legati alla generazione di campi sonori. Viene inoltre trattata l'auralizzazione, e viene presentata una possibile soluzione per questa.

Abstract

This report is a thorough look at the acoustic criteria - 3D-Audio - the strong definition of VR-environment. A brief introduction to sound, the human ear and audiohandling is given, and to conclude this introduction, a definition and summary of VR-environments. Finally I discuss the implementation of 3D-Audio with regard to these aspects, and to the effectiveness of human-computer- interaction and the algorithms in the sound-field-generation module. As a conclusion, the auralization stage is discussed and a possible solution is presented.

Prefazione

Questa relazione presenta un lavoro di laurea svolto durante il primo semestre del 1994 su un computer μ\mu di tipo Amiga. Il lavoro di laurea costituisce una dettagliata prologazione agli ambienti acustici VR. L'attenzione è stata rivolta all'interazione uomo-macchina e all'efficienza degli algoritmi per la sintesi di campi sonori.

Ringrazio i miei genitori per la loro pazienza nei miei confronti e per il loro prezioso sostegno nei momenti più difficili nel corso degli anni.

Desidero ringraziare Michael Dovits e Lars Malmborg per avermi stimolato con idee interessanti e progetti sperimentali nel corso degli anni. Per la prima stampa di alta qualità, Lars ha messo a mia disposizione la sua HP-550C.

Voglio ringraziare Lars Holmgren per la sua presentazione della video-ray-tracer Lightwave.

Ringrazio Roberth Frank per avermi fornito molte critiche costruttive e per avermi aiutato nella correzione del testo principale. Anche la vignetta a pagina 17 è stata da lui contribuita.

Desidero ringraziare il mio relatore in acustica, l'ingegnere di ricerca Erling Nilsson, per le sue chiarificazioni sull'argomento e per aver temperato i miei entusiasmi in tempo.

Infine, ringrazio il mio relatore presso il Dipartimento di Informatica e Analisi Numerica, Sten Henriksson, per la sua preziosa conoscenza e i suoi suggerimenti.

Malmö, novembre 1994
Denis Tumpic

Principi del suono e dell'udito

Original AIFF Image Original AIFF Image

It has long been an axiom of mine that the little things are infinitely the most important.

Sir Arthur Conan Doyle

Di seguito si trova una breve introduzione alla natura del suono e dell'udito. La ragione principale per cui ho scritto questo capitolo è quella di permettere a coloro che non hanno alcuna conoscenza del funzionamento del suono di formarsi un'idea su questo argomento. Anche i "vecchi volpi" dell'acustica dovrebbero leggere questo capitolo, per sostenere la mia successiva e fluida argomentazione nei capitoli successivi.

Ho cercato di affrontare i problemi meno evidenti dell'acustica per mostrare quali problemi esistano realmente. Per una eccellente panoramica dell'acustica (soprattutto in ambienti chiusi), rimando il lettore interessato a "Room Acoustics" di Heinrich Kuttruff. Per i principi dell'orecchio, raccomando l'"Encyclopedia Britannica", poiché contiene un ricco materiale informativo sull'argomento. Inoltre, "Audio-Engineering Handbook", curato da K. Blair Benson, è una lettura molto utile e preziosa per coloro che sono interessati anche all'aspetto tecnico.

La natura del suono

Il suono non è molto diverso dalla luce nella sua natura. La differenza sta nel fatto che si tratta di compressioni e rarefazioni di un mezzo, piuttosto che di un flusso costante di fotoni. Il suono si propaga in modo longitudinale, a differenza della propagazione trasversale della luce, come mostrato nella figura sottostante.

Onda trasversale in alto e onda longitudinale in basso, λ è la lunghezza d'onda.

Nella vita quotidiana siamo costantemente esposti a diverse forme di suono. Possono essere toni profondi che fanno vibrare oggetti. Questi toni sono chiamati toni infrasonici, e i nostri orecchi non li percepiscono bene; è invece la periferia del corpo a vibrare leggermente. Questo fenomeno è stato notato da tutti coloro che sono stati sorpassati da un camion pesante mentre pedalavano all'aperto. In particolare, tale fenomeno si manifesta quando il camion accelera. Ai toni infrasonici appartengono tutti i toni puri al di sotto dei 20 Hz. Con toni puri intendo toni costituiti da una semplice forma d'onda sinusoidale.

Il metodo utilizzato dai pipistrelli (Chiroptera) per rilevare oggetti è molto impressionante e può essere facilmente paragonato a un radar (RAdio Detection And Ranging). A differenza delle onde radio utilizzate dal radar, il pipistrello emette un tono acuto nella sua direzione di movimento per rilevare, ad esempio, la presenza di un ostacolo o di un oggetto lungo il suo percorso [1,2]. Questo tono acuto è chiamato tono ultrasonico, e tutti i toni puri al di sopra dei 20 kHz sono definiti così. Tra il range infrasonico e quello ultrasonico si trova l'udito normale dell'uomo.

Per questo motivo non è casuale che l'High-Fidelity venga definita, tra le altre cose, dalla capacità di riprodurre materiale registrato con una risposta in frequenza lineare nell'intervallo 20 Hz - 20 kHz [3, 4]. Con risposta in frequenza lineare si intende che sono ammesse piccole fluttuazioni nei range di frequenza adiacenti, e che la massima deviazione dalla media non può superare i 3 dB. Il decibel è un'unità relativa e in questo contesto è definita da 10log(PutPin)10\log(\frac{P_{ut}}{P_{in}}), dove P sta per potenza acustica. In natura si trovano numerose sorgenti sonore. In realtà, quasi tutto è in qualche modo una piccola sorgente sonora. Una persona che parla è ovviamente una sorgente sonora, ma anche quando sta completamente in silenzio, il suo corpo genera suoni. Tuttavia, questi suoni hanno un contenuto energetico molto inferiore rispetto alla voce. Quando un'orchestra sinfonica suona in forte fortissimo, abbreviato come fff nella notazione musicale e che indica che l'orchestra deve suonare estremamente forte, si genera appena circa 2,5 W di potenza acustica. La nostra stessa voce, che in questo contesto è ampiamente soverchiata dal boato dell'orchestra, raggiunge tipicamente circa 25 µW. È chiaro che siamo circondati da un flusso ininterrotto di suoni: dal gioco dei bambini del vicino al sussurro del sangue nelle orecchie.

Alcuni tipici livelli di pressione sonora per oggetti produttori di suoni comuni. Le distanze tra parentesi indicano la distanza di misura.

I suoni di solito consistono in molte tonalità composte che ne determinano la caratteristica. Queste tonalità hanno ampiezze (intensità) diverse e fasi differenti per costruire il suono. Per facilitare la gestione del concetto di frequenza, suddividiamo lo spettro delle frequenze in ottave.

La parola "ottava" proviene dal mondo della musica occidentale e indica un raddoppio della frequenza. La nostra musica si basa fondamentalmente su un sistema modulo-8: C1 D E F G A H C2 (ottava = 8). Matematicamente, sarebbe probabilmente modulo-7, ma i musicisti non usano lo zero come riferimento iniziale. Va aggiunto che qui ignoriamo i "tasti neri", poiché furono introdotti successivamente. Le misurazioni acustiche sono solitamente suddivise in intervalli di ottava, poiché ciò consente una rappresentazione naturale e semplice quando si analizza il materiale musicale.

L'ampiezza A e la fase j.

Durante un'analisi di frequenza (analisi di Fourier) del suono, possiamo visualizzarne la caratteristica. Per scomporre un suono nelle sue informazioni intrinseche, possiamo far operare un filtro passa-banda sui dati sonori provenienti da un microfono. Questi filtri passa-banda devono avere intervalli di frequenza limite disgiunti (non sovrapposti), e l'unione dei loro intervalli di frequenza deve coprire tutto l'intervallo di frequenze che stiamo considerando, se vogliamo una buona visualizzazione (figura 1.3). Per chiarire ulteriormente, un filtro passa-banda è un filtro che atenua fortemente tutte le frequenze superiori alla frequenza limite superiore e inferiori alla frequenza limite inferiore (vedi anche risonanza). I filtri, in generale, sono un ampio campo che non tratto nei dettagli. Chi desidera saperne di più sui filtri può consultare libri di telecomunicazioni.

Permettendo di integrare l'energia nei bandi di frequenza separati su un periodo di tempo determinato, che non deve essere necessariamente uguale per ogni filtro, possiamo visualizzare le informazioni in modo relativamente semplice. Questa visualizzazione è chiamata spettri sonori e può essere un modo appropriato per mostrare come un suono è strutturato, specialmente durante la produzione del suono.

Un'analisi di frequenza possibile di un suono in un dato intervallo temporale.

Propagazione del suono

La propagazione del suono non è affatto banale. Anche se sembra di natura semplice, va sottolineato che si tratta di oscillazioni meccaniche. Si prega il lettore di tenerlo a mente durante la lettura successiva. Inoltre, va sottolineato che il suono non può propagarsi nel vuoto, poiché il vuoto non contiene alcuna materia in grado di generare variazioni di pressione per la propagazione del suono. Poiché siamo circondati da enormi quantità di materia in diversi stati di aggregazione (a diverse pressioni e temperature), ciò rende difficile effettuare calcoli e assunzioni generali corretti. Tuttavia, esistono alcuni principi fondamentali che valgono anche per la luce.

Assumiamo di avere una sorgente isotropa, il che significa che la sorgente emette energia uniformemente in tutte le direzioni. Facciamo in modo che la sorgente emetta un impulso breve e, utilizzando microfoni, registriamo l'energia ricevuta a diverse distanze dalla sorgente sonora. Se effettuiamo questo esperimento all'aperto, senza oggetti significativi che interferiscano con le nostre misurazioni, scopriremo che l'energia diminuisce quadraticamente con la distanza.

Inoltre, possiamo affermare senza grandi riserve che, fintanto che l'ampiezza non è eccessiva, le compressioni e le rarefazioni si propagano a velocità costante. La velocità di propagazione del suono nell'aria, con umidità normale e 20o20^o °C, è di circa 343 m/s. Questa velocità è piuttosto modesta se paragonata alla velocità della luce, che è di circa 300.000.000 m/s nel vuoto. Tuttavia, la velocità del suono è comunque molto più veloce della mia auto, anche in discesa, con vento a favore e nostalgia di casa.

Riflessione e assorbimento

Tutti abbiamo sperimentato almeno una volta di essere confusi nel vedere la fonte sonora, mentre il suono sembrava provenire da una direzione completamente diversa. In condizioni estreme, questo può accadere. Il suono diretto viene assorbito così intensamente che le riflessioni dominano l'immagine sonora. Ciò comporta che la fonte sonora sembri dislocata, e si ha l'impressione che il suono non abbia una consistenza fisica. L'approccio ingenuo potrebbe supporre che il suono si comporti come la luce durante riflessione e assorbimento, ma si tratta di un'approssimazione molto grossolana che funziona solo in casi estremamente semplici. Nel caso delle riflessioni sonore, l'onda riflesso dipende dall'angolo di incidenza, dalla natura della superficie, dalla massa dell'oggetto riflettente e dalla caratteristica del suono.

Interpretazione geometrica della propagazione del fronte d'onda nella riflessione. Direzione dei raggi sonori.

Il fatto che la riflessione dipenda dalla caratteristica del suono implica che essa è dipendente dalla frequenza e dalla fase. Inoltre, abbiamo il grande problema che le onde sonore piane di solito non esistono in natura. Un'onda sonora piana dipende solo dal tempo e da una direzione. Ciò significa che non possiamo mai avere onde sonore parallele. Di conseguenza, l'ipotesi di utilizzare la natura della luce nei calcoli sulla propagazione del suono è fuorviante.

Interferenza

Consideriamo due sorgenti sonore identiche che emettono informazione coerente. Inoltre, queste sorgenti sonore sono posizionate arbitrariamente nello spazio. Secondo il principio di sovrapposizione, che funziona anche per i segnali elettrici, i contributi delle sorgenti sonore si sommano linearmente in ogni punto dello spazio. Con "punto" intendo qui un piccolo area delimitata che può contenere la frequenza più alta caratteristica del suono. Si noti che questa area dipende anche dal mezzo in cui il suono si propaga.

Due segnali sovrapposti con la stessa ampiezza e frequenza ma fasi relative diverse. Si noti lo specchiamento della fase totale dopo 180º.

L'interferenza è solitamente suddivisa in due gruppi: l'interferenza costruttiva e quella distruttiva. Nell'interferenza costruttiva, le due sorgenti sonore cooperano nel punto specifico considerato. Oscillano in fase e generano un rafforzamento del segnale. L'interferenza distruttiva, che si verifica quando le sorgenti sonore non oscillano in fase, produce un segnale attenuato nel punto considerato, come chiarito nella figura sopra. In natura, questo fenomeno si verifica naturalmente a causa dell'interferenza tra suono diretto e suono riflesso. L'interferenza può essere sfruttata per scopi pratici e utilizzata come smorzatore di rumore. L'idea semplice consiste nel posizionare microfoni vicino alla sorgente di rumore e, a una distanza appropriata, collocare un altoparlante che emette un segnale sfasato per annullare la sorgente di rumore. Questa idea è nota come smorzamento attivo del suono. Sebbene sembri relativamente semplice costruire un prototipo, dobbiamo affrontare alcuni problemi. Il primo problema è che introduciamo energia sonora nel sistema. Poiché l'energia aggiunta non può essere utilizzata in modo selettivo (vedi onde sonore piane), il nostro prototipo causerà amplificazioni in alcuni punti. Il rumore è spesso di natura complessa e dipende dal tempo, il che ci pone un ulteriore problema difficile. Non è del tutto impossibile realizzare smorzatori attivi, ma con la tecnologia odierna è comunque troppo costoso rispetto agli assorbitori sonori passivi.

Diffrazione

Questo fenomeno è semplice da comprendere, ma la sua natura è molto complessa. Il fenomeno si verifica quando un suono viene deviato attorno a un oggetto. Durante la diffrazione, l'onda sonora diventa disordinata e il risultato è che possiamo, ad esempio, sentire attorno agli angoli. La quantità di suono che viene diffuso dipende dalla forma dell'oggetto schermante e dalle caratteristiche del suono. Le componenti a bassa frequenza delle caratteristiche sonore non vengono disturbate da oggetti piccoli. Al contrario, le componenti ad alta frequenza, che hanno una lunghezza d'onda molto più corta, sono facilmente disturbate da vari oggetti ostacolanti sul percorso. Tutti noi abbiamo visto come le onde d'acqua con lunghe creste non vengano influenzate dai galleggianti che si trovano casualmente sul loro cammino.

Diffrazione delle basse frequenze e riflessione delle alte frequenze.

Il fenomeno di diffrazione non viene considerato quando si effettua un'interpretazione geometrica della propagazione del suono, poiché il postulato principale dell'interpretazione geometrica è la natura rettilinea. Quando si tratta di caratteristiche sonore complesse con un ampio intervallo di frequenze e quando le sorgenti sonore non sono coerenti, si può anche trascurare l'interferenza [5].

Rifrazione

Il suono che si propaga per lunghe distanze subisce probabilmente variazioni di temperatura e/o correnti. Quando il suono si muove verso il gradiente di queste variazioni, le onde sonore vengono deviate e possiamo quasi paragonare il risultato a una lente ottica. Naturalmente, la rifrazione si verifica quando c'è un'inversione termica/vento a favore o un gradiente termico/vento contrario. Quando si analizzano ambienti inferiori a 10.000 m³, possiamo trascurare questi effetti poiché le differenze di temperatura non raggiungono neppure un grado intero e il vento di solito non si verifica in spazi chiusi. Va tuttavia aggiunto che il calore corporeo umano, che forma un guscio attorno al corpo [6], possiede le differenze termiche necessarie, ma la sua estensione è di norma così limitata da non produrre alcun effetto significativo sull'esperienza uditiva.

Rifrazione del suono dovuta al vento e alle variazioni di temperatura.

Risonanza

Quando una forza di eccitazione agisce su un sistema oscillante, il sistema oscillerà in sincronia con la forza eccitatrice. Quando rimuoviamo l'eccitazione, il sistema si adatterà alla frequenza naturale del sistema. Questa frequenza è chiamata frequenza di risonanza ed è una componente fondamentale nei calcoli di tutti i sistemi oscillanti. Teoricamente, quasi tutto nel mondo fisico può essere riscritto come uno sviluppo in serie di Taylor. Troncando tutti i termini superiori al secondo ordine in questo sviluppo, rimane un'equazione differenziale del secondo ordine che sappiamo descrivere un sistema oscillante. Questa approssimazione approssimativa indica che tutto in natura è un sistema oscillante. Un sistema oscillante può essere descritto in molti modi diversi, ma il modo più comune è attraverso il fattore di qualità Q.

Calcolo del fattore Q (3 dB corrisponde alla metà della potenza massima).

L'importanza del fattore di qualità in dispositivi come ricevitori radio, altoparlanti e strumenti musicali è molto grande. Per garantire una buona selettività (capacità di selezione) al ricevitore radio, è necessario un alto valore Q nel modulo selettore (stadio HF), che estrae la stazione di ascolto dalle onde radio. In generale, i progettisti di altoparlanti devono costruire dispositivi con un basso valore Q, per evitare distorsioni del suono. Per quanto riguarda gli strumenti musicali, è la caratteristica dello strumento che deve essere enfatizzata, ed è il costruttore dello strumento che scolpisce e leviga infinitamente lo strumento fino a quando non raggiunge le corrette proprietà di risonanza.

Direttività

I trasmettitori omnidirezionali, le onde radio non hanno una direzione specifica poiché si diffondono uniformemente. Tutto ciò vale anche per i ricevitori, ma con la differenza che le onde sonore sono dirette verso l'interno anziché verso l'esterno. Tuttavia, la maggior parte dei trasmettitori non è omnidirezionale, bensì presenta una certa direzionalità nella informazione che trasmettono. Inoltre, la direzionalità dipende dalla frequenza, come si può osservare nelle illustrazioni riportate di seguito. Ciò rende chiaro che le basse frequenze tendono ad essere molto più omnidirezionali rispetto alle alte. Un ulteriore fattore che complica i calcoli è il fatto che la direzionalità dipende dal design del trasmettitore.

Diagramma semplificato della direttività di una tromba e di un violoncello a diverse frequenze. Estratto da [10].

Riverberazione

Il primo suono che l'ascoltatore sente è il suono diretto proveniente dalla sorgente sonora, che viaggia in linea retta verso le sue orecchie. Questo è il principio della prima onda di fronte, e L. Cremer fu il primo a riconoscere e formulare questo fatto. Dopo il suono diretto, seguono le prime riflessioni provenienti dal soffitto, dalle pareti, dal pavimento e da vari oggetti di grandi dimensioni. Le prime riflessioni percorrono una traiettoria più lunga e raggiungono le nostre orecchie in un momento successivo, tipicamente entro i primi decimi di secondo. Se si verifica una riflessione molto forte dopo i primi decimi di secondo, la consideriamo un'eco. L'eco è, a differenza del riverbero che produce un segnale confuso e nebbioso, un segnale sonoro distinto e riconoscibile. I suoni che arrivano successivamente e che non sono riflessioni nel senso stretto (riflessioni di ordine superiore), si considerano suoni di riverbero. Il tempo di durata del riverbero, che è una parte fondamentale nei calcoli acustici, può essere calcolato utilizzando la formula di Sabine. Esistono diverse formule per il calcolo del tempo di riverbero, ma quella menzionata è la più adatta allo scopo nei modelli generali. Una volta calcolato il tempo di riverbero (T60T_{60}), possiamo applicare diversi criteri qualitativi acustici allo spazio di osservazione. Questi criteri qualitativi si basano sulla risposta all'impulso della stanza, che nella forma visualizzata è chiamata riflettogramma ed è una funzione della pressione sonora rispetto al tempo (vedi figura 1.10).

Per ottenere la risposta all'impulso della stanza, generiamo una pulsazione energetica molto breve, detta impulso di Dirac. Un impulso di Dirac è una pulsazione la cui intera energia è concentrata nel momento iniziale — vedere l'appendice B per la definizione completa. Questa pulsazione può essere approssimata efficacemente utilizzando una pistola o uno schiocco di mani. I criteri qualitativi più utili sono la Chiarità, la Distintività, il Tempo di Salita e l'Efficienza Laterale. Questi sono stati sviluppati sperimentalmente su base soggettiva, ma risultano estremamente utili nelle costruzioni acustiche.

Possibile risposta all'impulso di una stanza. Td è il suono diretto e Tr è l'inizio della riverberazione, che costituisce un confine sfumato, e T60T_{60} è il tempo di riverberazione. Vedere l'allegato B per le formule.

Dispersione

Quando il suono si propaga in un mezzo che non trasmette le frequenze alla stessa velocità, si verifica la dispersione. Questo fenomeno si manifesta spesso quando il suono viaggia in liquidi viscosi o gas densi. In questi mezzi, la velocità del suono aumenta con l'aumento della frequenza; notare che questo è esattamente l'opposto della dispersione ottica nei materiali di vetro comuni.

Effetto Doppler

Finora abbiamo considerato solo sorgenti e ricevitori sonori statici. Se permettiamo alle sorgenti e ai ricevitori sonori di essere oggetti mobili nello spazio, le onde sonore si comprimeranno nella direzione di movimento. Questa compressione comporta uno spostamento verso l'alto della caratteristica sonora in frequenza. Nella direzione di allontanamento, le onde sonore si espanderanno, causando uno spostamento verso il basso in frequenza. Questo fenomeno si verifica anche per la luce, ed è proprio per questo che possiamo determinare se un corpo celeste si sta avvicinando o allontanando da noi.

L'effetto Doppler è così chiamato in onore del fisico austriaco Christian Doppler. Egli notò che il fischio del treno che si allontanava dalla stazione cambiava la sua caratteristica sonora. Tuttavia, ciò che udì non era solo l'effetto Doppler: la rifrazione coesisteva, poiché esistono turbolenze attorno al treno in movimento. Queste turbolenze non approfondirò ulteriormente, poiché è generalmente accettato che si tratti di sistemi caotici e che la potenza computazionale necessaria per risolverli numericamente è enorme.

Esperienza del Suono

Nella vita quotidiana normale, non siamo interessati alla qualità del suono che raggiunge i nostri orecchi. È durante l'ascolto di musica e parlato, quando visitiamo aule per conferenze, opere, teatri o cinema che richiediamo una certa qualità sonora. Di seguito sono riportati alcuni criteri, selezionati da [7], che l'ascoltatore può utilizzare per caratterizzare la qualità del suono.

Chiarezza (Clarity)

Voti elevati in questa categoria richiedono un sistema acustico che riproduca un ampio spettro di frequenze, abbia una risposta in frequenza lineare e bassa distorsione non lineare. Il criterio della distorsione non lineare deve essere considerato quando si valutano sistemi di riproduzione come altoparlanti e simili.

Luminosità, Nitidezza e Pienezza

Quando il sistema acustico riproduce le alte frequenze con un timbro leggermente esagerato, questa esperienza viene percepita come luminosità (brightness). Con un timbro ancora più esagerato, l'esperienza si trasforma in nitidezza (sharpness), in parte simile a un grido. L'opposto, quando le basse frequenze diventano dominanti, è chiamato pienezza (fullness).

Sensazione di Spazio e Prossimità

Questi criteri sono quasi autoesplicativi: la sensazione di spazio (spaciousness) aumenta quando il materiale ad alta frequenza (tipicamente nell'intervallo 500–4000 Hz) che raggiunge le nostre orecchie presenta significative differenze (bassa correlazione). Minore è la differenza, più vicino sembra essere il suono all'ascoltatore.

Intensità (Loudness)

Questo criterio è autoesplicativo, ma non deve essere confuso con la nitidezza né considerato un'esperienza estremamente sgradevole.

Organo dell'udito

Qui di seguito una breve introduzione all'orecchio e alla sua anatomia. Inoltre, ho un breve approfondimento sulle tecniche recenti di compressione audio.

Anatomia dell'orecchio

L'organo uditivo umano. Il suono viene concentrato nel condotto uditivo, quindi amplificato nell'orecchio medio e infine convertito in impulsi elettrici nell'orecchio interno. L'orecchio interno contiene anche l'apparato dell'equilibrio.

Le orecchie sono le nostre antenne per la ricezione del suono e possono essere suddivise in tre parti principali (vedi figura sopra). L'orecchio esterno, la cui forma ricorda una tromba, funge da amplificatore direzionale. Il lettore dovrebbe ricordare la direttività della tromba dalla sezione precedente. L'amplificazione deriva dal fatto che una grande superficie di pressione sonora all'orecchio esterno viene compressa su una piccola superficie di pressione sonora all'orecchio interno; poiché l'energia rimane la stessa ma è più concentrata, si ottiene un amplificazione del suono (la pressione aumenta con la riduzione dell'area). Secondo Shaw [8], le frequenze superiori a circa 2 kHz risultano sia riflettenti che risonanti nella complessa struttura dell'orecchio esterno, il che conferisce una colorazione al suono ricevuto.

Quando le onde sonore raggiungono la membrana timpanica, dopo essere state diffratte dal capo e colorate dall'orecchio esterno, le variazioni di pressione dell'aria vengono trasformate in variazioni di pressione dei liquidi nell'orecchio medio, per poi essere convertite in impulsi nervosi elettrici nell'orecchio interno, che inviano i segnali al cervello per l'analisi. I nostri orecchi sono più sensibili nella regione intorno ai 4 kHz e meno sensibili nelle basse frequenze, come mostrato nella figura 1.12. Per ulteriori letture, consiglio l'“Encyclopedia Britannica” [9].

Le coclee non ricevono informazioni solo dall'orecchio esterno: il nostro cranio fornisce una notevole porzione del suono, poiché l'osso è un buon conduttore del suono. Un semplice esperimento consiste nel mordere un orologio meccanico: si riesce a "sentire" il ticchettio.

Quando ascoltiamo con le cuffie, manca l'informazione aggiuntiva proveniente da questa conduzione ossea e il suono sembra leggermente "smorzato", anche se non del tutto privo di carattere. La nostra voce viaggia principalmente lungo questo percorso attraverso il cranio. Questo spiega la repulsione verso l'ascolto della propria voce registrata su nastro: il suono viene fortemente colorato e in modi diversi. Qualcosa che approfondisce ulteriormente l'esperienza uditiva e che non si verifica durante l'ascolto con cuffie è la sensazione del suono nello stomaco, in particolare i toni molto bassi ad alta pressione sonora. Un fattore che la maggior parte delle persone non conosce o non considera è quando, dopo un periodo trascorso all'aperto nel freddo, entriamo in un ambiente caldo. Per godere appieno dell'esperienza, iniziamo ad ascoltare un po’ di musica. Ciò che si percepisce allora è che tutto suona male, poiché i nostri timpani sono rigidi a causa dell'esposizione all'aperto. Esistono ulteriori cause per cui il suono appare così, ma la principale è quella appena menzionata. Questo fenomeno si verifica in tutte le significative variazioni climatiche, ma l'intensità dell'esperienza è molto individuale.

La pressione sonora necessaria perché l'orecchio percepisca diverse frequenze con la stessa intensità di un tono di riferimento a 1 kHz. Queste curve sono chiamate curve phon. Disegno libero dall'Organizzazione Internazionale per la Standardizzazione, Raccomandazione R226.

Mascheramento

Il livello sonoro di una sorgente sonora che interagisce con altre sorgenti sonore viene colorato da queste ultime. Questa colorazione è chiamata mascheramento, e la frequenza fondamentale delle sorgenti sonore interagenti determina in quale banda di frequenze il mascheramento ha l'effetto maggiore. Gli armonici della frequenza fondamentale contribuiscono al mascheramento alle frequenze più alte, mentre le sottotonalità — meno numerose e più smorzate — contribuiscono alle componenti a bassa frequenza.

Questa è un'immagine semplificata del fenomeno, poiché suoni complessi che non provengono dal mondo musicale non possiedono una frequenza fondamentale distinta di natura armonica. Può sembrare un po’ confuso che un suono abbia una frequenza fondamentale indistinta, e qui di seguito ne viene data un'esplicazione. La frequenza fondamentale può essere definita come la prima frequenza che emerge in un'analisi spettrale complessiva del suono. Se consideriamo la frequenza fondamentale come variabile nel tempo (intervalli temporali piccoli, inferiori a circa 30 ms), come avviene di solito in contesti complessi, la frequenza fondamentale risulterà indistinta. Quando si tratta di suoni puramente musicali, la seconda rappresentazione è un po' superflua, poiché la maggior parte dei suoni con fondamentali indistinte sono dissonanti e non utilizzabili in brani musicali "veri". Gli armonici della fondamentale possono essere più forti della fondamentale stessa, e per tutti gli strumenti musicali questi armonici sono molto importanti. Qualcosa che ulteriormente colora la caratteristica sonora dello strumento è se l'armonico più forte ha energia costante, indipendentemente dalla fondamentale (formanti). Per una lettura esaustiva sulle caratteristiche degli strumenti musicali, rimando l'interessato a [10,11].

Soglia di udibilità per diverse frequenze con (a) suono isolato, (b) rumore a banda stretta (400 ± 50 Hz) a 80 dB e (c) una tono puro di 400 Hz a 80 dB come suono di mascheramento. Da Donald B. Hall, Musical Acoustics: An Introduction, Wadsworth, Belmont, CA 1980.

L'effetto di mascheramento non è sempre indesiderato, poiché può nascondere distorsioni peggiori che sono molto più dissonanti nel contesto musicale. Quando le sorgenti sonore interagiscono nella stessa dominio temporale e nel medesimo dominio di frequenza, si parla di mascheramento simultaneo. È chiaro dai ragionamenti precedenti che i suoni con componenti a bassa frequenza elevate disturbano più facilmente i suoni con componenti ad alta frequenza elevata, e non viceversa. Spesso le sorgenti sonore non agiscono nello stesso dominio temporale, e in tal caso si parla di mascheramento temporale. Abbiamo due tipi di mascheramento temporale: il mascheramento anticipatorio e il mascheramento retroattivo. Il mascheramento anticipatorio è causato da effetti che persistono dopo l'impatto fisico sui nostri orecchi. Tutti noi abbiamo sperimentato almeno una volta un suono molto forte che ci ha causato una breve sensazione di sordità temporanea.

L'esempio potrebbe essere un po' estremo, ma il principio e i suoi effetti sono sempre presenti. Tuttavia, non sono così marcati come nell'eccezione estrema. Poiché il nostro cervello elabora le informazioni in parallelo e a velocità diverse, accade anche il contrario. Questo può sembrare un po' strano per alcuni lettori, e qui di seguito una spiegazione. In particolare, se il suono successivo è molto più forte di quello precedente, i neuroni [12] tenderanno a "trattare in modo di panico" il suono più forte, causando l'"oblio" del suono debole. La mascheratura ha attualmente una pratica utilità nei prodotti audio. Esempi di ciò sono Philips DCC (Digital Compact Casette) e Sony MD (Mini Disc). Per riuscire a comprimere i dati in modo efficiente senza perdite in formato digitale, possiamo utilizzare la codifica Huffman, che comprime i dati fino al 90% a seconda del flusso di dati.

Quando si tratta di audio e immagini, possiamo permetterci una certa perdita dei dati originali per ottenere un tasso di compressione ancora più elevato. In tal caso, possiamo utilizzare la compressione frattale, ma questa tecnica è estremamente lenta se dobbiamo effettuare registrazioni in tempo reale su supporti multimediali. Ciò che rimane è un'idea sia efficace che sicura.

Ciò che i produttori hanno sviluppato è suddividere la banda di frequenza e analizzare le componenti in confronto tra loro, calcolando quali bande di frequenza sono portatrici di informazioni. La trappola consiste tuttavia nell'eliminare le informazioni superflue nei portatori di dati, che forse non sono udibili o visibili. Notate che scrivo "FORSE", poiché i criteri su cui si basa questa procedura di filtraggio sono molto individuali. Coloro che non sono particolarmente esigenti riguardo al suono e che in realtà non hanno mai ascoltato attentamente la musica riprodotta dal loro impianto stereo, sicuramente ritengono che suoni identico. Tuttavia, esiste una notevole quantità di persone che amano la musica e il paesaggio sonoro più di ogni altra cosa, e queste sono molto esigenti in termini di qualità del suono e riescono facilmente a percepire le differenze.

Riflesso acustico

La riflessione meno conosciuta nel nostro corpo è il riflesso acustico. Questo si attiva involontariamente nella maggior parte delle persone quando onde di pressione sonora superiori a 80 dBA raggiungono le loro orecchie. Il riflesso funge da protezione per le nostre orecchie dai suoni forti, oppure dal nostro masticare e parlare. I medici non sono concordi su quale dei due scopi sia quello per cui il riflesso si è evoluto, ma la mia opinione personale è che entrambi i ruoli siano sufficienti affinché la natura abbia evoluto questa soluzione. La velocità con cui il riflesso reagisce è di circa 150 ms alla soglia e di circa 10 ms per suoni molto forti [13]. Il problema con questo riflesso è che il timpano si tende, riducendo l'amplificazione (il che è di per sé positivo), ma la risposta in frequenza cambia in modo non lineare (il che non è positivo). Quando il suono forte scompare, il riflesso si rilassa lentamente. Suoni deboli (in realtà perfettamente udibili quando il riflesso è completamente rilassato) che arrivano durante il periodo di rilassamento (il cui tempo dipende da fattori come l'individuo, l'umore e il clima) non vengono uditi bene, poiché il riflesso attenua la pressione sonora da 10 a 30 dB, a seconda delle caratteristiche del suono.

Tuttavia, questa funzione ha un aspetto divertente per coloro che possono volontariamente controllare questo riflesso: attenua il rumore di fondo durante le sessioni di scrittura o le lezioni. Questa "funzionalità" può addirittura attenuare la voce di un politico sgradevole. Anche a casa, il riflesso può essere utile, come illustrato dalla seguente barzelletta:

Den bekymrade fru Svensson ringer sin husläkare: Snälla doktorn, det är något fel på min man. Jag kan tala till honom i timmar och efteråt verkar han inte ha hört ett ord!

Doktorn: Det är ingen sjukdom, det är skicklighet!

Sfortunatamente, il riflesso non funziona per gli strilli ad alta frequenza dei bambini piccoli, i cui risorse sonore sono enormi quando realmente necessarie. Durante impulsi sonori transitori (tipo impulso di Dirac), il riflesso non ha tempo di attivarsi, e il fatto di poter controllare volontariamente questo riflesso in tali momenti è di vitale importanza.

Elaborazione audio

It is the nature of all greatness not to be exact.

Edmund Burke

In questo capitolo ho fornito un riassunto molto breve dello sviluppo della produzione di segnali. Ho fatto questo per poter affermare con la massima forza il forte aspetto dei media digitali. Alla fine, tratto i problemi che sorgono quando dobbiamo elaborare segnali tramite computer, mostrando gli svantaggi derivanti dalla discretizzazione dei segnali continui.

Durante la discretizzazione, è necessaria un'aritmetica "esatta" nei calcoli, a differenza del corrispondente analogico in cui possiamo sommare e moltiplicare utilizzando amplificatori operazionali. Si noti che l'"esattezza" va persa in entrambi i casi: se si tratta di un sistema digitale, ciò avviene durante la conversione dal segnale analogico; se si tratta di segnali continui, avviene durante i calcoli.

Poiché ho scritto solo sugli aspetti che sottolineano il mio obiettivo nel lavoro di laurea, la presentazione potrebbe sembrare un po' frammentaria. Per affrontare tutto ciò che mi ha influenzato in questo campo, occorrerebbe un libro. Di conseguenza, rimando coloro che sono molto interessati alla produzione audio alle numerose informazioni e referenze disponibili nel "Audio Engineering Handbook", compilato da K. Blair Benson.

Audio analogico

Alla fine del secolo scorso, Thomas Alva Edison inventò un registratore audio analogico in grado di catturare fino a 30 secondi di informazioni sonore. Il registratore di Edison incideva una traccia su un cilindro rivestito di foglio, e la qualità del suono era sorprendentemente buona. Successivamente, l'inventore danese Valdemar Poulsen inventò il primo registratore magnetico. Le informazioni sonore venivano registrate su un filo d'acciaio, e il suono era migliore rispetto a quello della macchina di Edison, poiché la forza elettrica generata dalle fluttuazioni magnetiche era superiore a quella prodotta dalle incisioni meccaniche di Edison. Da allora, questa tecnologia è stata perfezionata fino a riprodurre suoni con un'eccezionale qualità, in modo da risultare estremamente naturale.

I primi apparecchi erano mono, con un'unica canale di informazione sonora, il che si rivelò insufficiente per ottenere un'esperienza audio immersiva. La maggior parte di coloro che lavoravano allo sviluppo della riproduzione analogica del suono comprese questo limite, e non passò molto tempo prima che venissero realizzate registrazioni stereo. Per ottenere un'esperienza spaziale del suono registrato, è necessario poter riprodurre frequenze alte durante la riproduzione, in linea con il modo in cui l'orecchio umano percepisce la distanza e la direzione, come descritto nel capitolo precedente. Per ampliare il limitato (secondo gli standard odierni) intervallo di frequenza delle macchine precedenti, era necessario un approccio innovativo, poiché il filo d'acciaio risultava piuttosto scomodo. BASF (Badische Anilin- und Soda-Fabrik) non tardò a cogliere questa opportunità. Già nel 1928 avevano realizzato un prototipo del nastro magnetico moderno, composto da carbonile di ferro su base di carta. Questi nastri con rivestimento magnetico sono stati successivamente utilizzati sia per registrazioni audio che per l'archiviazione dei dati provenienti dai computer. Il problema è che il supporto è sequenziale, e i tempi di ricerca per trovare un frammento di suono o dati possono talvolta essere estremamente frustranti. Per facilitare il trattamento del suono, i produttori hanno sviluppato macchine con diversi canali. Al momento, esistono registratori a nastro da 1 a 96 canali per la registrazione di informazioni sonore o segnali di controllo. Sicuramente esistono studi di produzione con registratori ancora più avanzati, ma la maggior parte dei produttori musicali ha bisogno di al massimo 32 canali o meno.

Per completare la definizione di High-Fidelity, la dinamica della pressione sonora deve poter essere riprodotta senza rumore e distorsione. Inoltre, la riverberazione deve essere approssimata al massimo grado possibile, e nelle registrazioni multicanale le differenze reciproche devono essere conservate integralmente [3,4].

La dinamica dei migliori studi di registrazione è di circa 140 dB (Pukstudio in Danimarca), il che potrebbe sembrare eccessivo, poiché la maggior parte delle forme musicali popolari ha un intervallo dinamico molto ridotto (tipicamente inferiore a 20 dB). Tuttavia, alcune musiche serie sono molto dinamiche e richiedono un'alta dinamica per catturare sia i passaggi estremamente forti (fff = forte fortissimo) che quelli estremamente deboli (ppp = piano pianissimo). Se vogliamo davvero ascoltare l'intera esperienza sonora, dovremmo, in accordo con la tabella 1.1, utilizzare un sistema di riproduzione con un intervallo dinamico di circa 130 dB. Per le persone normali, ciò non è una necessità necessaria e raramente indispensabile in ogni situazione. Tuttavia, per esperienze sonore occasionali, come ad esempio in un planetario con 1800180^0 schermo cinematografico, potrebbe rivelarsi molto apprezzabile. Il nastro magnetico ha un limite intrinseco per il massimo intervallo dinamico possibile, che attualmente si aggira intorno agli 80 dB con i migliori registratori a nastro. Per aumentare l'intervallo dinamico, possiamo far passare il suono attraverso un compressore prima che venga registrato sul nastro. Esistono diversi sistemi di compressione, tra cui Dolby A, B, C, S, SR e dbx. Il sistema di riduzione del rumore Dolby comprime in modo non lineare nell'intervallo di frequenze, come mostrato nella figura 2.1. Tuttavia, Dolby SR presenta una compressione dinamica non lineare a bande di frequenza e ricorda un po' la cancellazione del suono mascherato (vedi capitolo precedente sulla mascheratura), anche se il sistema non rimuove le informazioni, bensì amplifica quelle al di sopra del livello di rumore del nastro o le attenua al di sotto della soglia di distorsione.

L'ultimo esempio, dbx, presenta una compressione lineare su tutto l'intervallo di frequenze e per tutti i livelli del segnale. Il problema di comprimere tutto in un unico intervallo di frequenza è che i bassi tendono a fluttuare (pumping), un problema che le moderne configurazioni digitali evitano. Per ascoltare il materiale compresso, è necessaria una procedura inversa, chiamata espansione. Si noti che questa compressione/espansione non comprime o espande i dati nel dominio della frequenza o del tempo, ma nel dominio dinamico (cfr. capitolo precedente sulla mascheratura).

Compression/expansion dei segnali; il grafico superiore mostra la companding dbx tipo I 1:2:1 e quello inferiore mostra Dolby B. Per dbx la companding è lineare in tutto lo spettro di frequenze, mentre per Dolby B è dipendente dalla frequenza. Il grafico di Dolby B è stato disegnato a mano libera da "Audio Engineering Handbook", curato da K. Blair Benson.

Audio digitale

Anche se i media digitali sembrano nuovi, esistono dal 1961 e la teoria risale al 1937. Sono stati necessari quasi 25 anni perché i ricercatori trasformassero la teoria in pratica, e oggi possiamo "godere" dell'audio digitale. Il vantaggio offerto dai metodi di memorizzazione digitale è che diventa più facile gestire le informazioni registrate. Tuttavia, non diventa più semplice se si continua a utilizzare i supporti magnetici sequenziali; è quindi necessario un modo più intelligente per memorizzare i dati. Per aumentare l'utilizzabilità, si possono memorizzare i dati su un disco circolare. Un ulteriore vantaggio che otteniamo con questa scelta è la riduzione dell'usura del supporto. Meccanicamente, questa soluzione è altrettanto semplice di un giradischi, ma le tolleranze sono molto più rigide. È fondamentale avere pochissimi componenti meccanici nelle costruzioni, poiché i passaggi di stato meccanici richiedono molto tempo e spesso producono rumori sgradevoli (metallo contro metallo).

L'ago del normale giradischi, che tenta di seguire un segnale gravato modulato a croce sul disco (a sinistra), e una rappresentazione molto semplificata della controparte meccanica e digitale più semplice (l'ago laser) a destra, che tenta di seguire tracce incise binarie.

La maggior parte della natura è continua, e le onde sonore non fanno eccezione. Tuttavia, si osserva una discontinuità quando "sopraffacciamo" l'onda sonora, ed è questa discontinuità che viene percepita come un boato; tuttavia, nella maggior parte dei casi le onde sonore sono molto più dolci. Poiché i supporti di memorizzazione analogici hanno in linea di principio una larghezza di banda molto ampia, disponiamo di un ampio intervallo di frequenze. I moderni lettori di nastro video registrano facilmente informazioni nella banda 0-3 MHz, e questo è solo l'intervallo di frequenze visibile. Possiamo sospettare una risoluzione leggermente eccessiva del materiale, poiché i nostri occhi e orecchie hanno un numero finito di cellule sensoriali in grado di elaborare i dati in ingresso. Di conseguenza, il passaggio alla digitalizzazione del materiale analogico non è molto lungo. Il vantaggio di questo approccio è che comprimiamo enormemente (teoricamente in modo infinito) la quantità di dati, e non abbiamo più bisogno di supporti di memorizzazione ingombranti e complicati. La tecnologia odierna forse non mostra appieno il potenziale dei supporti digitali, ma il seguente esempio numerico dovrebbe dissipare la maggior parte delle nebbie. Supponiamo di poter, grazie all'uso del laser (Light Amplification by Stimulated Emission of Radiation) e di un'ottica raffinata, suddividere informazioni su alcune nanometri. Considero questo un limite ragionevole, poiché a lunghezze d'onda più corte sarebbero necessari raggi radioattivi per risolvere la suddivisione. Inoltre, supponiamo che una sfera con un diametro di 1 cm contenga informazioni digitali, dove ogni bit è una sfera di qualche nanometro di diametro.

Questo ci fornisce circa 110181 \cdot 10^{18} byte a nostra disposizione, e se confrontiamo quanti dei moderni dischi compatti (inglese: Compact Disc = CD) sarebbero necessari per memorizzare questa quantità di dati, otteniamo circa 3 miliardi di unità. In altre parole, possiamo memorizzare la vita di tutti, in forma testuale e anche con immagini e suoni importanti, in poche di queste sfere. Se comprimiamo le informazioni ad esempio con la codifica Huffman, riusciremo a inserire ulteriori dati e probabilmente ridurremo tutto a una singola sfera, e come extra potremo includere tutti i dati relativi alla storia mondiale con tutte le immagini mai scattate, film, dischi e opere teatrali.

Don't you think it's blinding??? You name it, you've got it!!!

Il principale vantaggio dell'informazione memorizzata digitalmente e disponibile su supporti non sequenziali è che possiamo "tagliare e incollare" senza danneggiare i dati originali. In passato, l'utente doveva tagliare direttamente sul nastro per ottenere l'ordine desiderato. Per farlo senza distruggere il nastro originale, era necessario creare una copia e tagliare quella. La copiatura del nastro master, se vogliamo mantenere una buona qualità, richiede un tempo eccessivamente lungo e la qualità risulta sempre inferiore a quella dell'originale. Quando utilizziamo tagli digitali, permettiamo al computer di memorizzare quali sequenze devono essere riprodotte e in quale ordine. Questo rende il processo molto più semplice, i tagli diventano molto più precisi e il tempo necessario per trovare le giuste angolazioni nei tagli si riduce notevolmente. Questa è la tecnica di campionamento nel suo essenziale, e il processo viene chiamato editing non lineare.

L'editing non lineare viene utilizzato anche per la produzione video, ma la quantità di memoria e potenza di calcolo richiesta per eseguirlo in modo fluido è notevole (alcuni gigabyte di memoria secondaria, alcune decine di megabyte di memoria primaria e ottimi processori video e software di alta qualità) ed è generalmente inaccessibile alle persone comuni. Indipendentemente dal fatto che il passaggio ai supporti digitali comporti o meno un degrado della qualità audio/video, i notevoli risparmi di tempo compenseranno ampiamente la leggera riduzione della qualità, inoltre la qualità può essere mantenuta durante le copie digitali.

Tuttavia, possiamo migliorare la qualità del materiale musicale, poiché conosciamo come sono strutturate le caratteristiche degli strumenti. Lasciando che gli armonici vengano armonizzati in modo sintetico e utilizzando questi per smussare eventuali artefatti di discretizzazione del segnale, riusciremo a ripristinare il segnale verso una riproduzione più continua.

Discretizzazione durante il campionamento di un segnale con una frequenza di campionamento 16 volte maggiore della frequenza fondamentale del segnale.

Quando si tratta di suoni naturali, non è possibile utilizzare questo metodo direttamente; al contrario, è necessaria una radicale ristrutturazione dell'algoritmo, e l'uso di una suddivisione informativa appropriata dovrebbe essere la soluzione al problema. Se, fin dalla fase di memorizzazione, dividiamo i dati sonori in una componente armonica e una disarmonica, abbiamo già fatto un passo avanti. La componente armonica viene trattata come musica, secondo quanto descritto sopra, mentre la componente disarmonica viene approssimata mediante spline cubiche (vedi appendice B. Nota: questo è solo un esempio). Per poter utilizzare facilmente questa tecnica, abbiamo bisogno di un convertitore AD/DA leggermente modificato (AD = Analogico-Digitale, DA = Digitale-Analogico).

L'aspetto ingegnoso è che possiamo memorizzare i dati in formato a virgola mobile, con m bit significativi nella mantissa e e bit nell'esponente, anziché in una forma intera discreta con m bit nella mantissa e senza esponente. I moderni processori di segnale migliori gestiscono queste operazioni con facilità, ma sono estremamente costosi e ovviamente non accessibili a ogni individuo. Ciò che caratterizza un processore di segnale digitale (DSP = Digital Signal Processor) è la sua straordinaria potenza di calcolo sui dati in virgola mobile. Nel mondo non commerciale, essi sono stati ampiamente utilizzati per radar e missili di vario tipo.

I primi ambiti in cui questi DSP sono stati sfruttati, rivolti al pubblico generale, sono stati ovviamente quelli musicali. Le difficoltà che i compositori hanno affrontato per decenni sono state quasi risolte, ma nella loro "tecnica interiore", alcuni compositori utilizzano questa tecnologia in modo errato. Il risultato è che alcuni creatori si abbandonano a effetti come delay, chorus, phasing, flanging, pitch shifting, armonizzazione, riverbero e molti altri ancora. Il fatto che utilizzino la tecnologia in modo errato non implica necessariamente un suono scadente o poco interessante. Le opere di questi creatori non hanno alcun riferimento alla realtà di strumenti musicali o sale d'ascolto esistenti, ma esercitano invece un forte impatto mentale sull'ascoltatore. Per non limitare questa capacità di creazione libera e colorare il materiale in alcun modo, è necessario utilizzare attrezzature di almeno la stessa qualità degli strumenti stessi dei creatori (se vogliamo spingerci fino al limite). Gli esempi più recenti di utilizzo dei DSP sono riconoscitori di testo e voce, distortori di immagini in tempo reale e riconoscitori di impronte digitali. È ora chiaro che la discretizzazione di un segnale continuo, sia esso audio o immagine, offre numerose ottime possibilità che dobbiamo sfruttare fino in fondo.

Aspetto computazionale dell'Audio Digitale

(Le spiegazioni delle formule in questo paragrafo sono trattate nell'Appendice B, per non interrompere il flusso.)

Un dettaglio importante nella discretizzazione di segnali continui è la velocità con cui campioniamo i dati in ingresso. Questa velocità di campionamento è chiamata frequenza di campionamento e la indicherò successivamente con fSf_S. Sia che si tratti di audio, immagini o informazioni provenienti da sensori, il segnale possiede una certa larghezza di banda che chiamo B. Questa larghezza di banda è considerata dall'intervallo da 0 Hz alla frequenza massima B Hz. Il teorema di Nyquist ci dice che è necessario un fSf_S almeno pari a 2B2 \cdot B per poter estrarre tutta l'informazione dal segnale. Quando consideriamo più sorgenti, il cui numero indico con S, B deve includere la massima frequenza presente nella sovrapposizione dei segnali provenienti da tutte le sorgenti. Inoltre, tutte le sorgenti devono avere la stessa larghezza di banda dati discreta, intendendo con ciò la risoluzione dei convertitori AD/DA in bit, che chiamo I. Durante la sovrapposizione (somma) di più canali dati, è necessario un IOUTI_{OUT} maggiore rispetto a IINI_{IN}, per evitare la perdita di informazioni a causa di eventuali overflow.

Dynamik6IDynamik \approx 6 \cdot I (dB) (0)

IOUT=IIN+Ceil(log2(S))I_{OUT}=I_{IN}+Ceil(\log_2(S)) (biti) (1)

Nel contesto di più sorgenti trasmittenti, abbiamo spesso diversi ricevitori (R) e anche se la larghezza di banda del ricevitore è maggiore, non dobbiamo sovraccaricare il sistema con dati inutili. Pertanto, non modifichiamo fSf_S. Consideriamo una possibile simulazione della propagazione delle onde sonore dalle loro sorgenti ai ricevitori. Le riflessioni precoci che chiamo XEX_E (Early refleXions, con unità di misura "pezzi") e il numero di approssimazioni della riverberazione che chiamo XRX_R (Reverberation refleXions, con unità di misura "pezzi"), sono anch'esse sorgenti comuni dal punto di vista computazionale. Ciò ci porta a una generalizzazione della (1):

IOUT=IIN+Ceil(log2(S+XE+XR))I_{OUT}=I_{IN}+Ceil(\log_2(S+X_E+X_R)) (biti) (2) Quanta potenza di calcolo è necessaria per sommare tutti questi canali in un segnale sovrapposto ai ricevitori? Utilizzerò l'unità "op", che implica un'addizione più una moltiplicazione. La seguente formula deve essere utilizzata per calcolare la potenza di calcolo necessaria con l'algoritmo NODIRAC:

D=fS(S+XE+XR)RD=f_S \cdot (S+X_E+X_R) \cdot R (op/s) (3)

Se vogliamo farlo in tempo reale, la formula 3 richiede una potenza di calcolo enorme anche per un caso così semplice come il seguente:

Problema 1:

Abbiamo due trasmettitori e due ricevitori. La frequenza più alta è di 20 kHz e abbiamo 23 superfici che generano riflessioni precedenti. Inoltre, approssimiamo la riverberazione con 100 istanti stocasticamente distribuiti esponenzialmente dopo TrT_r (pochi all'inizio, molti verso la fine), con approssimazioni lineari decrescenti della riverberazione. Quanta potenza di calcolo è necessaria per risolvere il problema con l'algoritmo NODIRAC?

Soluzione:

Abbiamo fSf_S = 40 kHz, S = 2, XEX_E = 23, XRX_R = 100 e R = 2. Sostituendo nella (3) si ottengono 10 milioni di op/s.

Se vogliamo effettuare uno studio "reale" di una stanza, possiamo campionare la stanza utilizzando un impulso di Dirac da ogni sorgente a ogni ricevitore. Chiamiamo queste frequenze di campionamento degli impulsi di Dirac fDIRACf_{DIRAC}, e la durata temporale di questi campionamenti, dalla prima onda fino a quando l'intensità del segnale decade di 60 dB, è T60T_{60}. Se lasciamo che questi segnali campionati della stanza siano la base della nostra simulazione (invece delle poche riflessioni e approssimazioni di riverberazione), che chiamiamo algoritmo NOMIX, la formula assumerà il seguente aspetto:

D=fSSfDIRACT60RD=f_S \cdot S \cdot f_{DIRAC} \cdot T_{60} \cdot R (op/s) (4)

Secondo la formula 4, avremo bisogno di un computer molto più potente, anche per casi estremamente semplici come il seguente:

Problema 2: Abbiamo due trasmettitori e due ricevitori, e la frequenza più alta è di 20 kHz. Utilizzando le risposte all'impulso, ottenute da un impulso di Dirac con durata temporale di 2 s e una frequenza di campionamento di 3125 Hz da tutte le sorgenti a tutti i ricevitori, vogliamo calcolare la potenza computazionale necessaria. Risolviamo il problema con un algoritmo NOMIX.

Soluzione:

Abbiamo fSf_S = 40 kHz, S = 2, fDIRACf_{DIRAC} = 3125 Hz, T60T_{60} = 2 s e R = 2.
L'inserimento in (4) fornisce 1 miliardo di operazioni al secondo.

Potrebbe essere una buona idea calcolare lo spazio di memoria richiesto per queste simulazioni "esatte". Per ogni sorgente, dobbiamo memorizzare MSM_S byte, dati dalla seguente formula:

MS=fST60IIN/8M_S=f_S \cdot T_{60} \cdot I_{IN}/8 (byte) (5)

Il requisito totale di memoria, considerando lo spazio di memorizzazione dell'impulso di Dirac, diventa:

MTOT=S(MS+RfDIRACT60IIN/8)M_{TOT}=S \cdot (M_S+R \cdot f_{DIRAC} \cdot T_{60} \cdot I_{IN}/8) (byte) (6)

Problema 3:

Quanta memoria libera è richiesta, se abbiamo una larghezza di dati informativi di 16 bit e i restanti dati sono come nel Problema 2?

Soluzione:

Abbiamo S = 2, fSf_S = 40 kHz, R = 2, fDIRACf_{DIRAC} = 3125 Hz, T60T_{60} = 2 s e
IINI_{IN} = 16. L'inserimento in (6) fornisce circa 360 kB.

Ci rendiamo conto dell'assurdità in questo contesto, poiché abbiamo bisogno di un computer con prestazioni computazionali molto elevate e una quantità relativamente piccola di memoria. Poiché la memoria è solitamente più economica delle prestazioni computazionali, è quindi una buona idea ridistribuire il carico di lavoro. Se permettiamo la sovrapposizione delle sorgenti già durante la discretizzazione, e lasciamo che queste siano disponibili in R aree di memoria con larghezza informativa di IOUTI_{OUT} bit, otteniamo le seguenti formule:

D=R(S+fDIRACT60)fSD=R \cdot (S+f_{DIRAC} \cdot T_{60}) \cdot f_S (op/s) (7)
IOUT=IIN+Ceil(log2(S))I_{OUT}=I_{IN}+Ceil(\log_2(S)) (bit) (8)
MTOT=RfST60IOUT/8M_{TOT}=R \cdot f_S \cdot T_{60} \cdot I_{OUT}/8 (byte) (9)

Questo algoritmo lo chiamo MIXTHEM, e osserviamo che utilizza lo stesso impulso risposta per ogni sorgente sonora, e pertanto non fornisce la stessa risposta di filtraggio dell'algoritmo NOMIX.

Problema 4: Abbiamo due trasmettitori e due ricevitori, con una frequenza massima di 20 kHz. Utilizzando le risposte all'impulso, ottenute da un impulso direzionale di durata 2 s e con una frequenza di campionamento di 3125 Hz da tutte le sorgenti a tutti i ricevitori, vogliamo calcolare la potenza computazionale e i requisiti di memoria necessari. Risolviamo il problema con l'algoritmo MIXTHEM.

Soluzione:

Abbiamo fSf_S=40 kHz, S=2, fDIRACf_{DIRAC}=3125 Hz, T60T_{60}=2 s, IINI_{IN}=16 e R=2. Sostituendo in (7) otteniamo 500 milioni di operazioni al secondo. Sostituendo in (8) otteniamo IOUTI_{OUT}=17, il che implica che abbiamo bisogno almeno di IOUT=32I_{OUT}=32 per rendere la gestione della memoria il più semplice possibile. Inoltre, la sostituzione in (9) mostra che servono 625 kB per risolvere questo problema.

Gli algoritmi NOMIX e MIXTHEM non producono la stessa risposta, poiché utilizzano diversi tipi di convoluzioni a delta. Potrebbe sembrare inutile confrontarli. Il punto è far sì che le sorgenti sonore vengano campionate in stereo in ambienti privi di riflessioni e memorizzate in un database. Da questo database, lasciamo poi che il computer recuperi i suoni corretti nei momenti appropriati, per poi filtrarli tramite l'algoritmo MIXTHEM (questo diventa "quasi" corretto). Anche con risposte all'impulso già precalcolate da tutte le sorgenti a tutti i ricevitori, è necessaria una potenza computazionale enorme per simulare questi tipi di propagazione d'onda.

Né l'algoritmo NOMIX né quello MIXTHEM sono completamente corretti rispetto alla natura, ma anche se lo fossero, sarebbe evidente che serve un'hardware sofisticata in grado di gestire questo processo "automaticamente". Non intendo i semplici DSP attualmente disponibili, bensì dispositivi più sofisticati che, in senso proprio, non si basano sull'addizione e la moltiplicazione digitali per i calcoli. Se ignoriamo il criterio che richiede che i campioni di impulsi di Dirac siano elaborati in tempo reale, possiamo utilizzare un algoritmo overlap-add [14]. Con questo algoritmo, è necessaria circa un millisecondo della velocità di calcolo dell'algoritmo NOMIX, ma i dati in ingresso subiranno un ritardo di 2T602 \cdot T_{60} [15]. L'implementazione hardware dell'algoritmo overlap-add è disponibile commercialmente sotto forma di un circuito FDP-1 prodotto da Lake[16]. Per piccole stanze, questa soluzione può essere utile, ma per sale più grandi possiamo scartarla, poiché il feedback in tempo reale non è possibile con un effetto di ritardo di alcuni secondi. Un'analogia con la realtà è il sistema di controllo dell'aeromobile JAS, che in più occasioni ha dimostrato questa carenza (in particolare quando il pilota non è consapevole dell'effetto di ritardo).

Inoltre, nuovi circuiti DSP di Texas Instruments (previsti per il rilascio commerciale nell'autunno 1994) sono diventati leader in termini di velocità di calcolo (>1>1 miliardi di operazioni in virgola mobile al secondo). Utilizzando una coppia di questi potenti DSP, possiamo risolvere il problema della convoluzione in tempo reale, ma il costo sarà probabilmente elevato per gli utenti comuni e dovremo aspettare la convoluzione in tempo reale per il grande pubblico. Si noti che non mi riferisco direttamente al circuito DSP, ma alla memoria estremamente veloce che deve essere collegata. Con una stima approssimativa, sono necessari circa 0,5 ns di memoria veloce (se i dati sono in forma seriale) per sfruttare ottimamente la potenza di questi DSP. Va aggiunto che i computer attuali μ\mu dispongono di circa 70 ns di memoria veloce, il che indica che dobbiamo suddividere i dati in circa 128 parti uguali e convolverle in parallelo. La soluzione parallela è puramente ipotetica, poiché non ho esaminato completamente le specifiche hardware.

Realtà Virtuale

Between ingenuity and the analytic ability there exists a difference far greater, indeed, than that between the fancy and the imagination, but of a character very strictly analogous. It will be found, in fact, that the ingenious are always fanciful, and the truly imaginative never otherwise than analytic.

Edgar Allan Poe

Questo capitolo tratta la realtà virtuale ed è rivolto alle persone che non si sentono a loro agio con la storia. Poiché questa branca dell'informatica è relativamente nuova (la NASA "ha iniziato" con questo alla metà degli anni '80 e la VPL Research ha reso la RV un fenomeno di massa nel 1989), nella prima parte cercherò di definire cosa sia la "realtà virtuale" e nelle successive i suoi ambiti di applicazione. Si presuppone che il lettore sia ben consapevole dei grandi requisiti computazionali richiesti dalla visualizzazione tridimensionale (nel suo caso estremo, video ray-tracing in tempo reale, uno per ogni occhio) e dall'auralizzazione (nel suo caso estremo, convoluzioni in tempo reale delle risposte all'impulso calcolate tramite audio-ray-tracing, una per ogni orecchio).

Nella definizione, utilizzo il termine "dettaglio" nel senso che la natura dettagliata deve essere completamente imitata in termini di riflessione, assorbimento, interferenza, diffrazione, rifrazione, diffusione, risonanza e dispersione. Non ho scritto sulle idee folli presenti nella cybercultura, ma su quelle più realistiche e pienamente realizzabili.

Definizione della realtà virtuale

Per poter definire la realtà virtuale (Inglese: Virtual Reality = VR), devo descrivere i principali caratteristici della realtà reale. Percepiamo la realtà attraverso la vista, l'udito, il tatto, l'olfatto e il gusto. Quando siamo nella natura e ammiriamo il dondolio degli alberi, i vortici dell'acqua o il movimento delle nuvole, possiamo trovare affascinante osservare questi fenomeni. La base del nostro interesse è che ciò che vediamo ha un'alta ricchezza di dettagli e/o è in costante movimento. Oltre a percepire larghezza, altezza e profondità, possiamo osservare il mondo da un punto arbitrario.

(1) Un buon ambiente VR deve contenere oggetti tridimensionali scalari e a movimento fluido, con alta ricchezza di dettagli. In questo modello dobbiamo avere la possibilità di osservare l'ambiente circostante da un punto arbitrario in una direzione arbitraria.

In conformità con i due capitoli precedenti, il requisito di percezione uditiva aggiunge quanto segue:

(2) Un buon ambiente VR deve riprodurre la propagazione delle onde sonore dagli oggetti generatori di suono fino alla riproduzione binaurale (auralizzazione) con alta ricchezza di dettagli.

La nostra vita sarebbe piuttosto poco interessante se non potessimo percepire la forma e il peso di un oggetto. Anche se può sembrare che la vista trasmetta la forma dell'oggetto, va sottolineato che intendo la levigatezza e la temperatura della superficie. Ciò ci porta alla seguente estensione:

(3) Un buon ambiente VR deve trasmettere la texture, la temperatura e il peso degli oggetti con buona precisione.

Il senso dell'olfatto umano non è così sviluppato come quello, ad esempio, del cane, ma è altrettanto capace se allenato. Ciò che il nostro senso dell'olfatto contribuisce principalmente è l'intensificazione del gusto durante il cibo. Qualcosa che molti non sanno è che gli esseri umani possono fiutare per rilevare pericolo, sicurezza e amore. Sono i feromoni [17, 18, 19] a rendere possibile tutto ciò, e anche se la maggior parte di noi "ha dimenticato" come riconoscere questi "odori", possiamo allenare il senso dell'olfatto. Questo ragionamento ci porta alla seguente estensione:

(4) Un buon ambiente VR deve essere in grado di trasmettere feromoni e odori naturali. La maggior parte dei bambini piccoli striscia in giro e prova a assaggiare tutto ciò che trovano. Lo fanno per pura curiosità e per formarsi un'idea del mondo circostante. Nel mondo degli adulti, purtroppo, non possiamo girovagare e assaggiare tutto ciò che vediamo. Tuttavia, gli oggetti presenti nell'ambiente VR non necessitano di alcun legame con la flora o la fauna terrestre.

(5) Un buon ambiente VR dovrebbe principalmente essere in grado di trasmettere sensazioni dolci, acide, salate e amare durante l'assunzione orale. Ogni altra forma di assunzione deve comportare la degradazione chimica della sostanza.

Infine, questo requisito estremamente importante per la sicurezza dell'utente.

(6) Tutti gli ambienti VR devono avere requisiti di sicurezza molto rigorosi per non peggiorare la salute dell'utente.

Applicazioni

L'umanità ha qualche utilizzo per gli ambienti VR, o si tratta solo di un "fashion" americano come molti altri? Qui discuto alcuni dei campi che possono trarre grande beneficio dagli ambienti VR.

Medicina

Quando gli studenti di medicina imparano il funzionamento del corpo umano, hanno al massimo un modello in plastica su scala ridotta di un essere umano. Nei modelli più avanzati, lo studente può rimuovere vari organi per un esame più dettagliato. Questo sembra essere un metodo molto efficace e semplice per apprendere l'anatomia. Il problema è che ogni studente necessita di un tale modello per imparare allo stesso ritmo, ma questi modelli sono troppo costosi. Un ulteriore complicazione è che occupano uno spazio eccessivo.

I vantaggi di implementare il corpo umano o animale in un ambiente VR sono che possiamo facilmente eseguire prove automatizzate. Diventa più semplice mostrare tecniche chirurgiche (tutti gli studenti vedono ciò che vede il chirurgo) e la diffusione delle malattie. Questi vantaggi si ottengono anche utilizzando telecamere strategicamente posizionate durante le operazioni. Il problema è che abbiamo bisogno di un paziente (vivo o deceduto) con la stessa patologia che sta venendo insegnata per ottenere una "mappatura" accurata.

La tomografia è un'evoluzione della radiografia tradizionale. Il paziente viene "scansionato" in diverse sezioni ad alta risoluzione in tutti gli assi. La radiografia tradizionale è relativamente sfocata, poiché la pellicola fotografica riceve raggi X attraverso strati molto più spessi (scarsa risoluzione in profondità). Il vantaggio dell'uso della tomografia è che si può facilmente ottenere un'immagine tridimensionale.

Quando gli operatori attuali di tomografia computerizzata osservano l'interno del paziente, lo fanno su un semplice monitor. Nella migliore delle ipotesi, il software del computer può essere progettato per visualizzare un'immagine tridimensionale omogenea della regione patologica del paziente. Se miglioriamo la visualizzazione con un ambiente VR di alta qualità, il medico riuscirà ancora più facilmente a identificare possibili problemi chirurgici, consentendo interventi più sicuri e veloci. Ambiente VR medico, non deve essere necessariamente così complesso quanto la definizione forte, ma la vista e il tatto devono essere presenti. Per i patologi, anche l'olfatto può essere un ausilio, ma in generale non è necessario. Riguardo alla necessità che l'otolaringoiatra senta come il proprio paziente, non ho conoscenze in merito. La formazione degli studenti di medicina in un ambiente VR dovrebbe migliorare le competenze mediche di questi ultimi e, si spera, portare a pazienti più sani.

Immagine video-scansionata e ritoccata dall'Enciclopedia Britannica (Propaedia), che mostra parti dell'anatomia interna di una donna.

Viaggi spaziali

Immagine video-scansionata e ritoccata dall'Enciclopedia Britannica, che raffigura una navetta spaziale di tipo Rockwell.

Prima o poi, l'umanità dovrà espandere la propria visione poiché il nostro pianeta non sarà in grado di soddisfare i nostri bisogni. Ciò può avvenire esplorando numerosi corpi celesti nello spazio. Un "piccolo" problema è che i corpi celesti più interessanti si trovano a distanze così immense che, con le attuali navette spaziali, ci vorrebbero secoli per raggiungerli. Per risolvere questo problema, potremmo aumentare la velocità e l'accelerazione della navetta spaziale. Tuttavia, poiché il corpo umano non tollera alte accelerazioni/decelerazioni (fatale oltre 10g100m/s210g \approx 100 m/s^2), la navetta spaziale non può raggiungere la velocità massima o fermarsi entro tempi ragionevoli.

Una soluzione a questo problema fisiologico è di non trasportare affatto esseri umani. In tal caso, il problema della velocità diventa molto meno critico, poiché l'attrezzatura tecnica è in grado di sopportare accelerazioni molto superiori a 10g. Missioni non tripulate sono già state effettuate con le sonde Mariner (1962-1973), Pioneer (1972-1973), Viking (1975) e Voyager degli Stati Uniti, nonché le sonde Venera (1967-1975) e Mars della allora Unione Sovietica [20]. Queste hanno scattato solo immagini da lontano, e possiamo osservare soltanto oggetti molto grandi sulla superficie. Va tuttavia aggiunto che le sonde Viking hanno raccolto campioni "terrestri" e scattato immagini estremamente dettagliate della superficie di Marte. Tutto ciò è buono, ma non abbastanza (nonostante l'uomo abbia camminato sulla Luna). L'essere umano ha sempre desiderato esplorare luoghi e rotte sconosciuti. Un esempio tipico è Cristoforo Colombo, che ha esplorato l'ignoto in modo "esemplare". Ciò che spingeva gli esploratori era il desiderio di vedere con i propri occhi ciò che era sconosciuto. Se invece lasciamo che le nostre future sonde spaziali scattino immagini altamente strategiche per creare un ambiente VR, potremo esplorare più facilmente una possibile terraformazione (Terra = Terra -> Svedese: trasformazione della terra). Per una prima esplorazione dei corpi celesti, non è necessaria l'intera definizione VR (sono sufficienti solo la vista e il gusto), ma una volta completata la mappatura, bisogna utilizzare la definizione completa. Nota che non possiamo avere comunicazione tra la sonda spaziale e l'ambiente VR, poiché gli effetti temporali sono troppo elevati per permettere un feedback in tempo reale dei nostri movimenti.

Intrattenimento

Immagine video scansata da "Animali preistorici" (pubblicato da Bonniers) che mostra il più feroce e impressionante rettile predatore: Tyrannosaurus rex.

Per sfuggire al peso quotidiano e alleggerire la mente, la maggior parte delle persone ha bisogno di qualche forma di intrattenimento. La maggior parte desidera perdersi in un mondo onirico che esiste sotto forma di libro o film. Già all'inizio degli anni '80, i cineasti tentarono di utilizzare ambienti generati da computer nei loro film, soprattutto in pellicole come "TRON" e "The Last Starfighter". Il problema di questi film era che l'ambiente digitale risultava molto artificiale e non ingannava bene gli occhi del pubblico cinematografico. Film recenti come "Terminator 2" e "Jurassic Park" hanno ottenuto molto migliori risultati su questo aspetto. Anche se i cineasti non hanno ancora raggiunto il limite definitivo del numero di fantasie "reali" che possono essere create con un film bidimensionale, posso affermare senza esitazione che è necessaria una rinascita nel settore. Per aumentare le illusioni, è necessaria una resa tridimensionale e un'audio di altissima qualità. In una fase successiva, dovrebbe essere implementato anche l'olfatto. Questo ambiente VR impone i requisiti più severi, poiché la gente comune è molto scettica nei confronti dei computer e del loro impatto sugli esseri umani. Pertanto, la qualità elevata è di fondamentale importanza affinché le persone comuni possano accettare le illusioni.

Uno svantaggio di avere illusioni troppo realistiche è che possono indurre le persone a credere in cose non corrette. Purtroppo, molte persone utilizzeranno ambienti VR insieme a qualche forma di droga per intensificare l'effetto illusorio. Questo, unito al fatto che l'utente sperimenta un movimento molto ridotto, può portare a gravi problemi sociali. Gli scienziati che lavorano sugli ambienti VR dovrebbero informare sul possibili problemi sociali per coloro che li utilizzeranno, ad esempio nel cinema e nella pubblicità, prima del loro rilascio al grande pubblico.

Militare

Tutte le cose positive possono essere utilizzate per scopi negativi, e gli ambienti VR non fanno eccezione a questo fatto. Poiché gli effetti temporali sulla Terra sono relativamente piccoli (massimo circa 70 ms), possiamo ottenere facilmente un feedback in tempo reale dei nostri movimenti. Ciò significa che possiamo controllare facilmente un robot meccanico in territorio nemico senza essere fisicamente presenti. Nelle forme più recenti di guerra, possiamo realizzare il campo di battaglia in un ambiente VR totale e lasciare che coloro che sono interessati al declino dell'umanità vi si dedichino. Queste persone potranno così sfogare le loro istinti attraverso missioni di massacro, per poi tornare alla vita "normale". La qualità ottimale che tale ambiente VR militare dovrebbe avere per massimizzare l'effetto preventivo può essere discusso, ma probabilmente richiederà eccellenti impressioni visive e uditive.

Simulatori

Sono stati disponibili sul mercato simulatori per automobili, aerei e barche da un po’ di tempo, e questi costituiscono ambienti VR preistorici. I simulatori aerei esistono ad esempio fin dal 1929 [21]. La ragione per cui li definisco preistorici è che l’utente siede in una replica funzionale del vero ponte di comando. Questo è di per sé vantaggioso, poiché offre una mappatura perfetta. Tuttavia, utilizziamo interruttori meccanici che occupano molto spazio e sono costosi se devono essere affidabili.

Passando a un controllo completamente digitale dei sistemi (il che è estremamente difficile), potremmo progettare l’interfaccia uomo-macchina molto più semplicemente (sia nell’ambiente VR che nella realtà), consentendo a un numero molto maggiore di persone di operare la macchina in questione. Speriamo che l’apprendimento di scenari pericolosi possa diventare più veloce e semplice. Potremmo ampliare l’uso dell’ambiente VR e implementarlo in coesistenza con le attuali cabine di comando, per eliminare problemi visivi come i “punti ciechi”.

Le palestre moderne dispongono di vari attrezzi per migliorare la salute. Tuttavia, questi sono noiosi da usare nel lungo termine, e un utente “pö om pö” (come me stesso) si rifiuta il più possibile di usarli. La soluzione è uscire nella natura e iniziare il proprio programma di salute lì. Nella società del futuro, la densità della popolazione sarà così elevata che non avremo abbastanza spazio per la ricreazione nel senso naturale del termine. Dovrà allora l’essere umano essere costretto a rimanere in una stanza e svolgere il proprio programma di salute fissando un’insipida parete? Permetti alla persone attive dal punto di vista sportivo di praticare attività fisica in un ambiente VR personalizzato in base alla forza fisica individuale dell’utente. In questo ambiente, tutti potranno correre alla stessa velocità, almeno visivamente nell’ambiente VR. Se l’utente trova piacevole ricevere una vittoria per aumentare il livello di interesse, l’ambiente VR può essere programmato in tal senso. Sono convinto che la maggior parte delle persone che non gradiscono lo sport lo facciano perché sono troppo orientate alla vittoria, e quando si rendono conto della propria scarsa condizione fisica durante una “gara” contro gli altri, la loro volontà si spezza e abbandonano l’attività sportiva. Personalmente, considero gli ambienti VR una salvezza per questa problematica. Questi ambienti VR richiedono visione e udito per ottenere simulazioni sufficientemente realistiche.

Progettazione Assistita da Computer

Architetti e progettisti meccanici traggono attualmente un grande vantaggio dalle visualizzazioni grafiche computerizzate. Possono vedere la propria progettazione prima che venga costruita e, se il software lo consente, verificare se la struttura è solida e funziona (ad esempio, IGRIP su macchine Silicon Graphics). Nella costruzione di sale da concerto, è possibile considerare anche l’aspetto acustico e realizzare un’auralizzazione con il giusto software e hardware. Questi strumenti semplificano notevolmente il processo, riducendo al minimo costosi interventi di modifica e errori progettuali. Per ottenere la migliore possibile conceptualizzazione, dovremmo puntare a una realtà più perfezionista mediante ambienti VR che offrano all’utente una creazione più fantasiosa e maggiormente autorealizzante.

L'ambiente di programmazione del futuro

Nella ricerca dell'usabilità ultima, gli ambienti VR potrebbero rappresentare un passo nella direzione giusta. Gli attuali ambienti di programmazione soffrono di notevoli svantaggi, che forse non consideriamo quando li utilizziamo per brevi periodi. L'esigenza che tutto ciò che è visivo sia uniforme finirà per dare all'utente un sapore di monotonia. Coloro che hanno programmato per più di 16 ore consecutive possono talvolta avvertire una certa noia davanti al computer, che non deve necessariamente dipendere da una cattiva alimentazione o da poche pause al bagno. In realtà, l'interfaccia del computer verso gli esseri umani è terribilmente noiosa, poiché il contenuto dello schermo è statico. Un metodo preventivo potrebbe essere quello di trascorrere tempo in un ambiente VR durante il lavoro di sviluppo, dove gli effetti visivi forniscono segnali incoraggianti al cervello. Il datore di lavoro non deve spendere denaro per mobili, fiori e ampie superfici di lavoro: l'ambiente VR (grandi schermi ad alta risoluzione a cristalli liquidi fissati alle pareti, collegati a un computer VR) può essere personalizzato secondo il gusto dell'utente.

Un'ulteriore evoluzione dell'interfaccia utente consiste nel far sì che l'attività cerebrale controlli l'aspetto dell'interfaccia per mantenere l'attenzione e l'umore dell'utente. I problemi attuali risolti dai computer richiedono grandi team di programmatori. I membri di questi team dovrebbero condividere gusti simili in termini di arredi e musica d'ambiente, se vogliono lavorare efficacemente insieme. Ho osservato personalmente questo fenomeno in vari luoghi di lavoro nel corso degli anni. I vantaggi di trascorrere tempo in un ambiente VR sono che i membri non devono trovarsi nello stesso luogo e possono scegliere arredi e musica secondo i propri gusti. Ciò comporterà un guadagno di efficienza, poiché tutti potranno avere ciò che desiderano e quindi si sentiranno molto meglio. Perché dovremmo aver bisogno di ambienti VR per risolvere questo problema? È possibile ottenere lo stesso risultato con la tecnologia attuale in un mondo dati bidimensionale, ma la mancanza di "contatto umano tridimensionale" diventerà un grande problema prima o poi. Non abbiamo bisogno della definizione completa di VR in questo contesto, ma la visione, l'udito e il senso del tatto devono essere implementati.

Studio musicale

Possiamo trarre notevoli vantaggi dall'implementazione dello studio musicale del futuro in un ambiente VR. Il primo compito dell'ingegnere del suono è posizionare vari strumenti musicali (in realtà oggetti generatori di suono) nello spazio virtuale auto-modellato. Dopo averli posizionati, determina quale voce l'oggetto deve suonare e con quale intensità e carattere. Per aumentare il livello di interesse e ridurre la prevedibilità del brano musicale, può quindi far muovere gli strumenti nello spazio o modificare il loro carattere nel tempo. Musicisti da tutto il mondo potranno suonare in una sala da concerto virtuale, pur rimanendo comodamente seduti a casa (l'idea è stata tentata dal musicista Thomas Dolby).

Questo ambiente VR sarà inoltre di grande aiuto per l'industria cinematografica, poiché renderà più semplice l'inserimento di effetti sonori nei film. Anche se i moderni film cinematografici utilizzano già Dolby Surround (non lo stesso Dolby di cui sopra), che ricorda questo ambiente VR, la maggior parte soffre comunque di gravi carenze audiovisive. Per ottenere la massima qualità sonora possibile, questo ambiente VR dovrà attribuire grande importanza al criterio uditivo nella sua definizione, ma anche la visione deve essere implementata per facilitare l'interazione.

Problema principale

TNE logo ©Denis Tumpic

Das also war des Pudels Kern!

Johann Wolfgang Von Goethe

In questo capitolo descrivo il mio lavoro di laurea definendo innanzitutto il problema. Segue quindi un'analisi del problema nelle sue principali componenti. Infine, tratto brevemente diverse metodologie di programmazione. Il presente lavoro di laurea riguarda principalmente l'audio-ray-tracing in ambienti VR e la sua implementazione. Questa idea non è del tutto nuova, poiché alcuni elementi fondamentali furono formulati su una base solida nel 1992 [22, 23, 24, 25].

La metodologia dell'audio-ray-tracing è conosciuta fin dal 1967 [26], e recentemente ha attirato l'interesse di numerosi ricercatori grazie alla maggiore disponibilità di computer più potenti. La mia percezione del materiale disponibile (molto scarso rispetto all'video-ray-tracing) in questo campo mi ha dato la sensazione che ci siano davvero poche persone che sviluppano effettivamente algoritmi per ambienti VR audio-mediali.

All'inizio si potrebbe avere l'atteggiamento ingenuo secondo cui i metodi di soluzione sono gli stessi per i ray-tracer video e audio. Tuttavia, i primi capitoli illustrano i problemi associati al calcolo della propagazione del suono e le possibili approssimazioni che possiamo effettuare. L'implementazione stessa è stata aiutata dai manuali principali del sistema Amiga, da vari libri su C e da uno strumento per la creazione di interfacce grafiche (vedi Libri, Software e Hardware).

Problema

Al momento, i tracciatori di raggi video per computer personali (in particolare per la famiglia di computer Amiga) sono molto comuni, ma i tracciatori di raggi audio non esistono in eguale varietà. Non sono disponibili soluzioni commerciali a prezzi ragionevoli. I programmi Odeon e Computer Aided Theater Technique (CATT), disponibili per computer IBM compatibili, sono entrambi estremamente costosi e lontani dall'essere user-friendly. Questo fatto, unito all'aumentato interesse odierno per gli ambienti VR (cfr. il capitolo precedente su Virtual Reality), indica un forte bisogno di un tracciatore audio che sia allo stesso tempo veloce e facile da usare.

Ciò che dovrebbe essere incluso in un programma di ray tracing è un semplice editor 3D grafico, la possibilità di definire il materiale e il tipo degli oggetti, nonché la capacità di far seguire agli oggetti schemi di movimento predefiniti. L'editor 3D grafico può essere implementato con elementi molto complessi, come ad esempio "beta-splines" con "hidden surface removal". Tuttavia, creare l'editor 3D perfetto non è stato il mio obiettivo principale, ma la sua utilità ha influenzato in grande misura l'aspetto del programma. Per un tracciatore audio, i materiali degli oggetti possono essere associati alle proprietà di assorbimento delle superfici e alla direttività. I diversi tipi di oggetti possibili possono essere mobili, sorgenti e ricevitori. Gli schemi di movimento devono includere sia la morphing (trasformazione) che la traslazione nelle tre dimensioni (si prega il lettore di ricordare la definizione forte di VR). Il programma deve essere in grado di gestire le suddette funzionalità con semplicità, affinché l'utente non venga ostacolato nella propria capacità creativa o privato di tempo libero prezioso. La visualizzazione presente in tutti i ray-tracer video deve avere un'analoga efficace anche in un audio-ray-tracer, e chiamiamo questa auralizzazione. Questo termine è diventato uno standard de facto presso la Chalmers University of Technology. Tenuto conto della potenza di calcolo estrema richiesta per l'auralizzazione (dimostrata nell'Aspetto Computazionale dell'audio digitale) in combinazione con l'hardware semplice tipico dei computer personali, questo obiettivo non è la priorità principale, ma rimane comunque in considerazione per future implementazioni hardware.

Una parte obbligatoria dell'auralizzazione è la capacità di campionare ambienti esistenti mediante impulsi di Dirac per l'uso e il confronto nei risposte all'impulso calcolate. Questa parte è troppo semplice da implementare, e la menziono solo in questo contesto come possibile estensione del mio programma. In realtà, è già implementata poiché posso sfruttare i numerosi programmi di campionamento disponibili e eseguire il programma di campionamento in parallelo con il programma audio-ray-trace.

Un'idea molto promettente e pienamente realizzabile è far comunicare due computer personali mentre gli utenti si trovano in un ambiente audio/video comune, come una sorta di precursore delle future ambienti VR di alta qualità. Questo aspetto è stato oggetto dei miei interessi, ma poiché la competenza principale di un ingegnere informatico non riguarda la costruzione hardware, ho escluso questa idea da questa presentazione. La soluzione richiede comunicazioni più veloci di quelle seriali standard. È possibile realizzarla tramite trasmissione parallela, ma ciò comporta un costo circa 8-32 volte superiore (in base alla larghezza), e pertanto questa soluzione non è una buona opzione. Anche la seguente idea è stata esclusa poiché il fornitore americano di hardware è fallito. Attraverso occhiali speciali (in realtà due display a cristalli liquidi con un solo pixel) che alternativamente lasciano passare ogni immagine successiva dal monitor del computer a ciascun occhio, possiamo creare immagini tridimensionali estremamente realiste per aumentare l'usabilità dell'editor 3D [27, 28]. In realtà, l'hardware è molto semplice da costruire autonomamente, ma ancora una volta il principale obiettivo di un informatico è lo sviluppo di algoritmi.

Inoltre, un programma di audio ray tracing può essere uno strumento molto utile per migliorare l'acustica di ambienti già esistenti. Ciò è possibile se vengono implementate le corrette approssimazioni nel programma per la simulazione della propagazione del suono, e se si ignorano i severi requisiti dell'ambiente VR audiovisuale il cui postulato principale è la retroazione in tempo reale.

La scelta del computer è fondamentale, e come informatico si deve richiedere un buon sistema operativo supportato da hardware di qualità. Questi criteri non devono far scomparire l'aspetto economico, ma piuttosto spingerlo al suo massimo. La capacità del computer deve essere sfruttata in modo tale che l'efficienza degli algoritmi venga dimostrata nel modo più semplice possibile con i mezzi minimi necessari. Durante lo sviluppo, è indispensabile almeno il "multitasking preemptive" affinché il programmatore possa lavorare in modo efficace. Una forma di "Infinite Stream Of Consciousness" si manifesta durante l'uso di questi sistemi. L’uso di grandi workstation per questo lavoro di laurea sarebbe stato più semplice, ma la loro prestazione computazionale nasconde algoritmi scadenti. Poiché sono un accanito oppositore di interfacce grafiche lente e sistemi operativi pseudostabili mal implementati, ho scelto Intuition con AmigaOS come base per la realizzazione di questo lavoro di laurea: il mio ambiente preferito. Il lavoro di laurea costituisce inoltre un naturale prolungamento della tradizione leader di Amiga nel campo della realtà virtuale. L’unica cosa che potrei considerare negativa di AmigaOS è la sua gestione della memoria, poiché non è stata progettata per l’hardware MMU (Memory Management Unit). La base di ciò è il processore grafico ausiliario di Amiga (Agnes), in grado di spostare dati nella memoria del programma. Questo, insieme ad altri processori ausiliari (Denise, Paula, Buster, Amber, Ramsey, Gary e molti altri), è a sua volta la principale causa dell’efficienza e della velocità della architettura Amiga.

Questa architettura Amiga (una vera e propria macchina ibrida) è stata disponibile commercialmente dal 1985 ed è, nonostante la sua età, ancora oggi un computer molto utile. Tuttavia, nel lungo termine perde in prestazioni rispetto alle macchine RISC (Reduced Instruction Set Computer) più potenti. Per questo motivo, non ho ottimizzato alcuni algoritmi in assembler puro. Gli algoritmi sviluppati prima del 1989 sono in assembler, ma non vengono utilizzati nell’implementazione perché algoritmi più veloci sono stati sviluppati (OBS! miei).

A parte la scelta del computer, il linguaggio di programmazione è una pietra angolare fondamentale. Linguaggi complessi tendono spesso a generare traduzioni peggiori nelle istruzioni di base della macchina (soprattutto nell’architettura CISC - Complex Instruction Set Computer), ed era per me molto chiaro che Pascal (in realtà non complesso, ma meno efficiente del BASIC compilato sulle macchine Amiga!!!), Modula-2, Simula, Cluster e Modula-3 non erano abbastanza efficienti. I linguaggi OOP (Object Oriented Programming) moderni C++ (Definizione 2.1) e Oberon non sono pienamente sviluppati per Amiga, mentre il C++ comune (Definizione 1.0) era troppo inefficace. Le opzioni rimanenti sono l'assembler, il DSPC (Denis Tumpic Structured Assembler Programming Code sviluppato tra il 1986 e il 1988, non utilizzato in questa implementazione poiché il RISC era in fase di sviluppo) e il linguaggio di programmazione C. Tra queste, ho scelto C perché è un linguaggio relativamente semplice e molto flessibile da utilizzare. Chiunque può programmare in C, poiché è costruito con mezzi semplici e tutto è permesso (se lo confrontiamo con i cosiddetti "veri" linguaggi di computer – escludendo il BASIC!). Questo mette alla prova la disciplina del programmatore, e posso affermare senza esitazione che scrivere codice C leggibile è un'arte. Dal punto di vista puramente tecnico, il mio obiettivo principale è stato quello di scrivere un programma C estremamente leggibile, con ampie spiegazioni testuali per le costruzioni complesse. Questo è di fondamentale importanza nei progetti di programmazione su larga scala, specialmente quando si tratta di un progetto individuale come questo.

Analisi e Implementazione del Problema

La parte di implementazione del mio lavoro di laurea è stata suddivisa nelle strutture fondamentali del problema. Queste sono: la progettazione dell'interfaccia grafica, gli algoritmi grafici 3D ad alta intensità computazionale, gli algoritmi di propagazione del suono, l'approssimazione della riverberazione, l'auralizzazione e infine la struttura del computer. Queste strutture influenzano maggiormente l'efficienza e la progettazione del programma.

Interazione Uomo-Macchina

The most we can hope for is that the oftener things are found together, the more probable it becomes that they will be found together another time, and that, if they have been found together often enough, the probability will amount almost to certainity.

Bertrand Russell

In questa sezione scrivo sui criteri necessari per un'interfaccia utente di alta qualità. Vengono inoltre trattati i problemi che si manifestano durante la creazione di interfacce grafiche. Inoltre, descrivo le fonti di ispirazione che ho utilizzato; queste non sono state spiegate in dettaglio, ma ho estratto solo elementi originali o fasi di sviluppo. Infine, descrivo la mia implementazione dell'interfaccia e tento di analizzare possibili problemi utilizzando i criteri definiti nella sezione sui principi fondamentali.

Principi Fondamentali

I programmi informatici moderni dipendono fortemente dall'interfaccia grafica (GUI - Graphical User Interface) per sopravvivere nella feroce concorrenza del software. Gli utenti che non accettano immediatamente un programma si stancano rapidamente e, con grande probabilità, lo abbandoneranno a favore di un altro con una GUI migliore. In termini semplici, la GUI è l'elemento più importante di un programma: chi riesce a creare l'interfaccia più intuitiva vince alla lunga.

Dal punto di vista della programmazione, lo sviluppo dell'interfaccia grafica richiede il maggior tempo di implementazione, e un gran numero di "mock-up" nascono e muoiono prima che il prodotto finale venga completato. In realtà, l'interfaccia grafica non è mai davvero completa, poiché possiamo migliorarla all'infinito.

Come si realizza una buona interfaccia grafica? Questa è una domanda semplice con una risposta estremamente complessa. Nella seguente descrizione non tengo conto delle differenze tra diverse culture, né considero le preferenze soggettive di ogni singolo utente, poiché purtroppo non possiamo soddisfare tutti gli utenti. Ciò che contraddistingue un'interfaccia utente ben progettata è una buona mappatura, un rapido feedback e una semplice adattabilità. Questi criteri non sono gli unici in vigore, ma sono senza dubbio quelli con maggiore impatto. Inoltre, l'interattività e la trasformabilità (ad esempio lo spostamento di controlli durante l'esecuzione del programma) nell'interfaccia utente possono facilitare preferenze soggettive semplici, portando a un utente più soddisfatto nel lungo termine. Questo è parzialmente implementato in MUI (Magical User Interface, sviluppata da Stefan Stunz e attualmente disponibile gratuitamente nell'ambito del pubblico dominio Amiga), che è un'estensione della libreria Intuition.

Una buona mappatura viene raggiunta quando azione e reazione sono collegate in modo semplice. L'esempio migliore è la mappatura del mouse alla freccia sullo schermo. Muoviamo il mouse in una direzione qualsiasi (al momento bidimensionale), e la freccia segue nella stessa direzione sullo schermo. Quando attiviamo pulsanti o altri controlli di parametri nell'interfaccia utente, la reazione deve essere visualizzata in una vicinanza locale. Se non è possibile rappresentare la visualizzazione in modo locale, devono essere utilizzati effetti di attenzione. Questa soluzione alternativa non è preferibile, ma sfortunatamente è necessaria in alcune situazioni. Il feedback rapido è probabilmente il criterio più difficile, poiché spesso richiede buone prestazioni hardware. In questi tempi, il problema hardware è di scarsa rilevanza, ma implementazioni errate dell'interfaccia utente possono rendere inutilizzabili anche i sistemi più spettacolari. Quando l'utente compie un'azione sull'interfaccia, la reazione deve essere attivata e visualizzata immediatamente, se possibile. Se l'attivazione immediata non è fattibile, deve essere comunicato all'utente, tramite una visualizzazione semplice e chiara, che il calcolo è in corso. Un elemento che aumenta l'usabilità è rappresentare graficamente il tempo rimanente per completare il calcolo. Ho scritto sul feedback in tempo reale nel capitolo precedente, e con questo termine intendo un feedback immediato con una mappatura locale, indipendentemente dalla complessità computazionale (polinomiale). Questo è molto difficile da realizzare, ma costituisce un obiettivo da perseguire.

L'adattamento semplice dipende molto dall'esperienza precedente dell'utente con le interfacce utente. Se le interfacce precedenti sono state progettate in modo uniforme e coerente, il tempo di apprendimento per la nuova applicazione sarà minimizzato se progettiamo l'interfaccia nello stesso stile. L'uniformità può essere facilmente ottenuta osservando altre applicazioni nello stesso ambito e "copiandone" l'aspetto. Questa soluzione può sembrare un po' povera, in quanto non implica alcun pensiero innovativo. L'innovazione — ovvero imparare dai nostri errori passati — è di fondamentale importanza in ogni tipo di progettazione. Pertanto, lo sviluppatore dell'interfaccia utente dovrebbe "copiare" solo le unità più fondamentali per mantenere l'uniformità. Le unità più specializzate devono essere implementate in modo logico e visivo simile alle unità di base. L'utente non deve essere sovraccaricato da numerosi trasformatori di funzioni del programma. Questi devono essere presenti nella quantità minima possibile, ma con la massima funzionalità possibile. La loro funzione deve essere visualizzata in modo semplice, tramite icona (simbolo grafico) o testo. Il problema nell'uso di icone è che l'utente carica la memoria cercando di ricordarne la funzione (se sono mal disegnate).

La dimensione delle icone è direttamente proporzionale alla capacità percettiva dell'utente. Questo costituisce un problema poiché lo schermo del computer non è illimitato. Possiamo o aumentare la risoluzione dello schermo per includere più grafica e icone più dettagliate, oppure sostituire le icone con parole semplici. Anche frasi possono essere utilizzate, ma spesso diventano troppo lunghe; e in caso di uso estensivo di questa soluzione, la velocità di manipolazione dell'utente diminuirà perché leggere frasi richiede molto più tempo che ricordare la funzione associata a un'immagine. Come si dice comunemente: "Un'immagine vale più di mille parole". Una moderna variante su questo tema potrebbe affermare: "Una buona visualizzazione dice più di milioni di libri".

Spesso è necessario suddividere l'interfaccia grafica in diversi blocchi più grandi e coerenti. Se questi vari blocchi hanno funzioni simili, i loro trasformatori di funzione del programma devono essere posizionati in modo tale che le funzioni logicamente equivalenti siano collocate nello stesso punto all'interno dei diversi blocchi. Questa coerenza è fondamentale nella progettazione dell'interfaccia ed è estremamente importante da perseguire durante la modellazione dell'interfaccia grafica. Quando un'applicazione non è coerente all'interno dei propri confini, l'utente finirà per abbandonarla. La coerenza è un fattore fondamentale nella velocità di manipolazione, e questo è molto importante per l'utente quotidiano che desidera lavorare in modo efficace. L'uniformità può anche essere chiamata coerenza globale (un criterio che ritengo troppo forte), e la coerenza può anche essere definita uniformità locale (un criterio che ritengo troppo debole). Se sia opportuno perseguire la coerenza globale può essere discusso, ma per evitare la monotonia dovrebbe esserci una certa libertà nell'interpretazione personale di metafore forse più appropriate rispetto a quelle disponibili nel sistema in questione.

La trasformabilità interattiva può essere implementata a diversi livelli, ma una eccessiva trasformabilità rende l'applicazione dipendente dall'utente. Questo è un problema acuto se la metafora fondamentale può essere modificata, e dovrebbe indicare che non dobbiamo implementare questa idea fino all'assurdo. Possiamo consentire all'utente di decidere autonomamente dove posizionare gli strumenti di modifica delle funzioni dell'applicazione e quale funzione debbano avere.

Se lasciamo che questa idea si diffonda ulteriormente, possiamo anche permettere al programma di essere controllato da un programma o hardware esterno. In realtà, il programma o l'hardware esterno utilizzano il programma esecutivo come una libreria di funzioni "normali". Questa idea può essere realizzata, ad esempio, con AREXX (nel mondo Unix viene chiamato REXX), e il programma esecutivo può diventare quanto si voglia avanzato. Se dobbiamo richiedere una trasformabilità interattiva completa nell'applicazione, dovremmo richiedere un'architettura del computer molto robusta; oggi, tuttavia, è frustrante utilizzare questi sistemi perché l'interazione diventa lenta nel tempo (la potenza del computer si esaurisce rapidamente). Anche se questo è un fatto, dobbiamo sforzarci di realizzare questa idea in un futuro prossimo grazie ad algoritmi efficaci e hardware di qualità. Ciò che forse dovrebbe essere il più importante e che l'utente nota per primo è la possibilità di annullare una decisione errata. Un principiante è condannato al fallimento nei primi incerti passi nell'applicazione se l'interfaccia grafica è incoerente. Gli errori di pensiero possono essere facilmente annullati da un utente esperto, e quest'ultimo non perde la fiducia nella macchina. Avere fiducia nell'operatività è particolarmente cruciale per applicazioni critiche, come quelle presenti in centrali nucleari o aerei.

La domanda principale è quanto profondo debba essere il "rimpianto". Nei sistemi più semplici, l'utente può annullare solo l'ultima trasformazione, ma nei sistemi migliori e più complessi si richiede una profondità di rimpianto "infinita". Ovviamente, aspetti legati alla memoria entrano in gioco in queste implementazioni. Possiamo risolvere questo problema permettendo all'utente di determinare la profondità del rimpianto durante l'esecuzione. Se lasciamo che la profondità del rimpianto sia virtualmente infinita, l'utente dovrebbe poter scorrere la pila di rimpianti in tutte le istanze correlate dell'interfaccia grafica durante l'esecuzione del programma.

Qualcosa che rende ulteriormente più difficile l'uso del software è se la sua interfaccia grafica è progettata in modo tale che il programma sia suddiviso in moduli. Questo può essere estremamente pericoloso e l'utente potrebbe sentirsi intrappolato. Ciò limita la creatività e rende l'uso scomodo e inefficace. Il problema nell'implementare un'interfaccia grafica senza moduli è che la complessità del programma diventa estremamente maggiore, e il lavoro di debug diventa a sua volta molto più complesso. Non è il codice stesso a crescere, ma il grado di indipendenza delle funzioni correlate, che deve essere totale. Per testare tutte le possibilità di modifica del flusso del programma, serve un lavoro esponenzialmente maggiore (n trasformazioni generano n! combinazioni di trasformazione diverse). Questo, insieme al fatto che possiamo facilmente dimostrare di non poter costruire un programma in grado di verificare la validità di un altro programma, dimostra parzialmente la mia affermazione secondo cui un'interfaccia grafica complessa non sarà mai completata. Per i principianti, e forse anche alcuni utenti esperti, potrebbe risultare poco chiaro a cosa servano tutti i trasformatori di funzionalità del programma. La maggior parte leggerà qualche forma di manuale d'istruzioni, ma dopo un uso prolungato questo diventerà logoro. La soluzione a questo problema consiste nel creare un manuale elettronico che l'utente possa consultare quando si verificano problemi durante l'esecuzione del programma. Questo è disponibile in Amiga-OS sotto forma di Amiga-Guide, esistente fin dal 1988 e basata su ipertesto. Questo manuale non è una parte fisica, bensì una componente logica del programma. Possiamo inoltre implementare messaggi di "aiuto istantaneo" posizionati in modo tale che l'utente possa trovarli facilmente direttamente nell'applicazione. Di solito posizioniamo questi messaggi di "aiuto istantaneo" nella finestra principale dell'applicazione e li aggiorniamo quando necessario (il feedback immediato è un requisito fondamentale in questa soluzione). L'interfaccia utente può talvolta costituire una barriera. Poiché fu un paese di lingua inglese a definire per primo un linguaggio informatico e a realizzare il primo hardware, la lingua fondamentale dei computer (sia hardware che software) divenne l'inglese. Gli utenti di quell'epoca erano per lo più scienziati, e conoscevano l'inglese. Oggi gli utenti non sono sempre scienziati e spesso non conoscono l'inglese. Questo crea un grande problema, poiché un utente che non comprende il testo visualizzato sullo schermo potrebbe, nel peggiore dei casi, abbandonare l'applicazione. Un ulteriore argomento contro l'uso di una lingua unica per tutte le interfacce sono le traduzioni scadenti (quelle degli utenti stessi) che spesso si verificano. Alcuni esempi tipici sono "save" (sejv, che in realtà dovrebbe essere "salva") e "load" (leåd, che in realtà dovrebbe essere "carica"). Queste espressioni si diffondono come un incendio, e il gruppo di utenti dell'applicazione finirà per sviluppare un "linguaggio secondario" rispetto alla lingua originale. Questi linguaggi secondari possono far sì che tale gruppo venga talvolta percepito come se provenisse dall'esterno dello spazio. Una soluzione a questo problema è progettare l'interfaccia grafica in modo tale che sia facile cambiare la lingua di base. Questo è stato risolto in Amiga-OS tramite Locale (implementato come libreria), dove specifichiamo la lingua e il paese che utilizziamo o in cui abitiamo. Successivamente, è compito dell'applicazione (se il programmatore ha implementato l'istanza locale) utilizzare questa impostazione.

Fonti di ispirazione

Poiché esistono così tanti raytracer video per Amiga, ho principalmente osservato le loro interfacce per trarre ispirazione. All'inizio del 1987 c'era Sculpt-3D, piuttosto avanzato, ma con un editor lento, nonostante mostrasse il mondo del modello in "wireframe". Il wireframe significa che il modello mostra solo gli spigoli degli oggetti, permettendo di vedere attraverso di essi. L'utente poteva determinare l'angolo di visione sul mondo del modello in ciascuna vista (tre viste mutuamente ortogonali). Funzioni utili come ingrandimento, prospettiva e altre erano disponibili. L'esigenza di creare sequenze animate dalle immagini calcolate richiedeva una ristrutturazione fondamentale del programma, ad esempio l'implementazione del motion blur (sfocatura di movimento). Il programma cambiò nome in Sculpt-4D durante questa fase. Tuttavia, l'editor rimaneva altrettanto lento, rendendo impossibile l'utilizzo di questo programma per progetti più complessi.

Questi programmi furono tra i primi a vedere la luce su Amiga e avevano interfacce utente relativamente buone. Un programma che non è un raytracer ma merita di essere menzionato è Videoscape. In questo programma, il mondo del modello era visualizzato con superfici reali, e l'utente poteva anche creare semplici animazioni. Anche in questo programma, l'uso risultava un po' faticoso per progetti più grandi. Va sottolineato che intendo "faticoso" in termini Amiga. Per chiarire: un editor 3D dipende fortemente dalla velocità con cui la grafica può essere visualizzata sullo schermo (in realtà tutta l'interfaccia grafica in generale) e dalla velocità con cui possiamo trasformare i vettori. La trasformazione stessa deve essere eseguita dalla CPU principale, a meno che la GPU non abbia routine dedicate. La GPU dell'Amiga (Agnes) non ha trasformazioni vettoriali integrate, ma l'algoritmo di Bresenham per le linee è implementato in hardware. Questo ha fornito un notevole vantaggio, anche se le prime Amiga avevano come CPU principale una semplice MC68000 (il fondamento della famiglia MC68K di Motorola). Questo concetto ha coinvolto anche i computer grafici più avanzati apparsi in vari contesti. Questi sistemi hanno implementato la texturizzazione in tempo reale e lo z-buffering nell'hardware, oltre a potenti processori RISC, tra cui quelli MIPS. Le macchine Silicon Graphics (l'azienda SGI fu fondata nel 1982) sono note in particolare per il loro utilizzo nell'industria cinematografica da parte di Industrial Light & Magic (vedi capitolo sulla Realtà Virtuale) e per la loro hardware-specifica.

Il primo programma professionale (sviluppato inizialmente con risorse molto limitate) fu Caligari, ed era estremamente intuitivo. In questo programma, l'utente poteva visualizzare il modello da diverse prospettive e scegliere tra una rappresentazione solida (estremamente lenta dal punto di vista delle prestazioni) o una visualizzazione wireframe (accettabile in termini di velocità). In Europa, però, questa applicazione non riuscì a imporsi poiché il mercato era troppo limitato e povero. L'interfaccia utente di Caligari era superiore a quella delle applicazioni contemporanee, poiché il suo utilizzo era più semplice e la risposta in tempo reale eccellente. Potevamo spostare oggetti 3D in tempo reale come se fossero icone comuni. Presto, i ray-tracer video di Amiga divennero "standard dell'industria", specialmente negli Stati Uniti e in Canada, ma il mercato richiedeva un programma migliore. Il software che, dopo un significativo miglioramento estetico dalla precedente implementazione in Intuition v1.0 a Intuition v2.0, si chiamava Imagine.

Ritengo che questa serie di programmi sia un cattivo sviluppo dei primi programmi Sculpt, anche se risultano più utilizzabili. La ragione per cui penso questo è che la loro interfaccia grafica è diventata eccessivamente ingombrante e confusa quando si tratta di definire materiali e schemi di movimento. Una persona senza grande pazienza abbandona rapidamente questa serie di programmi. Nonostante questi problemi, l'applicazione viene utilizzata ampiamente tra i professionisti della pubblicità televisiva in America. Il mio programma preferito in questi contesti è Real-3D (RealSoft dalla Finlandia). La versione originale era implementata nell'antica Intuition v1.0 e si basava sulla stessa metafora dei programmi Sculpt. La principale differenza consisteva nel fatto che le viste erano implementate in finestre non modificabili, e avevano angoli di visione specifici che non potevano essere modificati. Quello che si vedeva erano le tre viste del modello (dall'alto, di lato e ortogonale a queste) e un elenco degli oggetti del modello in una struttura ad albero gerarchico. Accanto all'elenco c'erano diverse icone per la definizione rapida degli oggetti nel modello. Queste icone erano molto ambigue, e l'utente spesso sceglieva oggetti di base errati. Da questo punto di vista, si potrebbe credere che il programma fosse difficile da usare, ma chi legge qui si inganna. Questo programma era estremamente semplice da utilizzare, e un utente principiante poteva ottenere risultati produttivi entro i primi cinque minuti.

Ciò su cui questa prima implementazione fallì fu la parte di animazione. Questa era lontana dall'essere ben mappata, e il risultato medio (i dati che contenevano la sequenza di animazione stessa e non la grafica già calcolata) presentava una ridondanza tremenda. Questi problemi scomparvero con l'introduzione di Real-3D V2.0, che si basava su Intuition v2.0 e portò un notevole miglioramento estetico. Tuttavia, ciò che purtroppo fu trascurato fu la semplicità, il che ha portato a un'attrazione limitata verso questo programma, rivolto solo a un gruppo molto specializzato di utenti. Questi diventano nel tempo esperti, ma definizionalmente questo non suona bene per quanto riguarda la progettazione di un'interfaccia grafica ottimale. Il programma è collegato ad Amiga-Guide e quindi, nonostante tutto, offre un aiuto relativamente ampio per gli utenti occasionali. "Questo non risolve i problemi, ma un po' di aiuto è meglio che nessun aiuto affatto, e il programma può comunque essere utilizzato, sebbene non in modo efficace!" Questa citazione proveniva da un silenzioso lamento di un utente occasionale. Qualcosa che non esiste negli altri programmi è un semplice linguaggio funzionale (di tipo Lisp), che facilita ad esempio la creazione di schemi di movimento. Con questo micro-linguaggio possiamo facilmente applicare le nostre leggi fisiche personali agli oggetti. Questo conferisce all'usabilità una direzione sia positiva che negativa. Positiva, perché diventa più facile realizzare processi realistici; negativa, poiché la metafora è la programmazione ad alto livello e le conoscenze meccaniche, il che potrebbe causare reazioni allergiche negli utenti avversi alla scienza. Speriamo che questo cambi radicalmente nelle future implementazioni.

Il programma di ray-tracing video più grande, costoso e talvolta migliore si chiama Lightwave. Questo programma è un notevole sviluppo di Caligari e possiede una propria interfaccia grafica completamente autonoma. Non utilizza la GUI standard di Amiga, cosa che personalmente ritengo una grande svantaggio. L'editor 3D in sé è veloce e molto pratico da utilizzare. Il problema presente in questa applicazione sono i modi che si attivano. L'utente non viene avvisato di un cambio di modalità, il che può risultare estremamente frustrante. Inoltre, le definizioni per oggetti, materiali e schemi di movimento sono estremamente complesse e fanno reagire anche utenti con anni di esperienza informatica. Forse gli utenti esperti sono molto tolleranti, ma ciò non riduce i problemi. Lightwave è stato utilizzato ad esempio nelle serie televisive Babylon-5 e seaQuest-DSV. Gli altri programmi di video ray-tracing (anche su altri computer personali) disponibili nello stesso intervallo di prezzo (tra 5.000 e 50.000 kr) non meritano nemmeno di essere menzionati qui, poiché soffrono di carenze molto più gravi. Per coloro che oggi desiderano essere impressionati, le macchine Silicon Graphics dovrebbero offrire questa esperienza attraverso i programmi IGRIP ed Elastic Reality. Tuttavia, queste applicazioni sono molto costose e non rivolte al pubblico generale.

La mia soluzione per la finestra

Ho scelto l'inglese come lingua base del programma. La traduzione in svedese e l'implementazione dell'utilizzo delle impostazioni locali sono semplici ma dispendiose in termini di tempo. La parte centrale del programma è l'editor 3D, e quindi la finestra "3D View & Edit" è la finestra principale. L'utente trascorrerà la maggior parte del tempo nell'editor 3D, e per questo motivo questa soluzione appare ragionevole. La maggior parte di questa finestra visualizza il disegno in tre dimensioni (al momento solo wireframe), mentre la restante parte della superficie grafica è sparsamente riempita da alcuni trasformatori importanti. In questa finestra ho implementato un aiuto "istantaneo", posizionato in basso, che mostra l'ultima funzione eseguita.

Il modello stesso deve poter essere ruotato nello spazio, e ho implementato questa rotazione come la "mano di Dio". Utilizzo questo termine perché il modello è realizzato come un oggetto composto da altri oggetti, e non come un mondo costruito da oggetti. In realtà queste due implementazioni sono equivalenti, ma i modi di ruotare il modello sono molto diversi. Immagina di ruotare l'aula lezione invece di camminarci attorno. Personalmente, ritengo che questa soluzione offra una migliore mappatura, poiché l'utente rimane davanti al computer durante la rotazione del modello. Sebbene questa forma non sia preferibile in un'ulteriore evoluzione verso un ambiente VR, il codice principale è identico nelle due implementazioni, e quindi il lavoro non è stato fatto invano. Ho posizionato i trasformatori che ruotano il modello vicino alla finestra di visualizzazione del modello, il che fornisce una mappatura più forte rispetto a un'implementazione in una finestra separata. Questa soluzione potrebbe sembrare leggermente scadente, poiché il puntatore del mouse non si trova dove si trova il modello (cioè, una cattiva mappatura). Tuttavia, lo schermo è bidimensionale, e l'implementazione di trasformatori funzionali invisibili per facilitare la rotazione nella dimensione mancante causerebbe mappature molto più errate. I trasformatori di rotazione sono del tipo "slider" e sono orientati nella direzione degli assi principali del mondo (asse X verso destra, asse Y verso l'alto).

La finestra principale di editing di 3D-Audio, in cui l'utente può spostare, ruotare e ridimensionare sia il modello che oggetti specifici.

Il problema con l'asse Z è che i trasformatori standard di Amiga (Intuition v2.0) non dispongono di slider circolari, e sono stato costretto a utilizzare uno slider lineare per quest'asse. Esistono due possibili posizioni per lo slider dell'asse Z: sotto l'asse Y o accanto all'asse X. Ho scelto di posizionarlo sotto l'asse Y, come mostrato sopra.

Il problema nell'utilizzare gli slider per la rotazione è rappresentato dai loro limiti estremi. Ai limiti, non è possibile ruotare ulteriormente nella direzione del limite, e ciò risulta frustrante. Ho risolto il problema posizionando piccoli pulsanti di ripristino, visualizzati come un "o" che rappresenta l'origine, a ciascun limite. Quando l'utente fa clic su uno di questi pulsanti di ripristino, il "knob" (pulsante scorrevole in svedese) dello slider viene posizionato al centro tra i due limiti. Potrebbe sembrare una buona idea far seguire il puntatore del mouse durante questi ripristini, ma farlo saltare potrebbe risultare confuso; pertanto, non ho implementato questa idea. Un ulteriore dettaglio è che il modello deve ruotare nella stessa direzione in cui si muove il knob dello slider. Poiché ho solo una vista visibile, sono necessarie alcune scorciatoie che forniscano le viste del modello particolarmente interessanti e molto utili durante la modellazione. Chiamo queste tastiere "Fast View", e trasformano la visualizzazione in vista dall'alto, di profilo, ortogonale a queste e prospettiva da uccello. Senza questi pulsanti, la modellazione sarebbe stata impossibile. La velocità di trasformazione della Fast View è critica nella modellazione, poiché si basa fortemente su questi pulsanti (vedi algoritmi grafici 3D). La ragione per cui ho solo una vista è che devo minimizzare il rendering grafico. Con più viste, dovremmo aggiornare ogni vista quando spostiamo un oggetto. Questo ragionamento mostra che il tempo di calcolo, per ottenere un buon feedback, diventa tante volte più lungo quanti sono i numeri delle viste. Questa eccessiva complessità non posso permettermela, inoltre più viste possono a volte essere molto confondenti.

Di solito siamo in grado di esaminare il modello a diverse dimensioni, e questo è possibile anche in questo software. Anche qui ho risolto il problema utilizzando slider. Ancora una volta, esistono due modalità equivalenti ma con sensazioni completamente diverse per mappare ingrandimento e riduzione. Possiamo far sì che un movimento verso l'alto rappresenti una riduzione (spingiamo l'oggetto lontano da noi) oppure un ingrandimento (avviciniamo la nostra testa all'oggetto). In linea con il ragionamento precedente, avrei dovuto implementare la prima forma, poiché l'utente rimane seduto alla scrivania. Tuttavia, non l'ho fatto perché questa mappatura mi sembrava sbagliata (leggasi: inconsistente). Anche se questa è un'incongruenza, essa è profondamente logica e l'utente non dovrebbe notarla immediatamente. La realizzazione del cursore di ingrandimento mi ha portato un ulteriore problema che si manifestava nelle aree di massimo ingrandimento. La prima soluzione era implementare il cursore con una funzione esponenziale. Questo ha comportato una mappatura estremamente scadente, costringendomi a scartare il concetto. Un’implementazione meno povera di mappatura consisteva nell’aggiungere un limite superiore (visualizzato con +), che alternavo tra regolazione grossolana e fine, e viceversa. Anche questa soluzione è in realtà scadente, ma l’uso di due cursori funzionalmente identici affiancati causava maggiore confusione; pertanto, ho implementato il pulsante aggiuntivo.

Per aumentare il realismo, possiamo visualizzare il modello in prospettiva. Due linee parallele che si allontanano da noi si incontrano nel punto d’infinito (in questo caso, al centro dell’area di visualizzazione del modello). Come nei trasformatori precedenti, ho utilizzato un cursore che aumenta la prospettiva man mano che viene spostato verso l’alto. La base di questa mappatura è, tra le altre cose, il fatto che i potenziometri a corsiera del mixer (l’equivalente analogico dei cursori) forniscono una minore attenuazione alle posizioni più elevate (maggiore intensità del segnale).

Nell’area di visualizzazione del modello, mostro anche il piano di riferimento del modello utilizzando una griglia 3D. Questa griglia può essere configurata tramite menu circolari in unità e suddivisioni che risultano più adatte al contesto. L’unità di misura ("measure") può essere in metri, piedi o disattivata. Quando è disattivata, la griglia 3D non viene visualizzata. La griglia può avere diverse dimensioni ("grid size"), consentendo di modellare il mondo in porzioni. Questa funzione viene spesso utilizzata quando si definiscono oggetti che devono essere inclusi in molti disegni. È generalmente una buona idea ridurre al minimo l’inserimento manuale di numeri, e in questo contesto sembra ragionevole. Per chiarire l’orientamento del modello, ho esagerato le dimensioni degli assi principali e ho aggiunto X', Y', Z' ai loro estremi positivi. Questo aggiungimento è primario perché gli assi principali del mondo sono fissi, e ciò evita una cattiva mappatura con i nomi dei trasformatori di rotazione. Gli oggetti nel modello vengono visualizzati tramite una spilla posizionata al centro di rotazione dell'oggetto. L'utente determina autonomamente la posizione di questo centro durante la definizione dell'oggetto. Quando l'utente deve spostare un oggetto specifico, lo seleziona posizionando il cursore del mouse sul capocchia della spilla e premendo il tasto del mouse. Il cursore scompare e l'intero oggetto diventa un cursore, eludendo i problemi di prospettiva (gli oggetti più vicini si muovono più velocemente di quelli lontani). Un ulteriore chiarimento visivo è che l'area del modello viene premuta contro lo schermo, indicando che l'oggetto è stato selezionato e il resto del modello rimane fermo (cioè "l'oggetto è stato sollevato dal modello"). Quando l'utente rilascia il tasto del mouse, l'oggetto viene posizionato nella posizione visualizzata.

Gli oggetti vengono spostati nel piano che lo schermo visualizza. Questo è il fondamento delle prime tre icone di vista fissa. Gli spostamenti piani sono preferibili, poiché gli spostamenti tridimensionali risultano strani e molto mal mappati. Almeno nelle implementazioni che ho realizzato, con l'ausilio di ombre di aiuto, è risultato così. Un aspetto che riduce la confusione tipica dei modelli wireframe è che ho deciso di disegnare le spilline per ultime nella visualizzazione. Ciò garantisce che tutte le spilline siano in primo piano e nessun oggetto oscuri le spilline di altri oggetti. In disegni complessi, queste spilline possono diventare molto ingarbugliate (sovrapposte tra loro), e l'utente non riesce a capire quale spillina appartenga a quale oggetto. Anche modelli semplici con due soli oggetti possono diventare ambigui, poiché le spilline degli oggetti possono essere proiettate sullo stesso piano. La soluzione a questo problema verrà ripresa più avanti, poiché fa parte dell'illustrazione di una finestra secondaria chiamata "Drawing-Pool". I nostri oggetti dobbiamo poterli traslare e ruotare in modo semplice. Una possibilità sarebbe quella di rendere la traslazione, la rotazione e la scalatura tre diverse modalità nel programma o di avere un pulsante per ciascuna funzione. Le modalità sono completamente escluse, e tre pulsanti per oggetto diventerebbero troppo ingombranti. Se potessimo risolvere il problema con un solo pulsante, sarebbe una soluzione possibile. Tuttavia, gli errori di mappatura che si verificano (ci manca una dimensione) sono così gravi che mi sono visto costretto a scartare questa soluzione (alla mia grande disperazione).

Caligari e Lightwave hanno implementato questo con modalità più pulsanti nascosti, ma non sono riuscito a utilizzarli in modo soddisfacente. Per questo motivo ho implementato trasformatori di dimensione e rotazione di tipo slider per questo scopo. Questi sono disponibili solo quando l'utente ha selezionato un oggetto. Quando un trasformatore non è disponibile, viene visualizzato come sbiadito. L'utente può modificare le dimensioni lungo gli assi principali dell'oggetto, e la rotazione di un oggetto specifico viene mappata allo stesso modo dell'intero modello. La differenza principale è che tutti i trasformatori di rotazione sono orientati nella stessa direzione. Questo indica una mappatura scadente, ma il design è stato compromesso dall'asimmetria e ho optato per questa soluzione. Gli strumenti di trasformazione delle dimensioni sono anch'essi orientati nella stessa direzione, poiché l'orientamento degli oggetti nel modello non deve necessariamente corrispondere alla posizione fisica del mondo non primario, in questo caso dello schermo. Per chiarire l'orientamento dell'oggetto nel modello, ho deciso di visualizzare un "orientatore" che indica le direzioni degli assi principali dell'oggetto (X", Y", Z"). Durante le modifiche di dimensione, l'utente deve poter essere sicuro di ingrandire nella direzione corretta. Anche se questi strumenti non sono posizionati in prossimità diretta della trasformazione, possono essere utilizzati in modo relativamente efficace. Quando l'utente seleziona e sposta un oggetto, la posizione dell'oggetto nel modello (nell'unità di misura predefinita) viene visualizzata nella barra di aiuto "instant". Durante le modifiche di dimensione, le dimensioni dell'oggetto (Larghezza, Altezza e Profondità nell'unità di misura predefinita) vengono visualizzate nello stesso punto. Se l'utente ha disattivato la griglia 3D, gli aghi degli oggetti non vengono visualizzati e il modello assume una rappresentazione più chiara. Poiché gli aghi degli oggetti non sono visualizzati, l'utente non può selezionare accidentalmente un oggetto. Questo è un intervento di sicurezza deliberato.

L'utente non deve selezionare un oggetto specifico (posizionando il cursore del mouse nell'area dell'ago), ma può afferrare l'intero modello (in qualsiasi altra area della visualizzazione del modello) e spostarlo nel piano di proiezione. Questa funzionalità può facilmente causare difficoltà quando vengono eseguite rotazioni ripetute seguite da spostamenti. Il nostro cervello rimane fermo e tutto il resto si muove attorno a noi, il che ci permette di ruotare facilmente il modello fuori dalla finestra di visualizzazione e perderlo completamente. Per questo motivo, reimposto il centro di rotazione del modello sull'origine durante la rotazione del modello, per evitare disorientamento. Uno spostamento del modello seguito dalla selezione di un oggetto non comporta il ripristino del centro di rotazione. Ciò rende più facile posizionare, ruotare e modificare le dimensioni degli oggetti periferici (soprattutto se si ha una prospettiva molto accentuata). La maggior parte dei nomi dei trasformatori sono abbreviati in qualche modo, ma i nomi dei trasformatori di misura e griglia per la rete 3D sono completi ("Measure" per la misura e "Grid Size" per la dimensione della griglia). Il problema delle abbreviazioni non è nuovo, e quando sono particolarmente pessime, la comprensione diventa inesistente. Chiamo il trasformatore di ingrandimento del modello Mg (Magnification, solitamente abbreviato come Mag.) e il trasformatore prospettico Pr (Perspective, solitamente abbreviato come Pers.). All'inizio possono sembrare criptici, ma le abbreviazioni più lunghe creavano gravi problemi estetici nell'interfaccia, poiché non ho uno spazio illimitato su cui lavorare. I trasformatori di rotazione li chiamo X-, Y- e Z-Axis, e questi non dovrebbero causare problemi di comprensione.

I trasformatori di dimensione oggetto (object sizers) sono effettivamente molto criptici (SX = Dimensione lungo l'asse X, SY = Dimensione lungo l'asse Y, SZ = Dimensione lungo l'asse Z), così come i trasformatori di rotazione oggetto (object turners, AX = Angolo di rotazione attorno all'asse X, AY = Angolo di rotazione attorno all'asse Y, AZ = Angolo di rotazione attorno all'asse Z). Queste abbreviazioni possono sembrare un po' troppo compatte, ma un testo eccessivo ostacola l'uso efficace. L'utente tende infatti a leggere il testo ogni volta che utilizza il trasformatore, anche se conosce già la sua funzione. Questo tipo di abbreviazione suggerisce una certa inconsistenza, poiché nei primi casi ho usato le prime due consonanti, mentre nei secondi ho scelto arbitrariamente le lettere iniziali dalla frase. Tuttavia, dopo una riflessione più attenta, queste abbreviazioni risultano appropriate, poiché contengono informazioni sufficienti.

I trasformatori di "Fast View" sono relativamente intuitivi in questo senso, poiché i loro nomi indicano chiaramente quale vista verrà visualizzata (X-Y View, Z-X View, Z-Y View e Bird View). Questi trasformatori sarebbero stati in realtà supportati da icone per chiarire l'aspetto della vista, ma creare icone inequivocabili in questo caso è difficile. Una parte fondamentale dell'editing dei modelli è come suddividiamo le varie proprietà degli oggetti e le riuniamo in modo semplice. Possiamo creare un modello basato su computer utilizzando diagrammi E-R e costruire l'interfaccia a partire da esso. In questo caso, non era necessario ricorrere a diagrammi o metodi di normalizzazione, poiché gli oggetti sono composti da elementi molto primitivi. La mia soluzione si basa su questi elementi: forma, materiale e schema di movimento.

Finestra di coordinazione del modello di 3D-Audio che l'utente manipola durante la definizione di oggetti, materiali e schemi di movimento.

Queste primitive convergono in una finestra di coordinazione dei modelli che chiamo "Drawing-Pool" (DP). Tutte le finestre di coordinazione nel mio programma hanno "pool" come suffisso. Il nome "pool" (pozzanghera) deriva dal "caos" che spesso si genera durante i tentativi di coordinamento (in realtà, il comportamento degli animali attorno alle pozze d'acqua nelle savane).

La parte principale della finestra DP è l'elenco in cui sono elencati gli oggetti. In questo elenco, l'utente può selezionare un oggetto specifico; l'aggiornamento avviene sia nella DP (chiarimento del nome, tipo, materiale e schema di movimento) che nella "3D View & Edit" ( evidenziazione dell'oggetto nel modello wireframe).

In precedenza ho scritto riguardo alla complessità della modellazione wireframe, e ho risolto il problema di selezione nel modo seguente. Innanzitutto, l'utente seleziona un oggetto nell'elenco degli oggetti della finestra DP. Quindi preme uno dei tasti Shift (in realtà una cattiva mappatura, poiché non visualizzo come l'utente dovrebbe agire in questi casi), il che indica che sta tenendo l'oggetto con entrambe le mani (ad esempio, la mano sinistra sul tasto Shift e la destra sull'interfaccia di controllo, o viceversa), potendo così posizionare, spostare, ruotare o modificare le dimensioni dell'oggetto specifico selezionato. Questa funzione viene interrotta immediatamente quando l'utente rilascia il tasto Shift, ma se l'utente mantiene premuto il pulsante dell'interfaccia di controllo, tiene fermo l'oggetto per lo spostamento. Accanto all'elenco degli oggetti, sono presenti pulsanti che facilitano l'organizzazione degli oggetti del modello. In linea con le finestre precedenti, la maggiore area visiva si trova in alto a sinistra, mentre gli strumenti di modifica sono posizionati a destra. Gli strumenti che presentano tre punti dopo il nome indicano che un'ulteriore domanda seguirà all'azione.

La funzione del pulsante di modifica più in alto ("New...") è quella di creare un nuovo oggetto nel modello, chiedendo tramite una finestra di dialogo quale tipo di oggetto deve essere aggiunto. La metafora è quella di un viaggio in un magazzino di mobili per acquistare pezzi d'arredo. Quando l'utente seleziona il "mobile" specifico, esso viene sempre posizionato nell'origine del modello, seguito dall'aggiornamento visivo della finestra principale. I nuovi oggetti non sono associati a materiali o schemi di movimento specifici. Ciò viene visualizzato con "NO TYPE AT ALL" (tipo di mobile), "NO MATERIAL ASSIGNED" (materiale del mobile) e "NO FLIGHT ASSIGNED" (schema di movimento del mobile) nelle rispettive aree informative.

L'utente può quindi scegliere il materiale di cui è composto l'oggetto tramite il pulsante "Select..." allineato all'area di visualizzazione dei materiali. Questo pulsante attiva una finestra di dialogo in cui l'utente è invitato a selezionare un materiale. La specifica dello schema di movimento funziona allo stesso modo, ma qui l'utente è invitato a scegliere un "percorso di volo". Una volta selezionati questi elementi, l'utente può assegnare un nome all'oggetto appena creato nel modello, utilizzando il campo "Name". La modifica del nome genera un aggiornamento dell'elenco dei nomi degli oggetti. Se il modello deve contenere diversi oggetti con la stessa morfologia e materiale, l'utente può copiare gli oggetti già esistenti utilizzando il pulsante "Copia". Gli oggetti superflui o altrimenti ritenuti non necessari nel modello possono essere eliminati con il pulsante "Elimina". Durante l'eliminazione, l'oggetto viene inserito in cima allo stack "Annulla" della finestra DP e può essere ripristinato con il pulsante "Annulla" più grande. Se l'utente desidera eliminare l'intero modello, può attivare il pulsante "Cancella", e tutti gli oggetti verranno aggiunti allo stack "Annulla". Questa funzione è stata implementata unicamente come misura di coerenza, poiché è già presente negli altri pool (con un utilizzo molto più elevato).

Quando l'utente, dopo aver riorganizzato il modello per un po', desidera tornare alla finestra principale per la posizionamento degli oggetti, lo fa premendo il pulsante "Modifica...". Questo comporta che la finestra principale venga portata in primo piano rispetto a tutte le altre e attivata con l'oggetto selezionato in modalità " evidenziato". In realtà, la mappatura dei colori non è raccomandata e dovrebbe essere evitata nella massima misura possibile. La ragione di ciò è che anche le persone con disabilità visive cromatica devono poter utilizzare il programma. Tuttavia, l'elenco dei nomi nella finestra DP è la principale mappatura attraverso la quale l'utente deve identificare quale oggetto è selezionato. La necessità di questa soluzione deriva dalla scarsa chiarezza della visualizzazione wireframe.

L'utente può definire oggetti personalizzati attivando il pulsante "Disegno>Oggetto...". Questa funzione trasforma l'intero modello in un unico oggetto composto esclusivamente dalla struttura morfologica. La metafora in questo contesto è che il creatore invia il suo nuovo mobile alla fabbrica di mobili per la clonazione. I pulsanti di attivazione sono tutti di tipo testo, poiché le loro funzioni sono comuni e molto radicate. Di conseguenza, non ho utilizzato icone per questi pulsanti, nonostante i risparmi di spazio siano stati significativi e le icone potrebbero essere state posizionate nella finestra principale. Inoltre, con questa progettazione dell'interfaccia utente, caratterizzata da pulsanti grandi e "amici dei bambini" con un certo spazio circostante, si evitano anche certe complessità. Le difficoltà legate alla posizione e alla formazione dei pulsanti per minimizzare gli errori dell'utente possono essere ridotte posizionando funzioni strettamente correlate più vicine tra loro, e quelle meno correlate a distanze significative. Un pulsante che non segue questi criteri è il pulsante "Annulla", che dovrebbe essere posizionato più vicino possibile alla funzione più critica e avere almeno il doppio delle dimensioni degli altri pulsanti.

Forse il pulsante di definizione dell'oggetto è poco intuitivo, poiché presuppone la conoscenza da parte dell'utente dell'operatore "->" nel contesto del linguaggio. Questo operatore linguistico indica la trasformazione dell'unità X nell'unità Y (X->Y) in questo caso. Logicamente, questa definizione è corretta, ma la percezione intuitiva da parte dell'utente generico potrebbe essere discutibile in alcuni casi. Tuttavia, frasi più lunghe sono eccessivamente complesse e, nel mio parere, disturbano l'aspetto altrimenti pulito (specialmente in questo caso).

Finestra specifiche di 3D-Audio per oggetti primitivi, materiali e animazioni. Al momento della conferma, l'utente verrà automaticamente reindirizzato alla finestra di coordinazione del modello.

I tre posizioni di prelievo per oggetti ("Object Pool"), materiali ("Material Pool", MP) e schemi di movimento ("Flight Pool") si basano su un modello di domanda personalizzato. Questo modello è stato creato manualmente e non fa parte della "Amiga-GUI requester library". Nello stesso spirito di prima, ho una lista di nomi a sinistra, i pulsanti di modifica a destra e i trasformatori di nome in basso. Le loro funzioni sono identiche a quelle presenti nella finestra DP. L'utente deve selezionare i criteri appropriati per l'oggetto da queste posizioni di prelievo e confermare premendo il pulsante "Ok!" oppure, in caso di errore nell'uso, il pulsante "Cancel". Questi pulsanti di conferma sono posizionati secondo il vero layout delle richieste Amiga. La definizione di nuovi elementi e la modifica di quelli esistenti sono attualmente possibili solo nella finestra MP.

Durante la definizione e la modifica dei materiali, si apre una finestra di richiesta ("Characteristics") in cui l'utente definisce varie proprietà del materiale. Le proprietà, posizionate in alto, sono il nome, il tipo (mobile, trasmettitore, ricevitore) e il colore (da utilizzare in un'implementazione futura con modellazione solidframe). Sotto questi trasformatori si trova un grafico che mostra la caratteristica in frequenza del materiale. Il grafico visualizza la curva di assorbimento se si tratta di un mobile, e il profilo in frequenza per gli altri tipi (trasmettitore e ricevitore).

Qui applico l'idea che tutti gli oggetti possono in realtà essere considerati filtri. In questo grafico, l'utente può disegnare liberamente la caratteristica in frequenza; al primo salvataggio, il grafico viene "incollato" sullo schermo per chiarire che una modifica è stata effettuata. Poiché i coefficienti di assorbimento non vengono misurati in tutte le bande di frequenza, le aree non utilizzate nei calcoli vengono ombreggiate.

Finestra di definizione dei materiali di 3D-Audio a cui l'utente accede se ha cliccato su "Nuovo..." o "Modifica..." nella posizione dei materiali ("Material Pool").

Sotto questo grafico sono posizionate le trasformatori direzionali. Questi sono collocati sotto ciascuna ottava di frequenza per una mappatura ottimale. Qui l'utente può determinare le direzioni di riflessione, trasmissione o ricezione a diverse frequenze (Leggi la natura del suono e il trattamento audio per comprendere la terminologia). Anche questo modulo di interrogazione dispone di pulsanti di conferma in basso. A differenza del mio precedente ragionamento sulla posizione del pulsante "annulla", ho collocato questo tra i pulsanti di conferma.

Era esteticamente errato posizionarlo accanto al grafico delle frequenze (lato destro per mantenere la coerenza). Tuttavia, rimane comunque allineato alla presenza presso i trasformatori più critici (anche se non è esattamente adiacente). La progettazione della finestra di definizione dei materiali presenta alcune somiglianze con i moduli di interrogazione di tipo più avanzato. Questa metafora, se ben progettata, può diventare un'interfaccia molto efficace, poiché i moduli sono ampiamente consolidati nella civiltà occidentale.

Il percorso del raggio calcolato da 3D-Audio è visualizzato in questa finestra, e l'utente può scegliere l'umidità relativa dell'aria e quale delle due antenne del modello (ricevitori) deve servire da base per l'impulso inferiore.

Quando viene calcolata la traiettoria dei raggi, si apre una finestra di visualizzazione dati ("Computed Data", CD). Questa finestra è ancora in fase beta, poiché l'implementazione effettiva sarà integrata nel modulo di auralizzazione. In alto a sinistra mostro i parametri su cui è impostato il tracciamento dei raggi. Questi sono descritti in inglese conciso e minimale, poiché lo spazio grafico deve essere dedicato a elementi più importanti. Una grafica estremamente importante è la distribuzione della riverberazione, che mostra i tempi di riverberazione in diversi bandi di frequenza. Questi tempi sono calcolati mediante la formula di Sabine. Inoltre, l'utente può selezionare un'umidità dell'aria specifica da un menu a ciclo ("R. Humidity"). Mentre il computer calcola il percorso del raggio, in caso di calcoli riusciti visualizzerà questi percorsi nell'echogramma in basso nella finestra (l'ampiezza dipende dal percorso del raggio). Una barra che mostra quanti calcoli rimangono da completare viene visualizzata in questo blocco dell'echogramma. Anche se questa visualizzazione è utile, sottolineo tutti i calcoli più lunghi cambiando l'aspetto del puntatore. La freccia viene trasformata in un orologio se l'utente ha impostato l'opzione standard in "Pointer Preferences" (impostazioni del puntatore di Amiga). Al termine della tracciatura del raggio, l'utente può scegliere quale ricevitore visualizzare nell'echogramma tramite il menu a ciclo "Receiver".

Finestra delle preferenze di 3D-Audio in cui l'utente può specificare dove posizionare le varie unità dati nel proprio sistema informatico.

Per semplificare e rendere più piacevole l'esperienza dell'utente, ho implementato una finestra per le impostazioni di base. Qui l'utente può determinare dove devono trovarsi le sue aree di archiviazione per modelli, arredi, materiali, schemi di movimento e percorsi calcolati dei raggi.

L'utente può digitare i nomi nei campi di input oppure premere "Set...", il che attiva una finestra di selezione della cartella. Anche i colori base dell'applicazione possono essere configurati, se desiderato. I controlli per i colori sono di tipo standard Amiga-GUI, il che significa che i colori sono suddivisi in tre componenti (R = Rosso, G = Verde, B = Blu). Queste componenti sono ben integrate in Intuition e vengono utilizzate, tra l'altro, in "Palette Preferences" (impostazioni della tavolozza di Amiga). L'utente seleziona innanzitutto il colore, quindi sposta le manopole dei cursori alle posizioni corrette. I colori cambiano simultaneamente, offrendo una mappatura relativamente accurata. In I Intuition V3.0 esiste una ruota dei colori per una migliore mappatura, ma il problema di reperire i dati necessari per l'uso di questa funzionalità mi ha costretto a implementare la versione meno ottimale. In fondo si trovano nuovamente i pulsanti di conferma, che in questo caso sono leggermente più complessi rispetto al passato. Se l'utente commette un errore, preme come di consueto il pulsante "Annulla modifiche"; se invece si rende conto di non dover effettuare alcuna trasformazione, preme "Annulla". All'avvio del programma, le impostazioni di questa finestra vengono caricate e utilizzate. Pertanto, l'utente può salvare le impostazioni ("Salva modifiche") per un uso futuro, fino a quando non verrà effettuata una nuova trasformazione seguita da "Salva modifiche", oppure utilizzarle senza salvare ("Usa").

Durante sessioni di modellazione più lunghe, l'utente potrebbe dimenticare quale "negozio di mobili", "fornitore di materie prime" o "compagnia aerea" ha visitato. Per questo motivo ho implementato una finestra informativa ("Finestra Informazioni"), che mostra questi elementi insieme al nome del modello. Vengono inoltre visualizzate la disponibilità delle due memorie (RAM fissa e RAM chip) e il nome del produttore del programma. I tre diversi tipi di oggetti che possono essere presenti in un modello vengono stampati per informare l'utente sulla complessità del modello. Questi numeri sono direttamente proporzionali al tempo di calcolo del percorso dei raggi (numeri più elevati comportano tempi di calcolo più lunghi).

La finestra di pronto soccorso di 3D-Audio, in cui l'utente può vedere quali primitive sono state caricate e quanto è complessa il modello. La disponibilità dei due diversi tipi di memoria viene visualizzata in byte.

Oltre a tutte queste finestre, esistono numerosi finestre informative, di conferma e di domanda. Le ho implementate per impedire all'utente di commettere errori gravi, come ad esempio perdere il modello all'uscita dal programma. Nella Figura 4.8 mostro un estratto delle finestre aggiuntive disponibili nel programma, che l'utente può incontrare durante un'utilizzo "incosciente". Le finestre di richiesta si manifestano in tutte le forme di attività della memoria secondaria. Queste sono le "finestre di richiesta file" proprie di Intuition, per garantire che il programma sia coerente con tutti gli altri programmi Amiga. Un tipo di finestra di richiesta è quella che richiede solo una conferma (finestra di conferma). Questo tipo di finestre viene utilizzato, ad esempio, quando l'utente deve effettuare una modifica significativa (uscire dal programma, eliminare il progetto, ecc.). Al momento del cambio di modello, pool di oggetti, pool di materiali o pool di schemi di movimento, l'applicazione chiederà all'utente se desidera scartare le modifiche apportate. Se l'utente intende uscire completamente o ripristinare completamente il programma, anche questa azione verrà confermata qualora siano state effettuate modifiche. Nel caso di più modifiche, possiamo raggruppare le diverse entità in una singola finestra per offrire una migliore panoramica. Le entità devono essere visualizzate nell'ordine in cui appaiono nel programma, per mantenere la coerenza.

Le finestre di informazione vengono utilizzate quando si verifica un errore dell'utente e possono contenere messaggi di errore più o meno intelligenti. Nella maggior parte delle interfacce grafiche utente, gli errori dell'utente sono di natura molto banale e quindi facili da esprimere in un messaggio d'errore. Tuttavia, gli errori dell'utente che si verificano durante il caricamento dei dati del programma da una memoria secondaria sono di natura molto più complessa.

Poiché salvo tutti i dati prodotti dall'applicazione in un formato modificabile (l'utente può leggere i dati in un comune editor di testo e modificarli), l'utente può modificare gli errori. Questi errori devono essere rilevati e accompagnati da un messaggio di errore chiaro al momento del tentativo di caricamento. Ho implementato solo il calcolo del numero di riga dell'errore, che verrà commentato successivamente in "La mia soluzione per il banco di lavoro". I pulsanti di conferma devono essere di tipo testo per minimizzare l'ambiguità. La norma da seguire in Intuition è che la trasformazione "fatale" avvenga all'attivazione del pulsante sinistro nella finestra di conferma ("Ok!", "Chiudi Programma!", "Cancella Dati!"). Per evitare possibili errori di manipolazione, il pulsante destro di conferma ("Annulla") deve essere attivato. Questo pulsante non deve mai cambiare testo per minimizzare la confusione. Tuttavia, i pulsanti fatali (pulsante sinistro) diventano molto più chiari se utilizziamo frasi specificamente scritte durante le conferme a blocco.

Quando è presente un solo pulsante di conferma, esso deve riflettere la natura del problema. Se l'utente commette un errore, il testo del pulsante deve essere formulato alla prima persona ("Colpa Mia!") per rafforzare la consapevolezza che l'utente ha commesso un errore. Questo dovrebbe portare l'utente a detestare l'uso errato dopo un po'. Il problema successivo potrebbe essere che l'utente si irriti con il computer e i suoi toni da "saggio superiore".

Problemi di natura meno grave (ad esempio, installazione errata del software) che non influiscono sull'applicazione in modo significativo, ovviamente, non devono generare questi tipi di messaggi esplicativi intensi ("Ignora!"). La base del mio utilizzo di queste scelte lessicali è che i programmi che usano esclusivamente il pulsante "OK" finiranno prima o poi in una fase ambigua, e modificare il pulsante di errore violerebbe le regole. Dovrebbe essere più facile correggere gli errori che commetterli.

Un campione delle finestre di interrogazione, affermazione e informazione di 3D-Audio.
La mia soluzione per i menu

Ulteriori dettagli che facilitano l'interazione sono i menu. Questi servono, tra le altre cose, a evitare pressioni multiple di tasti per diverse funzioni. La progettazione dei menu deve inoltre seguire la natura generale dell'interfaccia ed essere molto simile ad altri programmi. Secondo lo standard Intuition, le trasformazioni del progetto devono apparire per prime, seguite dagli strumenti di modifica. Dopo questi, vengono gli operatori più specifici del programma. Anche se si cercano di evitare le pressioni multiple di tasti, queste sono presenti sotto forma di pressione del tasto Amiga destro combinato con un tasto normale. Questa forma viene visualizzata automaticamente nel menu da Intuition. Queste funzioni aumentano l'efficienza dell'utente senza compromettere la facilità d'uso per i principianti.

In ogni istanza dell'applicazione, l'utente può attivare le funzioni di menu necessarie associate alla finestra attiva. Possiamo implementare menu locali, progettati appositamente per ogni finestra utente. Tuttavia, questo approccio crea una forte confusione nell'utente, poiché ampie modifiche visive dei menu all'interno della cornice dell'applicazione compromettono la coerenza locale. Ho risolto questa difficoltà rendendo il menu un menu globale. Il problema con questa soluzione è che l'utente può attivare funzioni errate in istanze sbagliate. Per evitare tali problemi e guidare l'utente verso le funzioni corrette, ho reso inattive (sbiadite) tutte le funzioni di menu non correlate in tutti i casi specifici.

Le funzioni implementate nel menu "Project" sono: "New" (ripristino completo di tutta l'applicazione), "Open..." (caricamento del modello, della collezione di oggetti, della collezione di materiali, della collezione di schemi di movimento e dei dati di ray tracing diretto e inverso), "Merge..." (fusione di modelli, collezioni di oggetti, collezioni di materiali e collezioni di schemi di movimento), "Save" (salvataggio del modello, della collezione di oggetti, della collezione di materiali e della collezione di schemi di movimento senza modificare il nome precedente), "Save As..." (come "Save", ma con eventuale modifica del nome precedente), "About..." (apre la finestra informativa "About Window") e "Quit..." (chiude il programma con domande di conferma).

Il menu del progetto 3D-Audio utilizzato in tutti i contatti esterni. Inoltre, l'utente può accedere alla finestra del primo soccorso tramite questo menu e, se desidera terminare la sessione di modellazione, può effettuare un'uscita completa.

Poiché questo programma è destinato a team di grandi dimensioni che devono lavorare in parallelo, la suddivisione dei dati del programma è estremamente importante. Alcuni membri del team modellano, mentre altri si occupano di materiali e arredi. Inoltre, alcuni possono applicare forme di movimento agli oggetti della modello già completati. Le funzioni di "Unione" ("Merge") sono appositamente progettate per questo scopo.

Le funzioni disponibili in "Editing Windows" servono unicamente a posizionare i rispettivi finestre in primo piano e a evitare confusione sullo schermo. La suddivisione in due sezioni è stata effettuata perché le tre finestre inferiori sono di tipo domanda, mentre quelle superiori sono i principali finestre di modifica.

Quando l'utente non ha accesso a un grande monitor ad alta risoluzione, lo schermo sarà affollato da finestre sovrapposte, e per facilitare la ricerca è disponibile questo menu. L'attivazione di una voce specifica del menu porta la finestra corrispondente in primo piano.

I parametri e l'attivazione del ray tracer sono visualizzati nel menu "Tracer". I parametri di precisione sono tutti dello stesso tipo enumerativo ("Alta", "Media", "Bassa", "Automatico"), e i loro nomi funzionali sono formulati in modo coerente. Anche se si tratta di testi lunghi, queste funzioni sono destinate a un utilizzo poco frequente. L'utente trascorre più tempo nella modellazione che nelle impostazioni dei parametri, quindi i requisiti di efficienza hanno poca rilevanza in questo caso. In realtà, questo tipo di impostazione dei parametri è sconsigliabile, poiché l'utente non ha una visione d'insieme delle funzioni impostate. Va nuovamente ricordato che la componente di ray tracing è ancora in fase beta. La seconda sezione di questo menu serve ad attivare la parte di calcolo del ray tracing nell'applicazione. La terza sezione è dedicata alla visualizzazione dei dati già calcolati.

I vari parametri dell'algoritmo di tracciamento dei raggi sono stati inseriti in questo menu. (Nota! Fase beta)

Le funzioni che non trovano spazio negli altri menu le raggruppiamo alla fine della barra dei menu ("Varie"). Questo menu non deve essere considerato una "menu di scarto" per funzioni superflue, ma deve invece contenere funzioni importanti. Funzioni rilevanti nel mio programma sono l'eliminazione di specifiche pile "Annulla/Ripristina" ("Clear >>", dove >> indica la presenza di sottomenu) e l'apertura della finestra delle impostazioni di base dell'interfaccia utente ("Preferenze...").

))) )))

Quando la memoria del computer è piena, può essere una buona idea svuotare vari "mucchi di cose da fare/non fatte". L'utente può attivare la finestra delle impostazioni predefinite tramite questo menu.
La mia soluzione per il banco di lavoro

Le unità dati associate all'applicazione devono essere visualizzate sulla scrivania ("Workbench") tramite icone semplici. Queste icone devono rappresentare il contenuto delle unità dati (vedi figura 4.13), e l'utente può ridefinirle tramite "Icon Editor" (programma standard dell'ambiente Amiga) per adattarle meglio alle proprie esigenze. Le icone delle unità dati, insieme alle impostazioni predefinite e agli oggetti primitivi, materiali e schemi di movimento, sono posizionate in una cartella speciale ("3DA-Prefs"). L'utente può personalizzare tutte queste icone e file dati secondo i propri gusti utilizzando un appropriato editor di sistema. Ho evitato l'inserimento di numeri nel programma principale, poiché la precisione del ray tracing è bassa.

In realtà, qualsiasi forma di rappresentazione numerica risulta sgradita agli utenti non tecnicamente orientati. In numerosi casi ho osservato utenti che hanno abbandonato un'applicazione a causa della sua eccessiva rappresentazione numerica. Escludendo blocchi di numeri, aumentiamo l'usabilità (personalmente amo i numeri). Gli utenti interessati a una maggiore precisione possono "doppio cliccare" su un'unità dati. Questo aziona il processore di testi preferito, che a sua volta carica l'unità dati. In termini meno criptici, l'icona è collegata al processore di testi e non al mio programma principale. Tuttavia, questo comportamento può essere facilmente modificato cambiando la "Default Tool" nelle icone originali, situate nella sottocartella Icons. L'unica funzionalità utente in queste entità di dati modificabili è che le righe di testo sono precedute da $ e quelle numeriche da #, oltre al fatto che un'intestazione informa l'utente sul tipo di file. Per coloro che trovano questi caratteri strani, voglio chiarire che si tratta di un'eredità dell'epoca BASIC, e ho ritenuto che fossero adatti in questo contesto. In realtà, dovrebbe esistere un compilatore bidirezionale (linguaggio intermedio <-> linguaggio) per questa entità. Tuttavia, ho assegnato a questo il livello di priorità più basso, poiché il programma principale non è ancora completo. L'implementazione di un compilatore o interprete bidirezionale coerente con PHIGS (Programmer's Hierarchical Interactive Graphics Standard) (esecuzione parallela sotto ARREX) è solo un progetto speciale.

Un possibile scenario sulla postazione di lavoro. Le diverse unità dati sono logicamente e fisicamente separate anche sui supporti di archiviazione. Le stesse unità di preconfigurazione sono presenti in 3DA-Prefs, dove l'utente può impostare i propri file primitivi da caricare all'avvio di 3D-Audio. Inoltre, le icone standard sono collocate in una sottocartella "Icons", dove l'utente può personalizzare le icone delle unità dati e specificare quale tipo di programma deve essere avviato con un doppio clic sull'icona.

La progettazione di queste icone è stata realizzata a un livello "naive". Ad esempio, l'icona dello schema di movimento è visualizzata come un aereo. Inoltre, l'icona del materiale è stata presa dallo standard dei filtri di segnale (tre onde sovrapposte). L'icona dell'oggetto è disegnata come un cubo fluttuante liberamente, mentre l'icona del modello è un piccolo modello con terreno. L'icona delle impostazioni predefinite è stata progettata come un modulo di domande in miniatura. Le due possibili metodologie di calcolo, tracciamento dei raggi in avanti e all'indietro, sono visualizzate con un altoparlante e un microfono con una freccia orientata nella direzione corretta. L'icona del programma principale è una variante stilizzata di A3D (Audio 3D), che dovrebbe assomigliare a un microfono all'interno di un campo sonoro. Coloro che non riescono a interpretare l'icona in questo modo non devono preoccuparsi eccessivamente. All'avvio, le applicazioni possono richiedere diversi parametri di avvio ("WBArgs", che significa WorkBench Arguments, o "CArgs", Command line interface Arguments).

Icon del programma principale in cui l'utente può impostare la risoluzione dello schermo desiderata per questa applicazione (WBArgs).

Questi parametri possono descrivere requisiti di memoria, risoluzione dello schermo, ecc. Ho implementato il parametro della risoluzione dello schermo in questa fase iniziale, poiché l'applicazione verrà probabilmente installata una sola volta per macchina. Lo standard Amiga inglese richiede che "HIRES" o "SUPERLACE" vengano aggiunti ai "Tool Types" come parole di risoluzione per mantenere la coerenza.

Flusso di interazione delle icone

Lo schema a flusso delle icone mostra la comunicazione tra le varie componenti del programma.
Una freccia continua indica che i dati vengono generati e utilizzati. Una freccia tratteggiata indica che la modifica non è consigliata. Una linea continua spessa indica il controllo del programma principale.

Algoritmi di trasformazione 3D

...real computer scientists rarely use numbers larger than 255...

Andrew S. Tanenbaum

Nel precedente paragrafo ho scritto sull'interazione uomo-computer (HCI) e i suoi requisiti. La parte più importante del mio programma, se consideriamo l'HCI, è l'editor grafico tridimensionale. Per renderlo utilizzabile, gli algoritmi fondamentali della modellazione 3D devono essere ottimizzati al massimo livello possibile. Possiamo suddividere la modellazione 3D nei seguenti componenti: scalatura (cambiamento di dimensione), traslazione (spostamento), rotazione e proiezione. La ragione per cui consideriamo qui la proiezione è che visualizziamo su uno schermo 2D. La scalatura e lo spostamento non richiedono grande potenza di calcolo, e la proiezione non è particolarmente complessa. Tuttavia, la rotazione è di gran lunga l'operazione più onerosa in termini di tempo. Ignoro i disegni di linee e superfici, poiché l'Amiga li implementa già nell'hardware. In questa sezione vengono mostrate le ottimizzazioni algoritmiche sviluppate tra il 1987 (Algoritmo Base) e il 1994 (Ottimizzazione Discreta Tipo III = DOT³) dell'algoritmo di rotazione.

Ogni programma ha diversi collo di bottiglia legati alla velocità di calcolo, ed è su questi che dobbiamo concentrarci. L'ottimizzazione deve essere effettuata quando si dispone di un algoritmo ben formulato, con la complessità più bassa tra tutti gli altri algoritmi che risolvono lo stesso problema. Il confine tra ottimizzazione e sviluppo algoritmico è molto sfumato. Le differenze tra gli algoritmi DOT¹ e DOT³ potrebbero forse essere definite sviluppo algoritmico piuttosto che ottimizzazione. Questi algoritmi sono in pratica molto semplici (quando si osservano le soluzioni nella forma scritta) e non dovrebbero causare grandi difficoltà. Per comprendere appieno gli algoritmi, richiedo che il lettore possieda conoscenze di algebra oltre alla mnemonic di Motorola. Tuttavia, l'ottimizzazione è estremamente difficile, e i produttori di programmi spesso non dedicano tempo né risorse a questo aspetto. Chi non è interessato all'ottimizzazione e alla lingua primaria del computer può saltare questo paragrafo; tuttavia, considero queste pagine una lettura utile, poiché questi algoritmi e i loro vantaggi e svantaggi sono estremamente importanti da comprendere. Ho implementato l'algoritmo DOT³ in virgola mobile per ottenere una maggiore coerenza scientifica nell'applicazione. Sebbene le operazioni in virgola mobile siano molto più lente rispetto all'aritmetica discreta tradizionale, la potenza dell'algoritmo DOT³ è tale che il collo di bottiglia si trova nella GPU. Nota: questo vale per ECS-Agnes, ma non per AGA-Agnes (due diverse generazioni di GPU per computer Amiga). Ciò implica che l'utilizzabilità è altrettanto buona su un A-500 (processore principale MC68030 a 50 MHz e processore matematico MC68882 a 60 MHz — questi IC sono prodotti da Motorola) quanto su un A-1200 (processore principale MC68020 a 28 MHz ma senza processore matematico!). Ulteriore chiarimento: il MC68020 non dispone di cache dati e ha una cache istruzioni meno ampia rispetto al MC68030. In ulteriori implementazioni con AAA-Agnes (GPU non rilasciata), sarà probabilmente necessaria l'implementazione discreta dell'algoritmo DOT³ per sfruttare appieno la potenza del computer.

Algoritmo di base

Le unità adatte per descrivere il mondo sono la larghezza (asse X), l'altezza (asse Y) e la profondità (asse Z), che chiamo assi principali. Nota che questi sono ortogonali (perpendicolari) tra loro. Una volta stabilita questa visione del mondo, possiamo procedere con varie operazioni. Le operazioni di base da poter eseguire sono le rotazioni del modello attorno agli assi principali. Per la rotazione intorno a un asse principale, possiamo utilizzare rotazioni 2D, poiché la posizione dei punti lungo l'asse di rotazione non cambia.

La rotazione di un blocco lungo l'asse Z di 270° mostra l'invarianza lungo l'asse Z.

Quando ruotiamo attorno all'asse Z, tutti i punti (x,y,z)(x, y, z) vengono trasformati in (x,y,z)(x', y', z') nel seguente modo:

Formula 1: Turnz(x,y,z,az)Turn_z(x,y,z,a_z)

x=xcos(az)ysin(az)(1.x)y=xsin(az)+ycos(az)(1.y)z=z(1.z)\begin{array}{l|l} \hline x'=x \cdot \cos(a_z)-y \cdot \sin(a_z) & (1.x) \\ y'=x \cdot \sin(a_z)+y \cdot \cos(a_z) & (1.y) \\ z'=z & (1.z) \\ \hline \end{array}

Quando ruotiamo attorno all'asse X, tutti i punti (x,y,z)(x, y, z) vengono trasformati in (x,y,z)(x', y', z') nel seguente modo:

Formula 2: Turnx(x,y,z,ax)Turn_x(x,y,z,a_x)

x=x(2.x)y=ycos(ax)zsin(ax)(2.y)z=ysin(ax)+zcos(az)(2.z)\begin{array}{l|l} \hline x'=x & (2.x) \\ y'=y \cdot \cos(a_x)-z \cdot \sin(a_x) & (2.y) \\ z'=y \cdot \sin(a_x)+z \cdot \cos(a_z) & (2.z) \\ \hline \end{array}

Quando ruotiamo attorno all'asse Y, tutti i punti (x,y,z)(x, y, z) vengono trasformati in (x,y,z)(x', y', z') nel seguente modo:

Formula 3: Turny(x,y,z,ay)Turn_y(x,y,z,a_y)

x=zsin(ay)+xcos(ay)(3.x)y=y(3.y)z=zcos(ay)xsin(ay)(3.z)\begin{array}{l|l} \hline x'=z \cdot \sin(a_y)+x \cdot \cos(a_y) & (3.x) \\ y'=y & (3.y) \\ z'=z \cdot \cos(a_y)-x \cdot \sin(a_y) & (3.z) \\ \hline \end{array}

Dopo varie semplificazioni e riorganizzazioni, possiamo raccogliere le tre formule precedenti in una formula generale con 12 moltiplicazioni e 6 addizioni:

Formula 4: Turnzyx(x,y,z,az,ay,ax)Turn_{zyx}(x,y,z,a_z,a_y,a_x)

y1=ycos(ax)zsin(ax)(4.y1)z1=ysin(ax)+zcos(ax)(4.z1)x1=xcos(ay)z1sin(ay)(4.x1)z=xsin(ay)+z1cos(ay)(4.z2)x=x1cos(az)y1sin(az)(4.x2)y=x1sin(az)+y1cos(az)(4.y2)\begin{array}{l|l} \hline y_1=y \cdot \cos(a_x)-z \cdot \sin(a_x) & (4.y_1) \\ z_1=y \cdot \sin(a_x)+z \cdot \cos(a_x) & (4.z_1) \\ x_1=x \cdot \cos(a_y)-z_1 \cdot \sin(a_y) & (4.x_1) \\ z'=x \cdot \sin(a_y)+z_1 \cdot \cos(a_y) & (4.z_2) \\ x'=x_1 \cdot \cos(a_z)-y_1 \cdot \sin(a_z) & (4.x_2) \\ y'=x_1 \cdot \sin(a_z)+y_1 \cdot \cos(a_z) & (4.y_2) \\ \hline \end{array}

Ora vediamo chiaramente il problema delle rotazioni, poiché abbiamo bisogno di rapidi calcoli delle funzioni trigonometriche. Il modo più semplice per risolvere questo problema è posizionare i fattori trigonometrici in pseudocostanti (vedere la metodologia di programmazione per la spiegazione del termine), che vengono calcolate durante l'inizializzazione della funzione. Questo impedisce di sovraccaricare la coprocessore matematico e risulta chiaramente vantaggioso in termini di velocità. Di seguito è riportata un'implementazione possibile dell'algoritmo di base, e si richiede al lettore di notare l'assenza di un'implementazione matriciale nella struttura dati. La ragione è che abbiamo bisogno di tutta la potenza per l'algoritmo e non per mantenere la struttura dati.

    /******************************************************************
* Denis Tumpic 1987 *
* Dimenzione 3. *
* Extract from Slave Function: Turn_Coordinates *
******************************************************************/
.
.
.
/**************************************************************
* Initiatus : Precalculation of turn angles which are placed *
* in pseudoconstants *
**************************************************************/
sax=Sin(ax): cax=Cos(ax)
say=Sin(ay): cay=Cos(ay)
saz=Sin(az): caz=Cos(az)

/**************************************************************
* Itera Computa : Operate turnmatrix over all coordinates *
**************************************************************/
Iterate next chunk thru i from 0 to Number_Of_Coordinates with
positiv discrete monotonic:
tempY=sourceY[i];
tempX=sourceX[i];
tempZ=sourceZ[i];
Y1=tempY*cax-tempZ*sax;
Z1=tempY*sax+tempZ*cax;
X1=tempX*cay-Z1*say;
destinationZ[i]=tempX*say+Z1*cay;
destinationX[i]=X1*caz-Y1*saz;
destinationY[i]=X1*saz+Y1*caz;
Ottimizzazione Discreta Tipo I

La prima cosa che colpisce osservando l'algoritmo di base è il suo elevato grado di dipendenza dai calcoli trigonometrici. I piccoli computer raramente dispongono di coprocessori matematici aggiuntivi, ed è completamente impossibile implementare l'algoritmo di base in virgola mobile su questi dispositivi se il feedback in tempo reale è un requisito. Possiamo risolvere il problema rinunciando ai requisiti di precisione. La risoluzione del monitor è bassa (1280x570), e quindi non sono necessari calcoli in virgola mobile. Per poter eliminare questi calcoli, dobbiamo effettuare le approssimazioni corrette, poiché una risoluzione troppo bassa (dal punto di vista computazionale) è una vera e propria abominazione scientifica. Innanzitutto, dividiamo il cerchio in 256 parti, per semplicità ed efficienza. Successivamente, possiamo generare una tabella sinusoidale e cosinusoidale (intrecciate) di 640 byte, dalla quale la funzione base può recuperare dati pre-calcolati. Ogni valore di funzione ha 16 bit; la moltiplicazione per 32768 è quindi possibile, fornendo almeno due cifre significative. Potrebbe sembrare privo di senso effettuare questa discretizzazione, ma un po' di riflessione ci chiarisce che principalmente ruoteremo oggetti. Questo perché ruotiamo oggetti all'interno di altri oggetti, e tutti gli oggetti volano attorno nel modello in ogni istante. Per chiarimento, rimando alla forte definizione degli ambienti VR del capitolo precedente.

La variazione di velocità è così elevata che possiamo facilmente costruire un paesaggio frattale con 100 punti e 300 linee, ruotabile in tempo reale (25 volte/s) su una comune A-1000 (MC68000 a 7,14 MHz). La seguente lista di codice è un'implementazione in assembler precoce per IGG (Inter Gigantica Galactica - L'ambiente VR completo):

    /******************************************************************
* Denis Tumpic *
* Pre Inter Gigantica Galactica *
* 1987-1988 *
* Slave Function: Turn_Coordinates *
* a0 : Pointer to Source_Coordinates *
* a1 : Pointer to Destination_Coordinates *
* a6 : Number_Of_Coordinates *
* ax, ay, ax : Turn angle around x-axis, y-axis, z-axis *
*cc instruction remark *
******************************************************************/
TurnCoords ;Initiatus
28 lea SinTable,a2 ; ->SinTable data fetch start address
28 lea CosTable,a3 ; ->CosTable data fetch start address
16 move.b ax,d0 ;Get angle AX
12 and.w #$FF,d0 ;Clear highbyte
10 asl.w #1,d0 ; *2 givs relative table pointer
14 move.w 0(a3,d0.w),d1 ;d1=Cos(ax)
14 move.w 0(a2,d0.w),d2 ;d2=Sin(ax)
16 move.b ay,d0 ;Get Angle AY
12 and.w #$FF,d0 ;Clear highbyte
10 asl.w #1,d0 ; *2 givs relative table pointer
14 move.w 0(a3,d0.w),d3 ;d3=Cos(ay)
14 move.w 0(a2,d0.w),d4 ;d4=Sin(ay)
16 move.b az,d0 ;Get angle AZ
12 and.w #$FF,d0 ;Clear highbyte
10 asl.w #1,d0 ; *2 givs relative table pointer
14 move.w 0(a3,d0.w),d5 ;d5=Cos(az)
14 move.w 0(a2,d0.w),d6 ;d6=Sin(az)

TurnLoop ;Itera Computa
12 move.w 2(a0),d0 ;d0 = y
70 muls d1,d0 ;d0 = y*Cos(ax)
12 move.w 4(a0),d7 ;d7 = z
70 muls d2,d7 ;d7 = z*Sin(ax)
12 sub.l d7,d0 ;d0 = y*Cos(ax)-z*Sin(ax)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized Y1
4 move.w d0,a3 ;Y1 = a3 = d0
12 move.w 2(a0),d0 ;d0 = y
70 muls d2,d0 ;d0 = y*Sin(ax)
12 move.w 4(a0),d7 ;d7 = z
70 muls d1,d7 ;d7 = z*Cos(ax)
12 add.l d7,d0 ;d0 = y*Sin(ax)+z*Cos(ax)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized Z1
4 move.w d0,a4 ;Z1 = a4 = d0
8 move.w (a0),d0 ;d0 = x
70 muls d3,d0 ;d0 = x*Cos(ay)
4 move.w a4,d7 ;d7 = Z1
70 muls d4,d7 ;d7 = Z1*Sin(ay)
12 sub.l d7,d0 ;d0 = x*Cos(ay)-Z1*Sin(ay)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized X1
4 move.w d0,a5 ;X1 = a5 = d0
8 move.w (a0),d0 ;d0 = x
70 muls d4,d0 ;d0 = x*Sin(ay)
4 move.w a4,d7 ;d7 = Z1
70 muls d3,d7 ;d7 = Z1*Cos(ay)
12 add.l d7,d0 ;d0 = x*Sin(ay)+Z1*Cos(ay)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized Z'
12 move.w d0,4(a1) ;Z' = d0
4 move.w a5,d0 ;d0 = X1
70 muls d5,d0 ;d0 = X1*Cos(az)
4 move.w a3,d7 ;d7 = Y1
70 muls d6,d7 ;d7 = Y1*Sin(az)
12 sub.l d7,d0 ;d0 = X1*Cos(az)-Y1*Sin(az)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized X'
8 move.w d0,0(a1) ;X' = d0
4 move.w a5,d0 ;d0 = X1
8 muls d6,d0 ;d0 = X1*Sin(az)
4 move.w a3,d7 ;d7 = Y1
70 muls d5,d7 ;d7 = Y1*Cos(az)
12 add.l d7,d0 ;d0 = X1*Sin(az)+Y1*Cos(az)
10 asl.l #1,d0 ;d0 = d0*2
4 swap d0 ;d0 = d0/65536 -> Normalized Y'
12 move.w d0,2(a1) ;Y' = d0
8 addq #6,a0 ;Increase source pointer
8 addq #6,a1 ;Increase destination pointer
8 subq #1,a6 ;Decrease coordinate counter
10 bne TurnLoop ;Transform until no more coordinates
rts

I numeri all'inizio delle righe non sono numeri di riga, ma il numero di cicli di clock (cc) necessari per completare l'operazione. La somma di questi valori indica che Initiatus richiede 254 cc e Itera Computa 1162 cc per ogni coordinata. Si noti che sia i registri dati che quelli di indirizzo sono stati utilizzati come memorie intermedie per aumentare la velocità. I registri dati d1 a d6 sono pseudocostanti e non devono essere distrutti in Itera Computa. Di conseguenza, siamo costretti a utilizzare i registri di indirizzo per la memorizzazione intermedia. L'accesso alla memoria esterna comporta infatti almeno 4 cc/addizione di tempo extra. Anche se i problemi di wait-state non esistono sull'Amiga, dobbiamo sempre minimizzare gli accessi esterni. In particolare, dobbiamo farlo quando abbiamo un'architettura con wait-state in cui diversi processori condividono il bus in modo asincrono.

Ottimizzazione Discreta Tipo II

Dalla computazionalmente pesante algoritmo base (oltre 100.000 cck per coordinata) alla algoritmo DOT¹ leggera (1162 cck), la maggior parte ritiene che ulteriori ottimizzazioni non siano necessarie. Tuttavia, è un obiettivo affascinante implementare l'algoritmo sotto i 1000 cck. La potenza computazionale è concentrata nelle moltiplicazioni (massimo 70 cck/moltiplicazione) e rappresenta 840 cck dell'intero calcolo. Se riuscissimo a eliminare le dodici moltiplicazioni, potremmo aumentare ulteriormente la velocità. La soluzione, come abbiamo già riconosciuto, consiste nel generare una tabella precalcolata con tutte le possibili moltiplicazioni. Il problema di questa implementazione è che la tabella richiede molta memoria. Se non ci impegniamo e utilizziamo aritmetica a 8 bit (256 valori), possiamo generare una tabella di 160 kB (640 * 256 byte). Il principale problema di questo algoritmo è che non possiamo avere un modello ad alta risoluzione, e aumentare l'aritmetica a 16 bit richiederebbe 40 MB di memoria. Inoltre, la precisione nei bordi è ancora peggiore in questa implementazione rispetto a DOT¹. Per risolvere il problema di risoluzione, possiamo modellare piccoli "mondi a 256 valori" concatenati in modo appropriato. Questa soluzione aumenterà anche la precisione nei bordi. Dal punto di vista implementativo, ho pensato fin dall'inizio di utilizzare questa soluzione, poiché riesco facilmente a rimanere sotto i 1000 cck. In realtà, potrebbe scendere a 600 cck, ma poiché richiede un po' più movimento di dati rispetto a prima, si attesta intorno ai 900 cck. Tuttavia, la concatenazione non è del tutto banale, e l'algoritmo successivo mi ha ispirato altre idee.

Il principio stesso di come le mondi di 256x256x256 unità vengono concatenate con sovrapposizione (spazio di concatenazione). Questo determina direttamente la dimensione massima dell'oggetto più grande (parte di un oggetto nella struttura gerarchica completa) nel modello. I calcoli devono essere eseguiti solo sulle unità che vediamo al momento, e l'algoritmo può essere facilmente suddiviso su più processori assumendo che gli oggetti diversi siano indipendenti.
Ottimizzazione Discreta Tipo III

Gli algoritmi iniziali sono stati sviluppati alla fine degli anni '80, e la maggior parte ritiene ora che non ci sia molto altro da fare. Tuttavia, raggiungere meno di 500 cck è un obiettivo molto allettante. Dovrebbero esistere modi più intelligenti per implementare l'algoritmo di rotazione; e se utilizziamo un po' di algebra e cerchiamo davvero di comprendere cosa significhi la commutatività (si confronti con la rotazione di un libro prima di 45º attorno all'asse x e poi di 45º attorno all'asse y, e viceversa), l'algoritmo si evolverà nella seguente gioia:

    /************************************************
* Denis Tumpic *
* IGG30++ 1994 *
* Extract from Slave Function: Turn_Coordinates *
*************************************************
x'=x; y'=y; z'=z

if (daz)
x1=Cos[daz][x']-Sin[daz][y'];
y1=Sin[daz][x']+Cos[daz][y'];
x'=x1; y'=y1;
if (dax)
y1=Cos[dax][y']-Sin[dax][z'];
z1=Sin[dax][y']+Cos[dax][z'];
y'=y1; z'=z1;

if (day)
x1=Cos[day][x']-Sin[day][z'];
y1=-Sin[day][x']+Cos[day][z'];
x'=x1; y'=y1;

Notate che utilizzo differenze angolari invece di angoli assoluti. Tuttavia, osservate che queste differenze angolari possono essere arbitrariamente grandi (modulo 256). Si noti inoltre la trasformazione in un algoritmo che, dal punto di vista della complessità, ha cambiato natura da un algoritmo sempre a tempo costante (isocrono) a un algoritmo a tre casi (non isocrono). Inoltre, Initiatus è incorporato in Itera Computa. Questa intuizione ci consente di ignorare completamente la coprocessore matematico, e l'uso della tabella in DOT² ci porta ora sotto i 500 cck. Nel caso peggiore (Worst Case) sono necessari poco meno di 300 cck, mentre nel caso migliore circa 140 cck. Non oserei affermare che questa implementazione rappresenti il limite inferiore per le rotazioni, poiché ho già sbagliato su questo punto due volte in passato. Tuttavia, questa implementazione algoritmica rende possibile ruotare oltre 20.000 coordinate al secondo su una comune A-1000 con un processore principale MC68000 a 7,14 MHz (l'algoritmo base riusciva appena a gestire circa 70 elementi). Poiché desidero mantenere il tono scientifico dell'applicazione, ho implementato questa versione completamente in virgola mobile (AOT³). Dal punto di vista della velocità, AOT³ è più veloce della sua controparte in virgola mobile di DOT¹, e ciò ha reso possibile muovere oggetti più grandi nella modellazione 3D con movimenti meno frammentati. Poiché la grande turbolenza attuale intorno ai processori principali comporta un periodo di incertezza, non ho programmato l'algoritmo in assembler. La semplice struttura dell'algoritmo potrebbe indicare che un computer basato su RISC otterrebbe una migliore implementazione. Tuttavia, i numerosi accessi esterni costituiscono il problema principale. Questi algoritmi richiedono una memoria veloce senza stati di attesa.

Se riuscissimo a realizzare una moltiplicazione più veloce di un trasferimento dati, questi algoritmi crollerebbero come un mazzo di carte. Inoltre, potremmo ritenere che un'implementazione hardware dell'algoritmo AOT³ dovrebbe essere standard in una macchina VR. Non so come Hewlett-Packard abbia implementato l'algoritmo di rotazione nei suoi programmi CAD, che utilizzano schede grafiche HCRX (che riescono a disegnare 2,3 milioni di vettori 3D al secondo quando il processore principale funziona a 100 MHz). Tuttavia, non dovrebbe essere molto diverso dalla mia soluzione se la velocità è stata posta come obiettivo primario.

Algoritmi di propagazione del suono

Eine Hauptursache philosophischer Krankheiten - einseitige Diät: man nährt sein Denken mit nur einer Art von Beispielen.

Ludwig Wittgenstein

Questo paragrafo tratta lo sviluppo dell'algoritmo di propagazione del suono. A differenza degli algoritmi di trasformazione 3D, che sono molto ben definiti, gli algoritmi di propagazione del suono non sono altrettanto completamente formalizzati e quindi non sono ancora entrati in una fase di ottimizzazione. Lo sviluppo dell'algoritmo inizia sempre con la formulazione di un ipotesi ipotetica per risolvere il problema. Una volta ottenuta un'ipotesi ben formulata che funzioni in una possibile implementazione, l'ipotesi deve essere migliorata in modo tale che la complessità computazionale dell'algoritmo venga ridotta. In termini semplici, ciò significa che dobbiamo compiere meno lavoro, e dal punto di vista dei risultati, entrambi gli algoritmi devono fornire risposte identiche. Abbiamo due mondi a cui trasferire i nostri algoritmi. A seconda di quale scegliamo, questo influisce direttamente sui tempi di calcolo. Nel primo e più scientifico mondo, disponiamo di una soluzione completamente analitica del problema. Nel secondo, scomponiamo il problema in segmenti discreti e lo risolviamo con un minor grado di precisione, comportando tempi di esecuzione significativamente più brevi. Inoltre, dobbiamo sempre evitare algoritmi che causano un aumento esponenziale dei requisiti di memoria o del tempo di esecuzione in funzione dell'aumento della quantità di dati di input.

Innanzitutto descrivo la soluzione completamente analitica, per poi passare a quella totalmente discreta. Seguono il ben noto metodo delle immagini speculari, utilizzato ad esempio nel calcolo di guide d'onda (telecomunicazioni), e successivamente il relativamente nuovo approccio basato sul ray-tracing. Viene trattata una miscela ben bilanciata tra il metodo delle immagini speculari e il ray-tracing, oltre a una piccola digressione che chiamo approssimazione ellissoidale. Gli algoritmi sopra menzionati hanno rapidamente suggerito l'idea di implementare un'algoritmo di propagazione del suono con un'euristica ben formulata, per abilitare feedback in tempo reale. Infine, descrivo il metodo meno scientifico "Cut & Paste Ray-tracing" e i suoi limiti.

I libri che hanno influenzato questa sezione sono: "Room Acoustics" di Heinrich Kuttruff, "Audio Engineering Handbook" a cura di K. Blair Benson, "An Introduction To Ray Tracing" a cura di Andrew S. Glassner e "Advanced Animation and Rendering Techniques" di Alan e Mark Watt.

Soluzione analitica completa

La prima cosa che dobbiamo sempre tentare è la soluzione completamente analitica. Se riusciamo a implementare una soluzione completamente analitica, non avremo errori di approssimazione. Notate che intendo una soluzione algebrica computazionale del problema. Anche se le soluzioni algebriche sono più matematicamente corrette, richiedono molto tempo per essere risolte. Nei pochi casi semplici in cui è possibile risolvere il problema in modo algebrico, lo faremo; tuttavia, nella maggior parte dei casi i problemi sono di natura molto più complessa.

Soluzione totalmente discreta

Dopo la caduta piatta della soluzione completamente analitica, possiamo tentare una soluzione totalmente discreta. Il seguente esempio servirà da base: il nostro mondo contiene un muro e un oggetto generatore di suono. In questo caso, otterremo un suono diretto e un suono riflesso, se posizioniamo l'oggetto di ascolto sullo stesso lato dell'oggetto generatore di suono. Questo caso semplice può essere descritto facilmente con un'equazione delle onde e risolto relativamente rapidamente tramite qualche metodo degli elementi finiti (FEM) o metodo degli elementi al contorno (BEM).

Se consideriamo la definizione forte di VR, ci rendiamo conto che il nostro mondo modello contiene molti oggetti, i quali non possiedono superfici lineari. Siano essi generatori di suono o meno, questi daranno luogo a equazioni delle onde non lineari. Possiamo ora chiederci quante equazioni delle onde siano necessarie per risolvere il problema della propagazione del suono in modo totalmente discreto. Poiché tutti gli oggetti (n st) interagiscono, sono necessarie almeno n*(n-1)/2 equazioni delle onde non lineari. Ogni oggetto può generare una discontinuità se non diffrange le onde sonore, e tale discontinuità è inoltre dipendente dalla frequenza. Inoltre, dobbiamo considerare le masse d'aria (diverse effetti di rifrazione), il movimento degli oggetti (effetto Doppler) e le fluttuazioni di temperatura, che introducono ulteriori non linearità nelle equazioni delle onde.

Se ci limitiamo a stanze chiuse e suddividiamo le equazioni delle onde per banda di frequenza, saranno necessarie circa 1.8*10^9 equazioni differenziali per ogni punto che consideriamo nella stanza, se analizziamo l'intervallo di frequenza da 0 a 10 kHz [29] (risolte con un appropriato FEM). Da questo enorme sistema di equazioni, dobbiamo costruire la risposta all'impulso del mondo modello nei punti in cui abbiamo ricevitori. Una volta riusciti a formulare questi, devono essere calcolati in tempo reale con una velocità di fS campioni/secondo. La base per questa elevata velocità di calcolo è che effetti come il Doppler e la dispersione devono essere completamente realizzati. Dopo questa semplice corrispondenza, dobbiamo solo auralizzare il modello, e l'ambiente audiovisivo VR sarà così un fatto.

Anche se disponiamo dei computer più veloci dell'universo, sembra terribilmente inefficiente risolvere il problema in questo modo. Infatti, è più veloce costruire diverse piattaforme di prova fisiche a scala piena, e inoltre risulta più economico, nonostante probabilmente dovremo demolire un gran numero di queste prima di essere soddisfatti.

In una variante degli elementi finiti (FEM), suddividiamo il modello in piccoli cubi disgiunti ma vicini nello spazio, ognuno con diverse proprietà. Queste proprietà possono variare dal modo in cui interagiscono tra loro fino al movimento nello spazio. In conformità con la definizione forte di VR, dobbiamo suddividere il modello nelle più piccole unità distinguibili. Ciò implica che, dal punto di vista audiovisivo, richiediamo una risoluzione dell'unità di circa 17 mm per catturare i 20 kHz. Il problema con questa soluzione è l'enorme richiesta di memoria (tipicamente per una stanza comune: 8*10^6 * numero di unità) e i calcoli, che risultano altrettanto terribilmente pesanti. Esistono implementazioni [30] (FEM non completa), [31] (caso particolare) di questa soluzione, ma anche qui siamo costretti a scartare il concetto poiché il feedback in tempo reale è quasi impossibile. Forse il metodo diventerà realizzabile se consentiamo a ciascun oggetto di essere un nodo in un grafo completamente connesso. In questa soluzione, la dimensione è n*(n-1)/2 invece di tre, e quindi le caratteristiche aumenteranno proporzionalmente. Ogni oggetto deve generare aggiornamenti dei flussi di raggi nelle caratteristiche di ogni altro oggetto. Inoltre, il requisito del modello di movimento impone che tutte le caratteristiche siano variabili in ogni istante di calcolo. Si notino le somiglianze con le reti neurali. Se consideriamo cosa comporta la diffrazione, la rete dovrebbe talvolta degradarsi dalla completa connessione, e questo deve avvenire automaticamente. Il problema con questo metodo è che i processi rapidi verranno allungati nel dominio temporale. Questo allungamento (diffusione, dispersione) del suono comporta la scomparsa della chiarezza e della percezione spaziale. Tuttavia, la soluzione è accettabile se il modello è statico.

Metodo delle sorgenti speculari

Dopo due varianti senza speranza, è necessario un approccio leggermente diverso. Nel metodo delle sorgenti speculari, consentiamo alle onde sonore di propagarsi come onde luminose (linee rette), e questa è una differenza sostanziale rispetto alle forme precedenti. Ciò implica che consideriamo il campo sonoro come diffuso. Esprimendolo in modo approssimativo, un campo sonoro diffuso è una distribuzione uniforme di pressione sonora senza differenze di fase. Inoltre, la diffrazione, la dispersione e tutti gli altri fattori non lineari non sono rappresentati in questa forma di soluzione (ma possono essere aggiunti successivamente). La figura a pagina successiva mostra come funziona il metodo nel caso 2D.

Rappresentazione semplificata del metodo delle immagini speculari. Il punto nero è il trasmettitore e il punto bianco è il ricevitore (o viceversa). Vengono mostrati i percorsi dei raggi riflessi solo sulle pareti esterne. Le riflessioni che si verificano sulle pareti interne vengono calcolate in modo simile, ma senza blocchi ortogonali in quei casi. Si noti la piegatura del blocco 3x3 nella risposta a destra !!!

Come notiamo, questo metodo è molto esigente in termini di memoria, poiché richiede che il modello sia replicato in memoria fino al punto in cui tutte le riflessioni fino a T60T_{60} (tempo di riverberazione) possano essere calcolate. Un modello tipico può occupare circa 100 kB di memoria. Se lasciamo T60T_{60} a mezzo secondo, ciò implica che devono essere calcolate traiettorie di lunghezza massima di 170 metri. La stanza, che è approssimativamente 5*2*4 metri, dovrebbe quindi essere replicata 34*85*43 volte per includere tutte le traiettorie. Il requisito di memoria diventa interamente di 11 GB!!! Questo non è l'unico problema con questo metodo. Poiché abbiamo oggetti mobili in tutto il modello, dobbiamo aggiornare (ruotare e traslare ogni copia) il mondo del modello in ogni istante di modifica. Sfortunatamente, queste cose rendono la feedback in tempo reale quasi impossibile, anche se possiamo utilizzare un'algoritmo DOT³ specializzato ortogonale. Il vantaggio di questo metodo è che abbiamo una hitrate del cento percento.

Definizione Hitrate: La hitrate è il rapporto tra il numero di intersezioni di raggi sicuramente necessarie e il numero possibile di raggi necessari.

Metodo del ray-tracing

Se rinunciamo al requisito di una hitrate del cento percento, possiamo diffondere i raggi uniformemente in tutte le direzioni da tutte le sorgenti sonore. Questi raggi li lasciamo quindi riflettere sulle superfici degli oggetti. Li facciamo continuare a riflettersi su altri oggetti fino a quando l'energia sonora diventa minima o viene colpito un ricevitore acustico. L'energia sonora diventa minima (soglia uditiva dell'orecchio) a T60T_{60} e non è necessario seguire ulteriormente il raggio, che viene quindi scartato. Quando osserviamo il modello dalle sorgenti sonore, questo viene chiamato forward ray-tracing (dalla parte del ricevitore acustico si chiama backward ray-tracing). I risultati del ray-tracing in avanti e all'indietro non sono gli stessi, poiché i raggi non hanno lo stesso punto di origine (piccole deviazioni angolari all'inizio producono grandi deviazioni alla fine). Anche il ray-tracing richiede che abbiamo un campo sonoro diffuso, poiché i raggi, in realtà piccoli coni emissivi, si disperdono sempre di più man mano che si propagano. Indipendentemente dal tipo di ray-tracing che implementiamo, dobbiamo memorizzare la lunghezza del raggio e la sua risposta di filtraggio. La risposta di filtraggio la calcoliamo più semplicemente moltiplicando insieme le curve di assorbimento degli oggetti che compongono il percorso del raggio (vedi appendice B per chiarimenti). Inoltre, possiamo memorizzare gli angoli di incidenza degli impatti sul ricevitore e quindi facilmente scartare gli impatti non pertinenti alla direttività.

Il metodo di ray-tracing non è nuovo e nella sua forma originale presenta alcuni problemi. Il principale è la sua terribilmente bassa percentuale di colpi (< 2%). Ciò significa che il 98% dei calcoli è sprecato (un calcolo di 10 ore avrebbe richiesto meno di 12 minuti!). Questo è il prezzo che dobbiamo pagare quando non vogliamo utilizzare tanta memoria quanto nel metodo a specchi.

    Primal Ray-tracer Code:

Definition Max length:
Computed reverberation time with Sabins's formula
multiplied with the soundvelocity through air.

Definition Hit object:
An object that mostly reflects rather than diffracts
soundrays.

Definition Transceiver:
Objects that transmits (loudspeaker) or receives (ear)
sound.

Definition Hit point:
Ray impact area on hitobject.

Definition Omnidirectional:
Uniformly select angles from (0..2¶, 0..2¶, 0..2¶)

Definition Clean hit:
When the ray-tracing cone hits a specific hitobject or
transceiver.

Master (Depth First Algorithm) function Trace:
Iterate over omnidirectional tracing rays.
Ray-trace until:
Transceiver hit or if raylength exceeds Max length.
When detected a Clean hit memorize:
Raylength, absorptionresponse and impact angle.

Slave (Recursive or/and Iterative) function Ray_Trace:
Compute nearest possible Hit object and reflect ray specularly through the new Hit point.
Multiply this Hit object absorptionresponse with:
Previous absorptionresponse in this recursion.
Depending on depth and grade of diffusion:
Smash ray into several directions and recurse.

La prima implementazione di questo algoritmo ha portato a diverse conclusioni importanti: tempi di esecuzione estremamente lunghi e una percentuale di colpi molto bassa. Tuttavia, dopo varie ottimizzazioni primarie e secondarie, il tempo di esecuzione è stato ridotto di oltre la metà (rimozione di numerose radici quadrate e precalcolo delle normali e dell'estensione delle superfici degli oggetti). Anche se siamo sulla buona strada, è comunque ancora impossibile ottenere feedback in tempo reale.

Metodo di approssimazione ellissoidale

Se consideriamo l’ambiente circostante dal punto di vista morfologico, esso ci mostra che tutto è più o meno angoloso. Se trascuriamo la caratteristica angolare degli oggetti, che in particolare influenza il suono alle alte frequenze, possiamo considerare tutti gli oggetti come superellissoidi. Le ellissoidi di ordine elevato assomigliano più a parallelepipedi che a ellissoidi tradizionali. Inoltre, la velocità di calcolo è inversamente proporzionale all’ordine dell’ellissoide (un ordine elevato comporta calcoli più lenti). Con questo metodo, abbiamo meno dati precalcolati da gestire e quindi siamo più efficienti in termini di memoria. Ulteriori vantaggi includono espressioni più semplici per il calcolo degli impatti dei raggi e degli angoli di riflessione (indipendentemente dall’ordine). Tuttavia, nonostante queste possibilità, il tasso di collisioni (deprecabile < 0.1%) impedisce l’implementazione di questo metodo.

Metodo ibrido

Un approccio intelligente potrebbe essere quello di combinare il metodo delle sorgenti speculari con il ray-tracing. Qui, facciamo in modo che il modello venga replicato in una quantità ridotta rispetto al passato (tipicamente 3×3×3 copie del modello). Dopo aver calcolato le riflessioni “esatte” nel blocco speculare, possiamo proseguire con il ray-tracing all’interno del rispettivo spazio modello in cui i raggi si trovano.

Notate l’importanza dell’efficienza degli algoritmi di trasformazione in questa soluzione. Anche se per lo più ci occupiamo di riflessioni ortogonali, la risposta in tempo reale ne soffre. Tuttavia, il tasso di collisioni migliora notevolmente; e se trascuriamo ambienti VR rigorosi, questo metodo risulta molto utile.

Un grande vantaggio di questo approccio è che possiamo implementare facilmente questa soluzione in esecuzione parallela. Possiamo farlo a patto di ignorare interferenze e mascheramenti (il che è possibile). Il problema viene ora trasferito alla disponibilità della CPU e all’algoritmo DOT³ specializzato per l’ortogonalità. Qui inizia a emergere una certa semplificazione, poiché ora vediamo la possibilità di risolvere il problema. Tuttavia, questa soluzione rimane ancora molto costosa, e un ulteriore sforzo cognitivo non nuoce.

Metodo euristico

I metodi precedenti non ci hanno fornito grandi esperienze "wow", e ora presentiamo la prima soluzione universale. Attraverso una funzione euristica appropriata (matematicamente chiamate funzioni obiettive), possiamo aumentare la precisione fino a rendere possibile il feedback in tempo reale. Il problema è trovare questa funzione, e si ritiene che questo, insieme al design dell'interfaccia utente, richieda il maggior tempo di sviluppo.

    Denis Tumpic's Heuristic Ray-tracer Code:

Definition Max length:
Computed reverberation time with Sabins's formula
multiplied with the soundvelocity through air.

Definition Hit object:
An object that mostly reflects rather than diffracts
soundrays.

Definition Transceiver:
Objects that transmits (loudspeaker) or receives (ear)
sound.

Definition Hit point:
Ray impact area on hitobject.

Definition Clean hit:
When the ray-tracing cone hits a specific hitobject or
transceiver.

Definition Looking range:
Circular cone that spreads(¶/2) from the hitpoint with
the direction of specular reflection.

Definition Diffuse hit:
When the path from ray-trace hitpoint to transceiver
surface is in the lookingrange and free from hitob
jects.

Master (Pseudoprobabilistic Heuristic) function Trace:
Iterate over ray directions that point onto objects.
Ray-trace until:
Transceiver hit or if raylength exceeds Max length.
When detected a Clen hit memorize:
Raylength, absorptionresponse and impact angle.

Slave (Recursive and Iterative Heuristic) function Ray_Trace:
Compute nearest possible Hit object and reflect ray specu
larly through the new Hit point.

Compute nearest possible Hit object.
Multiply this Hit object absorptionresponse with:
Previous absorptionresponse in this recursion.
When Diffuse hit detected:
Damp ray then memorize:
raylength, filterresponse and hit direction.
End recursion.
Depending on depth and grade of diffusion:
smash ray into several directions and recurse.

In questo modello, considero tutti gli oggetti come possibili ricevitori del suono diretto. A seconda di come il suono diretto della sorgente colpisce l'oggetto osservato (cioè l'angolo di incidenza), attenuiamo il segnale in misura appropriata. Il modo più semplice è utilizzare la funzione coseno per questa parte. Un angolo di incidenza di 90º non produce alcuna attenuazione, mentre onde sonore parallele (se esistenti) vengono completamente attenuate. Questa approssimazione può sembrare molto grossolana all'inizio. Tuttavia, un confronto con le approssimazioni precedenti — il campo sonoro diffuso e superfici oggettive infinite e lisce, che sono i requisiti per il ray-tracing — mostra che è di una magnitudine inferiore. Ulteriori vantaggi di questo metodo sono che possiamo facilmente implementare la diffrazione come un passo normale nell'euristica. Dispersione, rifrazione e direttività possono essere integrati fin dalle fasi iniziali dell'euristica, anche se ciò comporta una notevole riduzione della velocità di esecuzione.

Confronti

Di seguito sono riportati alcuni dati comparativi sulle varie algoritmi che ho implementato e testato nel mio soggiorno quotidiano. Si noti che questo volume (47 m³) è in realtà troppo piccolo perché la formula di Sabine funzioni bene. La profondità delle riflessioni è impostata a cinquanta riflessioni (il che è molto elevato nel contesto del ray-tracing).

AlgoritmnamnmaxHitrate%ExekveringstidEllipsoidapproximering0.16hPrimalRaytracing2.88hNosqarerootsRaytracing2.87hPrecalc.NormalPlanes(PNP)Raytracing2.84hDiffusePNPRaytracing9.24hHeuristicDiffusePNPRaytracing54.512min!!!\begin{array}{l|c|c} \hline Algoritmnamn & max Hitrate \% & Exekveringstid \\ \hline Ellipsoidapproximering & 0.1 & 6 h \\ Primal Ray-tracing & 2.8 & 8 h \\ Nosqareroots Ray-tracing & 2.8 & 7 h \\ Precalc. Normal Planes (PNP) Ray-tracing & 2.8 & 4 h \\ Diffuse PNP Ray-tracing & 9.2 & 4 h \\ Heuristic Diffuse PNP Ray-tracing & 54.5 & 12 min !!! \\ \hline \end{array}

Tutti questi algoritmi hanno prodotto risposte simili. Inoltre, il campionamento del mio soggiorno con un semplice applauso ha dimostrato di essere coerente (almeno inizialmente) con le risposte all'impulso calcolate. Considerando le approssimazioni grossolane che siamo costretti a fare, i risultati ottenuti sono relativamente accettabili.

Cut & Paste Ray-tracing

Infine, questo approccio audace e non scientifico (se lo consideriamo puramente dal punto di vista matematico). Si noti che non è necessario calcolare oltre Tr (il tempo di ingresso della riverberazione), poiché la riverberazione non è considerata una sorgente sonora distinta. Quello che possiamo fare è lasciare che i raggi seguano le riflessioni precoci (Cut), e successivamente sintetizzare le riflessioni tardive utilizzando queste ultime (Paste). Il modo più semplice per farlo è traslare il "Cut" al tempo successivo all'ultima riflessione calcolata nel "Cut". Le riflessioni traslate sono accompagnate da una modulazione temporale applicata mediante una funzione appropriata: questi costituiscono il contributo "Paste". La modulazione temporale può essere pre-calcolata sulla base di modelli esistenti o di misure probabilistiche ben definite. Si osservi che la riverberazione non deve essere calcolata in questa fase, poiché l'accuratezza diminuisce con la lunghezza della traccia dei raggi e vengono effettuati calcoli inutili. La riverberazione non richiede un'alta precisione, poiché è indistinta.

Poiché desideriamo ottenere feedback in tempo reale negli ambienti VR audio-mediali, il metodo Cut & Paste Ray-tracing sembra essere l'unico in grado di avvicinarsi a una possibile soluzione. In combinazione con il ray-tracing euristico, possiamo ottenere con mezzi limitati qualcosa che ricorda un primo passo verso la definizione forte di VR. Ciò è possibile riducendo il requisito di velocità di calcolo in tempo reale da fS volte/s a fDIRAC volte/s. In linea con il concetto di "spaciousness", fDIRAC deve essere circa 8000 Hz per riprodurre completamente la direzione del suono incidente.

Implementazioni esistenti

Le varie implementazioni circolanti sono il metodo delle immagini speculari [32, 33], il ray-tracing [34], ibrido [35, 36], euristico [37] (si noti che questo è un modello esclusivamente all'aperto) e il metodo degli elementi finiti [31]. Queste sono varianti più o meno avanzate di quelle brevi introduzioni che ho scritto. Tuttavia, tutte queste sono molto limitate e richiedono ulteriore hardware come periferiche.

Approssimazione della riverberazione

This is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning.

Sir Winston Leonard Spencer Churchill

In questa sezione descrivo diversi modi per stimare e calcolare la riverberazione senza dover effettuare un ray-tracing approfondito con una bassa percentuale di hit come risultato. Esistono due metodi di approssimazione: il primo è deterministico e il secondo è stocastico (il confine tra questi è sfumato). Non ho implementato completamente queste idee perché sono troppe, anche se relativamente semplici.

Poiché ho stabilito l'algoritmo euristico di ray-tracing come base, approssimeremo la risposta all'impulso dal tempo Tr al tempo T60T_{60} (la stessa cosa vale per il metodo delle immagini speculari). La base di questo è che richiediamo campi sonori più diffusi man mano che consideriamo riflessioni più profonde. Il problema consiste nel determinare Tr in modo tale che tutte le riflessioni prima di Tr siano distinte, mentre quelle successive siano sovrapposte all'interno di determinati intervalli temporali discreti. Se ignoriamo la legge della prima onda frontale, non dovremmo avere un campo sonoro diffuso (nella natura reale non esistono campi sonori completamente diffusi), e ciò implica che non dobbiamo effettuare un ray-tracing profondo. Tipicamente si utilizzano le riflessioni di terzo ordine, e questo è un'approssimazione qualitativa non dimostrata. Tuttavia, si noti che il tempo Tr è fortemente dipendente dal modello e, in senso puramente euristico, non possiamo generalizzare la precedente stima.

Metodi Deterministici

La riverberazione stessa è in realtà un filtro dipendente dal tempo che colora il segnale in un modo distintivo. Se esaminiamo le sale di ascolto già esistenti e ne confrontiamo l'aspetto della riverberazione, risulta che seguono la stessa struttura. Combinando questo fatto con il carattere indistinto della riverberazione, possiamo utilizzare una riverberazione già campionata. Questa idea è realizzabile solo se sappiamo che il modello è una sala. Dal punto di vista VR, questo metodo offre grandi capacità di generalizzazione, e siamo costretti a riformulare la riverberazione mediante funzioni appropriate. Queste funzioni appropriate possono essere una combinazione di numerose riverberazioni note in forma più o meno lineare. Il problema si riduce a individuare i limiti delle strutture di riverberazione e un numero ben bilanciato di varianti intermedie, che possono essere miscelate in modo tale che il modello rientri nell'ambito corretto.

Metodi stocastici

Un'estensione dei metodi precedenti consiste nell'utilizzare le riverberazioni campionate e le riflessioni precoci calcolate per formare la riverberazione del modello. Questo calcolo deve essere eseguito una sola volta, poiché la riverberazione è sostanzialmente indipendente dalla posizione degli oggetti. Si tratta tuttavia di un'approssimazione, poiché il tempo di ingresso della riverberazione (Tr) non è indipendente dalla posizione degli oggetti.

Inoltre, possiamo applicare una variante stocastica completa che costruisce la funzione di riverberazione utilizzando i seguenti parametri: le prime riflessioni, il numero di oggetti nel modello, il tempo di riverberazione T60T_{60} e l'intensità dell'attività di movimento. Il tempo T60T_{60} determinerà la dimensione della riverberazione. Il numero di oggetti e l'intensità dell'attività di movimento determinano quanto la riverberazione risulti indistinta. Inoltre, l'intensità dell'attività di movimento può essere seguita da una funzione stocastica (più efficace e semplice, basata su un processo stocastico appropriato) o da una funzione deterministica (più lenta e complessa, basata sugli schemi di movimento degli oggetti) per modificare la possibile dipendenza della riverberazione dalla posizione degli oggetti.

Due immagini schematiche dell’approssimazione della riverberazione, dove D indica la variante deterministica e S la variante stocastica. La croce indica che le due funzioni (eventualmente più di due) operano scalarmente l’una sull’altra per il calcolo della risposta all’impulso. La doppia croce indica che le due funzioni (eventualmente più di due) operano stocasticamente l’una sull’altra per la sintesi della riverberazione.

Auralizzazione

So gelangt man beim Philosophieren am Ende dahin, wo man nur noch einen unartikulierten Laut ausstossen möchte.

Ludwig Wittgenstein

Nella ray-tracing grafica, è estremamente semplice visualizzare singole immagini che mostrano l'aspetto del modello. Tuttavia, quando si tratta di ray-tracing acustico, la visualizzazione grafica non è altrettanto efficace. Può essere piacevole osservare la risposta all'impulso della stanza o singoli gruppi di energia che si propagano nell'ambiente. Ma rappresentare la propagazione del suono con immagini è un po’ come cercare di descrivere un suono a una persona con sordità congenita (estremamente difficile). In realtà, si tratta di una mappatura scadente, poiché vediamo ciò che vorremmo sentire. In conformità con la forte definizione di VR e i rigorosi requisiti dell'interazione uomo-computer per una buona mappatura, ciò implica che dobbiamo auralizzare (Eng. Auralization). Se volessimo mantenere la coerenza linguistica, l'auralizzazione dovrebbe chiamarsi "audializzazione", ma coloro che hanno percorso questa strada in precedenza si sono attaccati al concetto di auralizzazione.

Per la lettura successiva, richiedo che il lettore abbia letto "Aspetti computazionali dell'audio digitale" in "Elaborazione audio", e farò riferimento a questa sezione con [BDA].

Il grande carico computazionale dimostrato in [BDA] (nonostante algoritmi non ancora sviluppati) implica che, senza una certa ingegnosità, non possiamo auralizzare su un comune microprocessore. Il problema è già presente nell'algoritmo di ray-tracing. Tuttavia, possiamo implementarlo con un'euristica rapida che tenga conto della direttività dell'orecchio, del mascheramento e della non linearità (curve phon). Questo, unito al fatto che seguiamo i raggi solo fino alle riflessioni di terzo ordine, ci consente di costruire la prima parte della risposta all'impulso del modello in tempo reale (25 volte al secondo).

E allora? E l'auralizzazione? Poiché ci occupiamo di un computer con una potenza di calcolo estremamente limitata, non andremo lontano con l'auralizzazione. Amiga ha un audio a 8 bit con quattro canali in stereo (due per ciascun orecchio), e il volume di ciascuna canale (voce) può essere regolato su 64 livelli diversi (distribuiti in modo logaritmico). Il livello più basso corrisponde a un'attenuazione del segnale di 36 dB, il che ci consente di costruire una risposta parziale all'impulso in un dato intervallo temporale con 64 riflessioni sonore. Questo è calcolato in conformità con la formula 1 in [BDA]. Ciò implica che non è necessario calcolare più di 64 riflessioni per ciascun orecchio. L'algoritmo euristico di tracciamento dei raggi difficilmente diventerà più lento a causa di questo limite.

Perdendo la pazienza! E cosa ne è dell'auralizzazione?

In linea con l'argomentazione in "Approssimazione della riverberazione" e i primi due capitoli, ciò implica che non abbiamo bisogno della piena qualità offerta dalle convoluzioni di campionamento Dirac. Pertanto, possiamo approssimare la riverberazione con un reverb adeguato, disponibile in numerose varianti nel contesto musicale. L'unico requisito è che debba supportare MIDI (Musical Instrument Digital Interface) affinché possiamo modificare esternamente i parametri principali, T60T_{60} e diffusione della riverberazione. La soluzione consente all'utente di determinare autonomamente la qualità dell'approssimazione della riverberazione. Questa soluzione costituisce inoltre un naturale prolungamento del concetto Amiga (lascia che i processori specializzati svolgano il lavoro grezzo). Di seguito sono riportati l'algoritmo e un piano di flusso hardware.

    Denis Tumpic's Heuristic Auralizer-Ray-tracer Code:

Definition Max length:
Computed reverberation time with Sabine's formula
multiplied with the soundvelocity through air.

Definition Max rays:
Total number of additions without cancellations.

Definition Hit object:
An object that mostly reflects rather than diffracts
soundrays.

Definition Transceiver:
Objects that transmits (loudspeaker) or receives (ear)
sound.

Definition Hit point:
Ray impact area on hit object.

Definition Clean hit:
When the ray-tracing cone hits a specific hit object or
transceiver.

Definition Looking range:
Circular cone that spreads(¶/2) from the hit point with
the direction of specular reflection.

Definition Diffuse hit:
When the path from ray-trace hitpoint to transceiver
surface is in the lookin grange and free from hit ob
jects.

Definition Trace hits:
The calculated impuls response from the Ray Trace algo
rithm.

Master (Realtime V:input sampligfrequency) function Auralizer:
First time:
Compute reverberation time with Sabins's formula.
Initialize extern reverb through MIDI system messages.
Allways (Isochrone \& Parallel):
Convolv incomming data with Trace hits.
Output convolution to audiochannels.

Master (Parallel Pseudoprobabilistic Heuristic) function Trace:
Iterate over ray directions that point onto objects.
Ray-trace until:
Transceiver hit or
Raylength exceeds Max length or
Total Rays exceeds Max rays.
When detected a clen hit memorize:
Decay time and attenuation.

Slave (Recursive and Iterative Heuristic) function Ray_Trace:
Compute nearest possible Hit object and reflect ray specu
larly through the new Hit point.
Compute nearest possible Hit object.
Multiply this Hit objects absorptionresponse with:
Previous absorptionresponse in this recursion.
When Diffuse hit detected:
Damp ray then memorize:
Decay Time and attenuation.
Increase Total Rays.
End recursion.
Depending on depth and grade of diffusion:
smash ray into several directions and recurse.

Questa immagine mostra lo schema hardware dell'algoritmo di auralizzazione. Il microfono può essere sostituito da un DAT (Digital Audio Tape) che riproduce una registrazione precedente effettuata in una stanza anecoica.

Struttura dei dati

Gli insiemi totalmente dinamici sono la chiave di tutto.

In questa sezione descrivo e commento alcune parti delle strutture dati aperte del programma. Iniziamo innanzitutto con alcuni tipi enumerativi.

Il seguente tipo viene utilizzato per identificare gli oggetti durante i vari calcoli:

    /*****************************
* What type of object is it? *
*****************************/
enum ObjectType {Furniture,Sender,Receiver};

Gli oggetti modello primitivi sono suddivisi nelle seguenti unità:

    /**************************************
* What type of primitiv object is it? *
**************************************/
enum PrimitivObject (Tetraeder, Cube, Octaeder, Prism, Room, Pyramid, Plate};

La direttività ha il seguente tipo enumerativo:

    /**************************************************
* Propagation Directivity for objects in general. *
**************************************************/
enum DirectionType {Omni,Bi,Cardioid};

Poiché ci occupiamo di pozze, utilizzo liste doppio collegate (in realtà superflue a una prima occhiata, anche se i tempi di ricerca possono essere facilmente ridotti della metà). La struttura riportata di seguito è specifica per le caratteristiche dei materiali. In una futura evoluzione del programma con una struttura gerarchica completa, tutto ciò che si trova sotto i puntatori (*prev e *next) dovrà essere raccolto in una struttura (vale per la maggior parte di queste strutture). Questo è il fondamento della doppia collegamento in questa struttura. Inoltre, possiamo implementare un pulsante di ordinamento nelle finestre di coordinazione e rinominarle come "strati" (Eng. Stock). Se siamo ragionevoli, la struttura dovrà essere riformulata in un modello ad albero appropriato (in tal caso, il nome della struttura cambierà in Material<Type>Tree).

    /******************************************************
* Master struct for Material Characteristics *
* Materiallist holding all loaded \& created materials *
******************************************************/
struct MaterialList
{
struct MaterialList *prev; /*Pointer to previous in list */
struct MaterialList *next; /*Pointer to next in list */
char Name[80]; /*Material name */
int usage; /*How many objects uses this MTR */
enum GraphType GraphMode; /* Spline or linear */
enum ObjectType OType; /*Furniture, sender or receiver */
int Color; /* Draw Color (furnitures only) */
int Volume; /* Sound Volume (senders only) */
double meanabsorption; /*Material mean absorption coeff */

/*********************************************************
* Softtypeequalizer with normal equalizing frequencies *
* and extra directioncharacteristics for each frequency. *
* Frequency Absorption/Response variables *
* 32,63,125,250,500,1k,2k,4k,8k,16k,32k Hz *
*********************************************************/
int EHZ[11];

/*****************************************************
* Frequency Direction variables Omni, Bi or Cardioid *
* 32,63,125,250,500,1k,2k,4k,8k,16k,32k Hz *
*****************************************************/
enum DirectionType DHZ[11];
};

Ogni oggetto è composto da un certo numero di sottoggetti cuboidi, di tipo oggetto primitivo. Questi vengono inseriti in una lista doppio collegata (solo per mantenere la coerenza). Poiché la gerarchia completa non è stata implementata, ho collocato il materiale dell'oggetto nella struttura di modellazione. Tuttavia, in una versione successiva, questo verrà spostato in questa struttura. I valori dell'equazione del piano (calcolo della riflessione speculare tramite la normale) e l'estensione delle superfici (verifica se il raggio colpisce) sono presenti qui perché hanno fornito un notevole aumento di velocità all'algoritmo di tracciamento dei raggi. Ritengo che questo incremento di velocità sia più importante dei 480 byte extra richiesti. Inoltre, il calcolo dell'area è stato spostato nella fase di inserimento (cfr. ammortizzazione del calcolo durante la modellazione), il che permette di portare i calcoli tramite la formula di Sabine a livelli accettabili. I numerosi buffer per i vettori sono dovuti all'efficienza dell'algoritmo AOT³ e non vengono ulteriormente commentati qui (vedi Algoritmi di Trasformazione 3D).

    /*******************************************
* Struct holding all surfaces of an Object *
*******************************************/
struct SurfaceList
{
struct SurfaceList *prev; /* Pointer to previous in list */
struct SurfaceList *next; /* Pointer to next in list */
enum PrimitivObject PO; /* What type of prim object is it*/
double x[8],y[8],z[8]; /* x,y,z Rigid Coords */
double mx[8],my[8],mz[8]; /* x,y,z 1 transformed Coords */
double tx[8],ty[8],tz[8]; /* x,y,z 2 transformed Coords */
double AV[6],BV[6],CV[6],DV[6];/* Plane equation */
double maxx[6],maxy[6],maxz[6];/* Plane boundaries */
double minx[6],miny[6],minz[6];/* Plane boundaries */
double Area[6]; /* Area of the plane */
};

La seguente struttura rappresenta i nodi nelle liste di oggetti (anch'essi doppio collegati per coerenza):

    /**************************************************
* Masterstruct for a specific Object *
* ObjectList holding all loaded \& created objects*
**************************************************/
struct ObjectList
{
struct ObjectList *prev; /* pointer to prev in list */
struct ObjectList *next; /* pointer to next in list */
char Name[80]; /* Root name of an Object */
int cubes; /* Number of sub cubes */
struct SurfaceList *surfaces; /* Pointer to a surfacelist */
};

La stessa struttura di modellazione è anch'essa una lista doppiamente concatenata. Si noti che non dobbiamo implementare un intero albero di ricerca per questo, dato che i tempi di ricerca rapidi sono necessari quando l'utente seleziona un oggetto sullo schermo, poiché le rotazioni comportano il cambiamento di stato delle spille e richiedono una nuova ordinazione (si veda l'assenza di feedback in tempo reale). Tuttavia, la struttura ad albero è necessaria per l'archiviazione gerarchica. Inoltre, la posizione degli oggetti nello spazio e le loro direzioni (tre vettori unitari ortogonali) sono necessarie, ad esempio, per le modifiche di dimensione. I vettori unitari sono richiesti dalla formula computazionale dell'algoritmo AOT³ (ad esempio, la rotazione inversa durante le modifiche di dimensione). L'algoritmo di ray tracing memorizza temporaneamente la normale della superficie colpita in questo nodo, se il raggio interseca una superficie nella sua lista di oggetti. Questo è un aggiungimento derivato dalla soluzione euristica.

    /*************************************************************
* Masterstruct for a specific object in current Drawing Pool *
* DrawingList holding all objects in current drawing *
*************************************************************/
struct DrawingList
{
struct DrawingList *prev; /* Pointer to previous in list */
struct DrawingList *next; /* Pointer to next in list */
double x,y,z; /* Center of object in space */
double dxx,dyx,dzx; /* Sizing Orientation ex */
double dxy,dyy,dzy; /* Sizing Orientation ey */
double dxz,dyz,dzz; /* Sizing Orientation ez */
long int recnumber; /* Tracer receiver number */
int ax,ay,az; /* Anglegadgets real angle */
int dax,day,daz; /* Anglegadgets deviation */
double sx,sy,sz; /* Sizergadgets real size */
double dsx,dsy,dsz; /* Sizergadgets deviation */
double W,H,D; /* Width, Hight, Depth of object */
double AV,BV,CV,DV; /* Hitplane normal */
double pinx,piny,pinz; /* Pin location */
char Name[80]; /* Userspecified extra name */
struct ObjectList *object; /* Pointer to Objectdatalist */
struct MaterialList *material; /* Pointer to a material */
struct FlightList *flight; /* Pointer to a flightpath */
};

I dati di ray tracing sono inseriti in una lista doppiamente concatenata per consentire facilmente la concatenazione dei risultati computazionali provenienti da una forma parallela dell'algoritmo di ray tracing. Queste fusioni vengono utilizzate in calcoli successivi per vari criteri acustici. Durante l'auralizzazione stessa, ogni processore può completare i propri calcoli e quindi inviare la risposta al processo principale. Si noti che non abbiamo bisogno dei risultati in un ordine specifico, poiché la convoluzione viene eseguita su tutto il set di dati. Su una macchina con un singolo processore, gli array dinamici costituiscono una struttura dati più rapida per la convoluzione stessa. Si osservi inoltre che, con gli algoritmi NOMIX e MIXTHEM, i dati sono in ordine sequenziale poiché utilizziamo campionamenti.

    /**************************
* List/node of tracedata. *
**************************/
struct TraceList
{
struct TraceList *prev; /* Pointer to previous in list */
struct TraceList *next; /* Pointer to next in list */
double length,acoeff; /* Length and absorption of path */
double ex,ey,ez; /* Origin direction */
double time,amplitude; /* Realtime renderdata */
char Sname[80],Rname[80]; /* Name of sender \& receiver */
int recnumber; /* Asociated number to tracer */
};

Metodologia di programmazione

Quick and Dirty, Slow and Clean, Blade Running that's my dream.

DDT

In questo paragrafo descrivo la mia metodologia di programmazione in modo semplice e informale; chi non è interessato a un linguaggio talvolta pomposo non dovrebbe continuare la lettura. La metodologia di programmazione in sé ritengo sia estremamente importante, e spesso attribuisco grande importanza alla progettazione del codice, se c'è tempo. La maggior parte di noi ha stili di programmazione molto individuali, e nei grandi progetti sviluppati da una sola persona è fondamentale essere rigorosi e stringenti.

Possiamo riferirci a questa metodologia rigorosa come Slow & Clean Programming (SCP). Per lo sviluppo puro di algoritmi, SCP non è preferibile, poiché il programmatore si blocca sui dettagli anziché concentrarsi sul far funzionare l'algoritmo per risolvere il problema. Per testare idee, il programmatore può utilizzare Quick & Dirty Programming (QDP).

Una volta che gli algoritmi hanno superato i primi livelli di ottimizzazione, possono essere ripuliti da inutilità generali (nomi di variabili strani e simili). Esistono diversi livelli di ottimizzazione, e il primo lo chiamo ottimizzazione primaria. Questa è di natura puramente matematica e mira a ridurre eventuali calcoli superflui. Successivamente, abbiamo l'ottimizzazione secondaria, che consiste nel pre-calcolare (amortizzare) percorsi o risultati di calcolo che si ripetono costantemente. Esistono molte altre ottimizzazioni, ma queste sono quelle che devono sempre precedere uno sviluppo algoritmico più ampio. Quando disponiamo di un algoritmo ben formulato con la minima complessità computazionale, possiamo ottimizzarlo in assembler puro. Questo approccio è spesso molto costoso, se confrontato con i guadagni ottenuti tra implementazioni in diversi linguaggi di programmazione reali. I programmen tende spesso a diventare inmaneggiabili se non abbiamo una certa coerenza nel modo di descrivere le funzioni. Il metodo più comune per gestire problemi complessi consiste nel suddividere il problema in alcuni sottoproblemi. Questi sottoproblemi vengono poi ulteriormente suddivisi in sottoproblemi ancora più piccoli. Con questo approccio, continuiamo fino a quando riusciamo a risolvere i piccoli sottoproblemi. Si noti che si tratta di un algoritmo "Dividi e Vinci". Spesso i sottoproblemi sono più o meno correlati, e quelli strettamente correlati devono essere scritti in blocchi di testo contigui (completamente naturale in Simula, meno naturale negli altri linguaggi). Questi blocchi di testo sono moduli nel vero senso della parola, e io li chiamo spesso <name>handler (ad esempio ViewHandler, TraceHandler, SabineHandler). Il programma principale deve avere un nome meno criptico, che descriva in modo conciso ciò che esegue o sia un nome puramente estetico di tipo commerciale. La Figura 4.21 mostra l'immagine complessiva di come ho suddiviso il mio programma [^1].

Flussi di intercomunicazione audio 3D. La freccia doppia indica il traffico dati e la freccia singola indica le modifiche al flusso del programma. La stella indica che vengono effettuati chiamate alla modulo della funzione globale (AboutPrefsMischandler). Il completamento del calcolo in ciascun modulo porta al ritorno alla modulo degli eventi 3DAudio_events, per un'attesa passiva di nuove riconfigurazioni dell'utente.

Al momento del completamento di un modulo, esso deve essere completamente pulito e normalizzato. La normalizzazione costituisce la fase in cui il programmatore effettua una trasformazione coerente e uniforme del codice. Ciò implica che egli debba descrivere completamente le funzioni nei relativi intestazioni di funzione, mentre costruzioni più complesse devono essere brevemente descritte nei blocchi di testo adiacenti. Per il programmatore, il programma è come una grande dimostrazione matematica con definizioni e teoremi. Perché non dovremmo richiedere che i programmi siano altrettanto belli delle dimostrazioni matematiche o ben scritti come le migliori opere letterarie? La pagina successiva mostra la mia struttura di normalizzazione, e il layout è tratto dallo standard Amiga-Autodocs.

    /****** <Handler name> **************************************
* *
* NAME *
* <Function name> -- <Small description> *
* *
* SYNOPSIS *
* <Function name> ( <parameters> ) *
* *
* FUNCTION *
* <Big description> *
* *
* INPUTS *
* <Parameter description> *
* *
* RESULT *
* <Computed data description> *
* *
* EXAMPLE *
* Just necessary if it is a Global or Child function. *
* *
* NOTES *
* Type of function: *
* <Global, Master, Slave or Child> *
* ( <Realtime V:<velocity> > <Isochrone> *
* <Parallel or Sequential> *
* <Iterative, Recursive <Bottom upp or Top down>, *
* Input/Output or Event> *
* <Monte Carlo, Las Vegas, Pseudoprobabilistic or *
* Deterministic> *
* <Depth first, Width first, Greedy or Heuristic>) *
* function *
* <Function name>_<Nearest Parent name> *
* *
* BUGS *
* <Known bugs or logical missconditions> *
* *
* SEE ALSO *
* <This functions Global, Slave and Child calls> *
* *
* *
*************************************************************
*
*/
<Function name> ( <parameters> )
{
<Definitions>
Konstants have big first letter.
Descrete variables are i,j,k ...
Continous variables are x,y,z ...
Array variables are A[],B2[][],C3[][][]...
Pointers have big first letter and the type of data
structure with the leading characters as a suffix.

Suffixes are: <Oneway, Double, Circular or Vien> List,
<Binary, B- or <specialls>> Tree,
<Plain, Binomial or Fibonacci> HEap,
<Open, Chaining or Universal> HAshing ...

Initiatus <pseudoconstants, script or graphics>
<Itera or Recursiva> Computa
or
Redirection of programflow.

<Function return>
}

Queste cose sono banali quando il codice ha meno di cento funzioni. I grandi problemi solitamente hanno molte più funzioni, e credetemi, non diventa banale quando dobbiamo normalizzare questi programmi. A volte può essere difficile trovare l'ottimo per il percorso di implementazione più veloce — specialmente quando il programmatore è stato nella fase QDP per molto tempo, questi problemi emergono. Spesso, grazie all'esperienza precedente, si riesce a percepire questo "punto". Tutti possono programmare, ma solo i migliori programmatori riescono a bilanciarsi su questo equilibrio. Se questo progetto sia o meno un'implementazione veramente ottimale, lascio questa domanda aperta a chi non è un informatico. Personalmente ritengo che l'implementazione sia stata troppo lenta, e ciò deriva dalle versioni leggermente più complesse delle funzioni che mi sono imposto di realizzare al servizio della scienza (e non me ne pento).

Conclusioni

Quando ho iniziato questo progetto, speravo che ci fosse un po' di materiale disponibile su questi problemi, per ampliare nel modo più ampio possibile la mia prospettiva. Ho ottenuto quanto desideravo in misura considerevole. Anche se la biblioteca universitaria (UB2) possiede un gran quantitativo di materiale e ho ricevuto alcuni nomi preziosi dal mio supervisore, si è rivelato che quattro settimane di approfondite ricerche erano necessarie per reperire materiale rilevante. Di solito, la quantità di informazioni esplode quando si trovano alcuni indizi, ma in questo caso non è stato così. Sembra che un gran numero di scienziati che si occupano di ray-tracing audio riconoscano l'impasse della situazione e lascino il problema alle generazioni future, dotate di computer più potenti. Questo va confrontato con il ray-tracing video, dove esiste un numero molto più elevato di "seguaci".

Anche se l'Amiga non ha la stessa potenza computazionale di varie workstation, desidero sottolineare che la potenza della CPU non è tutto. Le implementazioni funzionali apparentemente artificiose che a volte mi sono costretto a scrivere non avrebbero mai visto la luce su altri sistemi, poiché il livello di frustrazione per l'inefficienza degli algoritmi era talvolta insopportabile. Tenendo conto di ciò, un'interfaccia grafica lenta sarebbe stata una grande barriera e mi avrebbe impedito di concentrarmi sulla programmazione e sugli algoritmi specifici. La scelta del computer e del linguaggio di programmazione si è quindi rivelata una buona decisione. Tuttavia, per realizzare i calcoli in tempo reale, è necessario un "Iris Crimson" (una macchina SGI).

Il mio lavoro di laurea nel contesto generale. "Inter Gigantica Galactica" (IGG) è l'ambiente VR perfetto, in cui l'utente potrà fare e vivere tutto, secondo la definizione rigorosa di VR.

Si dice spesso che un problema richiede almeno il doppio del tempo previsto inizialmente per essere risolto. Ciò dipende molto dall'ambizione e dalla visione che si includono. Quando le visioni superano l'ambizione, ci vorrà molto più tempo. In questo caso, la mia visione è molto più ampia della mia ambizione. Anche se questo è un fatto, non deve in alcun modo essere interpretato come un segno che la mia ambizione fosse mediocrer. Coloro che desiderano iniziare a risolvere il problema dell'audio ray tracing possono richiedere di accedere a "The Making Of 3D-Audio so far" e vedere cosa potrebbe eventualmente aspettarli.

3D-Audio instruction manual

What is 3D-Audio

This program is a simple but fast audio-ray-tracer, with a semiprofessional three dimensional editor as a base for human-computer interaction. It has been developed on the Amiga line of computers and thus works, at the moment, only on these machines. Recent virtual-reality hysteria and the vast amount of video-ray-tracers on these machines, gave Me the idea of making this piece of software, as a prologue to the strong definition of VR (my own). Most parts of the program are profound, but a warning to those with small sized memories when ray-tracing. I am not checking if there is enough memory when starting the ray-trace session, and thus could make the computer hang, when the vast amount of ray-tracing hits are found and stored.

What it isn't

As for the most audio-ray-tracers there are some limitations, and thus it can't be used in predicting the room model impulse response without having the following facts in mind.

(1) The emitted sound is strongly quantized in direction, due to the heuristic function.

(2) All model surfaces are plane and smooth.

(3) Specular reflections and angle-independent absorption are assumed.

(4) Energy addition is assumed.

(5) Discontinuities at the edges are discarded.

(6) Diffraction, Dispersion, Resonance and Refraction isn't implemented yet.

(7) Partially diffuse sound field is assumed.

Installing the Software on Hard-drive

(0.1) If you don't have an Amiga computer, then you have to go and purchase one, or else go to 1.1

(0.2) Follow the hardware set-up and install the system disks. Go to 1.2

(1.1) Turn the computer on.

(1.2) Find a suitable place where you want the software, and make a New Drawer there.

(1.3) Insert 3D-Audio disk in any drive and double click at the disc icon.

(1.4) Multiselect the six drawers and the main program, and drag them to the New Drawer.

(1.5) Click once at the program icon and request information about the program.

(1.6) Change screen resolution to your preference in the Tool Types list.

(1.7) Double click at the program icon and way you go.

Happy modelling!!!

Main Editing Windows

The two editing windows are the "3D View & Edit" window (VE) and the "Drawing Pool" window (DP). Moving, resizing and turning objects are done by operating gadgets in VE. Additional gadgets in VE are for model purposes that relate to the object size/position, viewpoint, perspective and the grid. Inserting new objects and changing old ones are done by operating gadgets in DP. The following two pictures shows what each gadget does, and I urge the user to open the test model and play around with it.

Questa è la finestra principale di modifica di 3D-Audio. Con i controlli a cursore dell'asse X, Y e Z puoi ruotare il modello in qualsiasi prospettiva. I piccoli pulsanti di ripristino, posizionati alle estremità di questi cursori rotativi e visualizzati come piccoli O, posizionano la manopola di rotazione al centro. Con il gadget del ciclo "Measure" puoi cambiare il sistema di misura da metri a piedi e viceversa. Con il gadget del ciclo "Grid Size" puoi modificare le dimensioni della superficie di base.

Questa è la finestra di coordinazione del modello, in cui sono elencati tutti gli oggetti visibili nel modello. Attivate il pulsante "Nuovo..." quando volete inserire un nuovo oggetto nel modello. L'eliminazione di un oggetto errato o non necessario viene eseguita con il pulsante "Elimina". L'assegnazione di materiali e voli viene effettuata con il pulsante "Seleziona..." appropriato allo stesso livello. La definizione di un oggetto dal modello esistente viene effettuata con il grande pulsante "Disegna->Oggetto...". Selezionando un oggetto specifico in questo pool e premendo un tasto Maiuscole, si mantiene quell'oggetto in modalità di modifica. Questa funzione è molto utile quando i pin degli oggetti sono raggruppati e non è possibile selezionare l'oggetto appropriato in "Vista 3D e Modifica".

Objects, Materials, Flights & Characteristics

When pressing "New..." or "Select..." gadgets in DP one of the following requester windows will appear on the screen. The "Object Pool" window handles the object fetch table, the "Material Pool" window (MP) handles the material fetch table and the "Flight Pool" window handles the objects morphing and flight path fetch table, and this end of the program is not yet fully implemented, and thus have no effect on the traced data.

Questa figura mostra i tipi di richiedenti che appaiono quando si invocano diverse funzioni nella finestra di coordinamento del modello. È necessario selezionare l'oggetto, il materiale e il volo appropriati in questi widget dell'elenco delle richieste e premere il pulsante "Ok!", se tutto è corretto. Altrimenti, bisogna premere il pulsante "Annulla", così il flusso del programma torna indietro al momento precedente all'errore.

When pressing "New..." or "Edit..." gadgets in MP the "Characteristics" requester window appears on the screen. This window handles the entities of a specific material, and it's properties are visualized in the following picture.

La definizione del materiale viene effettuata nella finestra "Caratteristiche", che è una sottoscheda della finestra di coordinamento dei materiali, dopo aver attivato il pulsante "Nuovo..." o "Modifica...". La denominazione viene facilmente eseguita tramite l'elemento di input "Nome", mentre il tipo di oggetto viene selezionato tramite l'elemento a rotazione "Tipo". La risposta in frequenza o la curva di assorbimento viene modificata a mano libera all'interno della casella del grafico, con il pulsante sinistro del mouse premuto. Le caratteristiche direzionali vengono attivate o disattivate tramite i pulsanti radio posizionati sotto ogni ottava di frequenza.

Computed Data

When you reach the stage of tracing the model, the "Computed Data" window gets active. If it's active the mouse pointer shows a clock. This indicates that the computer is calculating the reverberation times with Sabine's formula, and afterwards, that the ray-tracing has begun. While the computation commences, the echogram, at the bottom of the window, shows the computed ray hits. The reverberation distribution is visualized at the upper right corner, and you can - when computation is finished - change the air relative humidity, with the cycle gadget under the reverberation distribution.

La finestra dei dati elaborati che viene attivata all'inizio del tracciamento. Dopo la sessione di elaborazione, il tasso di colpi viene visualizzato nel gadget "tempo rimanente all'inondazione". Dopo una sessione di elaborazione, è possibile selezionare un ricevitore specifico con il gadget ciclico "Ricevitore". Ciò comporta la visualizzazione di un ecosgramma della risposta dell'ambiente nella zona circostante quel ricevitore.

Preferences

I have implemented a preference window to make modelling life easier. Here you can change the location path - mass storage location - for each model type (e.g. models, objects, materials and flights) and the traced data. Furthermore you can change the screen colors as in the workbench palette-preferences. The following picture shows this window.

La finestra delle preferenze deve essere aperta quando si verifica un cambiamento temporaneo del disco - solitamente durante il download massivo da un altro modello - o quando si desidera installare il software, impostando i percorsi delle directory e i colori dello schermo.

As usual the "Project" menu is at the left most position and it has the following properties visualized in the following picture.

Quando devi aprire, unire o salvare quei disegni, oggetti, materiali, voli e dati tracciati che crei, devi selezionare la funzione appropriata nel menu "Progetto".

The "Editing windows" menu has the effect of placing the respective window front most.

Se non si dispone di un monitor grande (ad esempio, HIRES invece di SUPERLACE è scritto sull'icona del programma principale - richiamata con il tasto destro di Amiga I, quando si fa clic sull'icona - elenco dei tipi di strumento), questo menu diventa molto utile.

The "Tracer" menu have all the parameters associated to the accuracy of the ray-tracer algorithm, and the initiation of tracing is also done here.

Il menu "Tracer" contiene tutti i parametri associati all'algoritmo di ray-tracing. Questo è solo l'aspetto in fase beta e l'interfaccia è soggetta a modifiche senza preavviso. Per ottenere la versione più recente e più user-friendly di questa funzionalità (attivazione/disattivazione dei parametri), è necessario attendere la release 2.

The "Miscellaneous" menu have, amongst other things, the Undo stack clearance functions. If you run out of memory, after a while modelling, you have probably many things in these undo stacks. This is because the computer remembers all deletion within the respective model type.

Questo menu gestisce gli stack di annullamento e l'apertura della finestra "Preferenze".

Data Files

Each of the model types can be edited in a normal text editor. All though it isn't recommended that a novice user should mess in these files, an expert user could have some fun with them. She can, amongst other things, create new primitive objects in this way. The following lists shows the file formats associated with 3D-Audio software.

WARNING!!!

Users that input false data format, could make the program calculate very strange things, and it is very important that she knows what she is doing. I have no responsibility if the computer goes berserk, or some "new" acoustical phenomena are encountered.

Drawing File Form

File form:

        $3D-Audio_DrawingHeader
# <number of objects> <Magnification 1-10000> <Perspective 1-250> <Measure: 0=Meter, 1=Feet, 2=Off> <Grid Size 0-11 (0=Big 11 Small)>
$<Object #n model name>
#<Object #n><origo XO, YO, ZO>
<eigen vectors XE, YE, ZE><size XS,YS, ZS>
$miniOBJHYES
Remark: $miniOBJHNO and discard the following if no object data is present.
$ <Object #m primitive name>
# <number of primitive objects>
# <Special primitive #> <Eight x,y,z coordinates>
0: Tetrahedra
1: Cube
2: Octahedra
3: Prism
4: Room
5: Pyramid
6: Two dimensional plate

$miniMATRHYES
Remark: $miniMATRHNO and discard the following if no material is assigned.
$ <Material name>
# 0 <type of source> 0 0
0: Furniture
1: Sender
2: Receiver
Remark:Frequencies (Hz): 32 63 125 250 500 1k 2k 4k 8k 16k 32k
# <Eleven absorption coefficients ranging from 0 to 100>
# <Eleven directivity numbers at above stated freq.>
0: Omnidirectional
1: Bicardioid
2: Cardioid
$miniFLGHNO
Remark: Not implemented.

Example:

            $3D-Audio_DrawingHeader
#1 9711 231 0 5
$Big Sofa
#0.040670 0.171643 0.656502 1 -0.001465 0.000168 0.001466 0.999994 -0.003108 -0.000164 0.003108 0.999995 67 92 99 $miniOBJHYES
$Big Sofa
#4
#1 -1.378665 -0.251693 0.281572 1.341315 -0.250144 0.273905 1.341489 0.251856 0.273736 -1.378491 0.250308 0.281404 -1.378989 -0.251859 -0.218429 1.340991 -0.250311 -0.226097 1.341165 0.251690 -0.226266 -1.378815 0.250141 -0.218600
#1 1.345374 0.259635 0.275123 1.478653 0.259711 0.274748 1.478686 0.357711 0.274715 1.345407 0.357636 0.275090 1.345049 0.259469 -0.224880 1.478328 0.259545 -0.225255 1.478362 0.357545 -0.225288 1.345084 0.357469 -0.224912
#1 -1.525151 0.240771 0.279624 -1.391872 0.240847 0.279249 -1.391839 0.338847 0.279215 -1.525117 0.338770 0.279591 -1.525478 0.240603 -0.224378 -1.392198 0.240679 -0.224754 -1.392165 0.338679 -0.224787 -1.525444 0.338602 -0.224412
#1 -1.394825 0.222433 0.385671 1.325155 0.223981 0.378003 1.325443 0.809575 0.508692 -1.394537 0.808027 0.516360 -1.394881 0.244214 0.288071 1.325099 0.245763 0.280403 1.325387 0.831357 0.411093 -1.394593 0.829808 0.418760
$miniMATRHYES
$Skin
#0 0 0 0
#8 10 7 12 25 30 29 31 40 45 44
#1 1 1 1 1 1 1 1 1 1 1
$miniFLGHHNO
Objects File Form

File form:

        $3D-Audio_ObjectsHeader
# <number of objects>
$ <Object #n primitive name>
# <number of primitive objects>
# <Special primitive #> <Eight x,y,z metric coords.>
0: Tetrahedra
1: Cube
2: Octahedra
3: Prism
4: Room
5: Pyramid
6: Two dimensional plate

Example:

            $3D-Audio_ObjectsHeader
#1
$Cube
#1
#1 -1 -1 1 1 -1 1 1 1 1 -1 1 1 -1 -1 -1 1 -1 -1 1 1 -1 -1 1 -1
Materials File Form

File form:

        $3D-Audio_MaterialsHeader
$ <Material name>
# 0 <type of source> 0 0
0: Furniture
1: Sender
2: Receiver
Remark:Frequencies (Hz): 32 63 125 250 500 1k 2k 4k 8k 16k 32k
# <Eleven absorption coefficients ranging from 0 to 100>
# <Eleven directivity numbers at above stated frequencies>
0: Omnidirectional
1: Bicardioid
2: Cardioid

Example:

            $3D-Audio_MaterialsHeader
#1
$Black Hole 100%
#0 0 0 0
#100 100 100 100 100 100 100 100 100 100 100
#0 0 0 0 0 0 0 0 0 0 0
Trace Data File Form

File form:

     $3D-Audio_ForwardTraceHeader or $3D-Audio_BackwardTraceHeader
#Number of trace hits
#<Ray density><Reverberation accuracy><Specular depth><Diffusion accuracy><Diffraction accuracy><Frequency accuracy><Mean reverberation time in seconds><Max Number Of Receivers>
Remark: Accuracy: 0.00 to 1.00 are Manual values -1.00 initiate Auto state.
Density, Depth & Max number: Integer values
Seconds: Float value.
Remark: Entries at frequencies (Hz): 32 63 125 250 500 1k 2k 4k 8k 16k 32k
# Frequency dependant reverberation times, 11 entries at 40% R. hum.
# Frequency dependant reverberation times, 11 entries at 50% R. hum.
# Frequency dependant reverberation times, 11 entries at 60% R. hum.
# Frequency dependant reverberation times, 11 entries at 70% R. hum.
#<Ray length in meters><Accumulated absorption coefficient><Receiver number>
# Directivity eigen vectors XE, YE, ZE
$Sender Name
$Receiver Name

Example: These data should not be manually edited, even if you know what you are doing!!!

Preferences File Form

File form:

        3D-Audio_Preferences_file.
Drawings Path
Objects Path
Materials Path
Flights Path
Trace Path
Remark: Color numbers 0-7, RGB values 0-15, Seven entries!
<color number> <Red value> <Green value> <Blue value>
Remark: For further expansions only, don't change manually.
0 0 0 0

Example:

            3DAudio_Preferences_file.
Work Harddisk:C Prg/Sound Tracer/Drawings
Work Harddisk:C Prg/Sound Tracer/Objects
Work Harddisk:C Prg/Sound Tracer/Materials
Work Harddisk:C Prg/Sound Tracer/Flights
Work Harddisk:C Prg/Sound Tracer/Traced_Data
0 13 8 6
1 0 0 0
2 15 13 9
3 14 11 8
4 15 0 0
5 0 15 0
6 0 0 15
7 15 15 15
0 0 0 0

Spiegazioni dei termini, definizioni, ecc.

Assorbimento additivo

Sia il fascio energetico riflesso dalle superfici {xi;i=1,2,...,n}\{x_i; i=1, 2, ..., n\} con
rispettivi coefficienti di assorbimento dipendenti dalla frequenza
{αi(f);i=1,2,...,n;f=[20..20000]Hz}\{\alpha_i(f); i=1, 2, ..., n; f=[20..20000] Hz\}; allora l'assorbimento totale sarà il seguente:

α(f)=1Π(1αi(f))\alpha(f)=1-\Pi(1-\alpha_{i}(f)) {i=1,2,...,n}\{i=1, 2, ..., n\}

Chiarità

g(t)g(t) è la risposta all'impulso della stanza.

C=10log100ms80ms[g(t)]2dt80ms[g(t)]2dtC=10\log_{10}\frac{\intop_{0ms}^{80ms}[g(t)]^{2}dt}{\intop_{80ms}^{\infty}[g(t)]^{2}dt}
dB

Deutlichkeit (Definizione)

g(t)g(t) è la risposta all'impulso della stanza.

D=050ms[g(t)]2dt0ms[g(t)]2dtD=\frac{\intop_{0}^{50ms}[g(t)]^{2}dt}{\intop_{0ms}^{\infty}[g(t)]^{2}dt}
100%

Impulso di Dirac

Definizione:

(1) δ(t)=0,\delta(t)=0,t0,δ(0)=+\neq0,\delta(0)=+\infty

(2) δ(t)dt=1\intop_{-\infty}^{\infty}\delta(t)dt=1

(3) δ(t)=δ(t)\delta(-t)=\delta(t) (δ\delta è pari)

(4) δ(ta)=aδ(t),a>0\delta(\frac{t}{a})=a\delta(t),a>0

(5) Θ(t)=δ(t),ddtsgn(t)=2δ(t)\Theta'(t) = \delta(t), \quad \frac{d}{dt} \operatorname{sgn}(t) = 2\delta(t)

Disgiunto

Abbiamo due insiemi A e B che non hanno elementi in comune.

AB=A\bigcap B=\emptyset

Dinamica

I è la larghezza di banda informativa in numero di bit.

Dynamik=20log10(2)IDynamik=20\log_{10}(2) \cdot I dB

Spiegazione della dinamica

Lo spostamento a sinistra di un valore binario di un passo comporta
un raddoppio del valore. Secondo la definizione di decibel, ogni bit vale
10log10(22)10\log_{10}(2^{2}) dB. Questo fornisce la formula.

Distribuzione dell'energia nella stanza

Q: è la potenza acustica della sorgente isotropica.

I(r)I(r): è l'intensità energetica, a r metri dalla sorgente sonora.

SiS_i: è l'area totale di assorbimento di una superficie specifica.

aia_i: è il coefficiente di assorbimento di una superficie specifica.

N: è il numero di superfici nella stanza.

R=αiSi(1αi)1R = \sum{\alpha_i}{S_i(1-\alpha_i})^{-1} {i=1,2,...,N}\{i=1, 2, ..., N\}

I(r)=Q((4πr2)1+4/R)I(r) = Q \cdot ((4{\pi}r^2)^{-1}+4/R)

Propagazione dell'energia

Q è la potenza acustica della sorgente isotropica.

I(r)I(r) è l'intensità energetica, a r metri dalla sorgente sonora.

I(r)=Q4πr2I(r) = \frac{Q}{4{\pi}{r^2}}

Convoluzione

Definizione: Il campionamento di Dirac è una sequenza discreta con la seguente forma: F={fi:i=[0..n1]}F=\{f_i:i=[0..n-1]\}

I dati in ingresso sono una sequenza discreta con la seguente forma: S={sj:j=[0..n1]}S=\{s_j:j=[0..n-1]\}

L'insieme F è statico, ma S è dinamico e cambia in ogni istante di campionamento i suoi elementi sj+1=sj, partendo da sn-1. L'ultimo dato campionato è s0 e si noti che:

n=fDIRACT60n=f_{DIRAC} \cdot T_{60}

poiché non è necessario convolvere il risultato oltre la lunghezza del campionamento di Dirac. La convoluzione di F e S diventa allora:

C=f0s0+f1s1+...+fn1sn1C=f_0 \cdot s_0+f_1 \cdot s_1+ ... + f_{n-1} \cdot s_{n-1}

Questo richiede n moltiplicazioni e (n-1) addizioni. Per semplicità e chiarezza, dico che richiede n operazioni/istante di campionamento (op significa che viene eseguita un'addizione più una moltiplicazione).

IOUTI_{OUT}

I è la larghezza dei dati informativi. S è il numero di termini (oggetti produttori di suono).

IOUT=IIN+Ceil(log2(S))I_{OUT}=I_{IN}+Ceil(\log_{2}(S))

Spiegazione IOUTI_{OUT}: Il numero più grande che possiamo rappresentare con I bit è 2I12I-1. Durante l'addizione di S termini, il valore massimo diventa (2I1)S(2I-1) \cdot S. Per determinare quanti bit occorrono, facciamo quanto segue:

IOUT=Ceil(log2((2I1)S))=Ceil(log2(2I1))+Ceil(log2(S))=IIN+Ceil(log2(S))I_{OUT}=Ceil(\log_{2}((2^I-1) \cdot S))=Ceil(\log_{2}(2^I-1))+Ceil(\log_{2}(S))=I_{IN}+Ceil(\log_{2}(S))

Risposta all'impulso

La risposta all'impulso del mio ufficio g(t)g(t).

L'impulso di Dirac nella figura B.1 è stato ottenuto con un forte e rapido battito di mani. Questo è stato campionato a una frequenza di 35 kHz tramite un microfono semplice e costruito manualmente. Il campionatore era collegato all'Amiga e l'intero processo dura circa 460 ms.

Efficienza laterale

g(t)g(t) è la risposta all'impulso della stanza.

glat(t)g_{lat}(t) è l'energia che proviene dai lati.

Leff.=25ms80ms[glat(t)]2dt080ms[g(t)]2dt100%L_{eff.} = \frac{ \intop_{25ms}^{80ms}[g_{lat}(t)]^{2}dt}{\intop_{0}^{80ms}[g(t)]^{2}dt} \cdot 100\%

MSM_S

fSf_S è la frequenza di campionamento. T60T_{60} è il tempo di riverberazione calcolato mediante la formula di Sabine. IINI_IN è la larghezza di banda delle informazioni in ingresso espressa in numero di bit.

MS=fST60IIN/8 byteM_S = f_S \cdot T_{60} \cdot I_{IN}/8\ \text{byte}

MS=fST60IIN/8 byteM_{S} = f_{S} \cdot T_{60} \cdot I_{IN}/8~\text{byte}

Spiegazione MSM_S: Per poter interpolare i dati in ingresso in ogni istante di tempo, dobbiamo memorizzare tutti i campioni acquisiti. Questa memorizzazione ha una lunghezza di fST60f_S \cdot T_{60} unità, poiché richiediamo la memorizzazione fino alla durata della funzione di Dirac. Il fatto sopra menzionato e la definizione della larghezza di banda delle informazioni forniscono la formula.

Capacità di MIXTHEM

op è un'addizione più una moltiplicazione. D è la capacità del computer in numero di op/s. fSf_S è la frequenza di campionamento. S è il numero di oggetti produttori di suono. fDIRACf_{DIRAC} è la frequenza di campionamento durante il campionamento della funzione di Dirac. T60T_{60} è il tempo di riverberazione calcolato mediante la formula di Sabine. R è il numero di ricevitori.

D=fS(S+fDIRACT60)RD=f_S \cdot (S+f_{DIRAC} \cdot T_{60}) \cdot R

Spiegazione Capacità di MIXTHEM: L'addizione preliminare di tutte le sorgenti sonore a ciascun ricevitore deve essere eseguita alla stessa velocità dei dati in ingresso, e ciò fornisce il seguente contributo alla formula:

fSSRf_S \cdot S \cdot R

La lunghezza della risposta impulsiva è fDIRACT60f_{DIRAC} \cdot T_{60} unità e contiene il suono diretto, riflesso e di riverberazione. Inoltre, dobbiamo filtrare ogni ricevitore tramite i fDIRACT60f_{DIRAC} \cdot T_{60} suoni parziali che abbiamo sommato preliminarmente. Anche questo deve essere eseguito alla stessa velocità dei dati in ingresso. Ciò fornisce il seguente contributo:

fSfDIRACT60Rf_S \cdot f_{DIRAC} \cdot T_{60} \cdot R

MIXTHEM MTOTM_{TOT}

R è il numero di ricevitori. fSf_S è la frequenza di campionamento dei dati in ingresso. T60T_{60} è il tempo di riverberazione calcolato mediante la formula di Sabine. IOUTI_{OUT} è la larghezza di banda delle informazioni in uscita, espressa in numero di bit.

MTOT=RfST60IOUT/8M_{TOT} = R \cdot f_S \cdot T_{60} \cdot I_{OUT}/8

Spiegazione Capacità di MIXTHEM MTOTM_{TOT}: A ciascun ricevitore sono necessari fDIRACT60IOUT/8f_{DIRAC} \cdot T_{60} \cdot I_{OUT}/8 byte per memorizzare le somme preliminari utilizzate nell'operazione di convoluzione con la risposta impulsiva (IOUT poiché non vogliamo perdere dati durante i calcoli). Si noti che è di fondamentale importanza avere la stessa frequenza di campionamento per i dati in ingresso e il campionamento della funzione di Dirac, al fine di semplificare le somme preliminari. Ciò fornisce la formula.

Capacità NODIRAC

op è un'addizione più una moltiplicazione. D è la capacità del computer in numero di op/s. fSf_S è la frequenza di campionamento. S è il numero di oggetti produttori di suono. XEX_E è il numero di riflessioni precoci. XRX_R è il numero di approssimazioni della riverberazione. R è il numero di ricevitori.

D=fS(S+XE+XR)RD=f_S \cdot (S+X_E+X_R) \cdot R

Spiegazione Capacità NODIRAC: Ogni sorgente genera S suoni diretti per ogni ricevitore. Ciò implica che richiediamo SRS \cdot R op per la convoluzione del suono diretto.

Le riflessioni precoci generano XE suoni riflessi per ogni ricevitore. Ciò implica che richiediamo XERX_E \cdot R op per la convoluzione del suono riflesso. Le approssimazioni della riverberazione generano XR suoni di riverberazione per ogni ricevitore. Ciò implica che richiediamo XRRX_R \cdot R op per la convoluzione del suono di riverberazione.

Tutto quanto sopra deve essere eseguito in ogni istante di campionamento, e ciò fornisce la formula.

Capacità NOMIX

op è un'addizione più una moltiplicazione. D è la capacità del computer in numero di op/s. fSf_S è la frequenza di campionamento. S è il numero di oggetti produttori di suono. fDIRACf_{DIRAC} è la frequenza di campionamento durante il campionamento della funzione di Dirac. T60T_{60} è il tempo di riverberazione calcolato mediante la formula di Sabine. R è il numero di ricevitori.

D=fSSfDIRACT60RD=f_S \cdot S \cdot f_{DIRAC} \cdot T_{60} \cdot R

Spiegazione Capacità NOMIX: La lunghezza della risposta all'impulso è fDIRACT60f_{DIRAC} \cdot T_{60} unità e include suono diretto, riflesso e di riverberazione. Inoltre, ogni sorgente genera fDIRACT60f_{DIRAC} \cdot T_{60} suoni parziali per ogni ricevitore. Ciò implica che richiediamo SfDIRACT60RS \cdot f_{DIRAC} \cdot T_{60} \cdot R op per la convoluzione di tutti i suoni parziali. Quanto sopra deve essere eseguito in ogni istante di campionamento, e ciò fornisce la formula.

NOMIX MTOTM_{TOT}

MSM_S è la dimensione della memoria intermedia per la convoluzione a risposta impulsiva. R è il numero di ricevitori. fDIRACf_{DIRAC} è la frequenza di campionamento della risposta impulsiva. T60T_{60} è il tempo di riverberazione calcolato mediante la formula di Sabine. IINI_{IN} è la larghezza di banda dei dati in ingresso, espressa in numero di bit.

MTOT=S(MS+RfDIRACT60IIN/8)M_{TOT} = S \cdot (M_S+R \cdot f_{DIRAC} \cdot T_{60} \cdot I_{IN}/8) byte

Spiegazione NOMIX MTOTM_{TOT}: Per memorizzare temporaneamente i dati di convoluzione di ogni trasmettitore, sono necessari SMSS \cdot M_S byte. Da ogni trasmettitore a ogni ricevitore sono richiesti fDIRACT60IIN/8f_{DIRAC} \cdot T_{60} \cdot I_{IN}/8 byte per memorizzare la risposta impulsiva utilizzata nelle convoluzioni. Ciò porta al seguente risultato:

MTOT=SMS+SRf+DIRACT60IIN/8M_{TOT} = S \cdot M_S+S \cdot R \cdot f+{DIRAC} \cdot T_{60} \cdot I_{IN}/8

Teorema di Nyquist

Il campionamento di un segnale filtrato passa-basso con banda B Hz richiede una frequenza di campionamento di 2B Hz per catturare tutte le frequenze fino a B Hz.

Dimostrazione: Un'onda è composta da una parte positiva e una negativa intorno a un riferimento. Se quest'onda oscilla B volte al secondo attorno al riferimento, avremo B parti positive e lo stesso numero di parti negative. Per catturare entrambe le parti, in modo da poter rigenerare l'onda, è necessario campionare 2B volte al secondo.

Tempo di salita

Il tempo necessario affinché metà dell'energia della pulsazione Dirac trasmessa raggiunga il punto di test.

Formula di Sabine

V è il volume libero della stanza. SiS_i è l'area totale di assorbimento di una superficie specifica. aia_i è il coefficiente di assorbimento di una superficie specifica. m è la costante di attenuazione dell'aria e può essere trascurata se la stanza è piccola. N è il numero di superfici nella stanza.

T60=0.163VSiαi+4mVT_{60}=\frac{0.163 \cdot V}{\sum{S_i\alpha_i+4mV}} i=1,2,...,N{i=1, 2, ..., N}

Funzione spline (cubica)

Definizione: Sia x1<x2<...<xnx1<x2<...<xn l'insieme dei punti di campionamento e sia la funzione s(x) definita sull'intervallo [x1,xn][x1, xn]. Inoltre, s(x),s´(x),s´´(x)s(x), s´(x), s´´(x) deve essere continua su tale intervallo. Per ogni sottointervallo [xi,xi+1],i=1,...,n1{ [x_i, x_{i+1}], i=1, ..., n-1 }, lasciamo che un polinomio cubico interpoli i valori tra i punti di campionamento discreti. Allora s(x)s(x) è una funzione spline cubica.

Superellissoide

f(x,y,z)=((x/a1)2/e2+(y/a2)2/e2)e2/e1+(z/a3)2/e11f(x, y, z) = ((x/a_1)^{2/e_2}+(y/a_2)^{2/e_2})^{e_2/e_1}+(z/a_3)^{2/e_1}-1

0<e1<1,0<e2<1,f(x,y,z)=00<e_1<1, 0<e_2<1, f(x,y,z)=0

Libri, software e hardware

Timeo hominem unius libri

St. Thomas Aquinas

Per coloro che hanno pensato di intraprendere un lavoro simile, questa raccolta di materiali di riferimento può risultare utile. Tutte le seguenti unità sono elencate con l'unità più comune in cima.

Influenze da libri

Heinrich Kuttruff, Room Acoustics
Andrew S. Glassner, An Introduction to Ray Tracing
K. Blair Benson, Audio Engineering Handbook
Alan Watt & Mark Watt, Advanced Animation & Rendering Techniques
Stewen Brawer, Introduction to Parallel Programming
John Watkinson, The Art of Digital Audio

Influenze da articoli

Yoichi Ando, Calculation of subjective preference at each seat in a concert hall, Acoustical Society of America 74 (1983) 873

A. Krogstad, S. Strøm & S. Sørsdal, Fifteen Years' Experience with Computerized Ray Tracing, Applied Acoustics 16 (1983) 291

Katsuaki Sekiguchi & Sho Kimura, Calculation of Sound Field in a Room by Finite Sound Ray Integration Method, Applied Acoustics 32 (1991) 121

Utilizzo di libri

Amiga ROM Kernel Reference Manual: Include and Autodocs
Amiga User Interface Style Guide
Amiga ROM Kernel Reference Manual: Libraries
Amiga Hardware Reference Manual
Steven Williams, Programming the 68000
Craig Bolon, Mastering C
J.D. Foley & A. van Dam, Fundamentals of Interactive Computer Graphics
Karl Gustav Andersson, Lineär Algebra
Grant R. Fowles, Analythical Mechanics
Tobias Weltner, Jens Trapp & Bruno Jennrich, Amiga Graphics Inside & Out

Libri di riferimento rapido

Encyclopedia Britannica versione 1991
Webster's International Dictionary
Jorge de Sousa Pires, Electronics Handbook
Carl Nordling & Jonny Österman, Physics Handbook
Lennart Råde & Bertil Westergren, Beta Mathematics Handbook
Steven Williams, 68030 Assembly Language Reference
Alan V. Oppenheim & Ronald W. Schafer, Digital Signal Processing

Influenze da software

Real 3D v2.0, RealSoft
Caligari, Octree
Lightwave, NewTech
Real 3D v1.4, RealSoft
Imagine 2.0, Impulse
Sculpt 3D, Eric Graham
Videoscape, Aegis

Utilizzo del software

Finalwriter, SoftWood, per la scrittura di documenti
Deluxe Paint, Electronic Arts, per la creazione e ritocco di immagini
TxEd, per la programmazione
Tool Maker, Commodore, per la creazione di interfacce grafiche
SAS C v6.0 e v6.5 compiler, per la generazione di programmi
CPR, per il debug
Enforcer, come strumento di debug
Devpac 3.0, HiSoft, per l'ottimizzazione
Metacomco Macro Assembler, per l'ottimizzazione
Maple IV, per l'analisi di ipotesi

Utilizzo dell'hardware

Amiga 500+ sistema 2.1 con MC68030 a 50 MHz, 68882 a 60 MHz e 4 MB, per lo sviluppo
Vidi Amiga, Rombo, per la scansione video di varie immagini con Sony Handycam
Star LC24-200, per la stampa di correzioni pre-stampa
Hewlett Packard Desk Jet 550C, per la stampa master v1.0
Hewlett Packard Desk Jet 520, per la stampa master v2.0 e successive
Amiga 1200 sistema 3.0 con MC68020 a 28 MHz e 6 MB, per il test e lo sviluppo
Amiga 1000 sistema 1.3 con MC68000 a 7.14 MHz e 2.5 MB, per le ottimizzazioni
Amiga 3000 sistema 3.1 con MC68030 a 25 MHz e 68882 a 25 MHz, per il controllo di coerenza
Amiga 4000 sistema 3.1 con MC68040 a 30 MHz, per il controllo di coerenza
Quadraverb, Alesis, per esperimenti di auralizzazione
Sampler costruito manualmente, interfaccia MIDI e mixer per esperimenti di auralizzazione
DSS8+ (Digital-Sound-Studio) Hardware e Software, GVP, per esperimenti di auralizzazione
Microfono dinamico, Sherman, per la campionatura di Dirac (determinazione della correlazione modello \Leftrightarrow realtà)

Riferimenti

1

Hofstätter, M., Illustrerad Vetenskap 11 (1989) 50.

2

Nya Rön, Illustrerad Vetenskap 12 (1993) 19.

3

IEC 581.

4

McGraw-Hill Encyclopedia of Science & Technology 8 (1992) 444.

5

Kuttruff, H., Room Acoustics (1991) 82.

6

Swiatecki, S., Illustrerad Vetenskap 5 (1994) 50.

7

Gabrielsson, A. & Lindström, B., "Perceived Sound Quality of High-Fidelity Loudspeakers," J. Audio Eng. Soc., 65, (1979) 1019-1033.

8

Shaw E. A. G., "L'acustica dell'orecchio esterno", Handbook of Sensory Physiology, vol. V/1: Auditory System, Springer-Verlag, Berlino, 1974.

9

Udito umano, Encyclopedia Britannica, 27 (1991) 204.

10

Meyer, J. Acustica e prestazione musicale, Verlag das Musikinstrument (1978)

11

Olsen, H.F., Musica, fisica e ingegneria, 2ª ed. (1967)

12

Comunicazione cellulare mediante segnalizzazione chimica (Encyclopedia Britannica) 15 (1991) 599.

13

Toole, Floyd E., Principi del suono e dell'udito (Audio Engineering Handbook) 1.42 (1988).

14

Oppenheim, A. V. & Shafer, R. W., Elaborazione dei segnali digitali. Prentice Hall, Engelwood Cliffs, NJ, (1975) 242

15

Hilmar Lehnert & Jens Blauert, Principi della simulazione binaurale di ambienti acustici, Applied Acoustics 36 (1992) 285.

16

Adams, G.J. & Watson, A. P., Elaborazione audio digitale per la simulazione dell'acustica di ambienti. ASSPA, 1989, 103-107

17

Sistemi endocrini, Encyclopedia Britannica, 18 (1991) 291.

18

Comportamento animale, Encyclopedia Britannica, 14 (1991) 662.

19

Feromone, Encyclopedia Britannica, 9 (1991) 262.

20

Esplorazione, Encyclopedia Britannica, 19 (1991) 48.

21

Simulatore di volo, Encyclopedia Britannica, 4 (1991) 834.

22

Möller H., Fondamenti della tecnologia binaurale, Applied Acoustics 36 (1992) 171

23

Gierlich H.W., L'applicazione della tecnologia binaurale, Applied Acoustics 36 (1992) 219

24

Lehnert H. & Blauert J., Principi della simulazione binaurale di ambienti acustici, Applied Acoustics 36 (1992) 259

25

Vian J. & Martin J., Simulazione dell'acustica binaurale: utilizzi e applicazioni pratiche, Simposio internazionale sull'ambiente auditivo virtuale e la telepresenza (Bochum, 8 aprile 1991) & Applied Acoustics 36 (1992) 293

26

Krokstad A., Strøm S. e Sørsdal S., Fifteen Years' Experience with Computerized Ray Tracing, Applied Acoustics 16 (1983) 291

27

Roese J. A. e Khalafalla A. S., Stereoscopic Viewing with PLZT Ceramics, Ferroelectrics 10 (1976) 47

28

Roese J. A. e McCleary L., Stereoscopic Computer Graphics for Simulation and Modeling, SIGGRAPH '79 Proceedings, Computer Graphics 13(2) (1979) 41

29

Kuttruff H., Room Acoustics, Elsevier Applied Science (1991) 62

30

Forsberg P., Applied Acoustics 18 (1985) 393

31

Choi S. e Tachibana H., Estimation of impulse response in a sound field by the finite element method, Thirteenth ICA No. E11-7 (1986)

32

Borish J., Extension of the image model to arbitrary polyhedra, Acoustic Society America 75(6) (1986) 1827

33

Kirszenstein J., An image source computer model for room acoustics analysis and electroacoustic simulation, Applied Acoustics 17 (1984) 275

34

Krokstad A., Strøm S. e Sørsdal S., Calculating the acoustical room response by the use of a ray tracing algoritm, Sound & Vibration 8(1) (1968) 118

35

Vorländer M., Simulation of the transient and steady-state sound propagation in rooms using a new combined ray-tracing/image-source algorithm, ASA 86(1) (1989) 172

36

Van Maercke D., Simulation of sound fields in time and frequency domain using a geometrical model, Twelfth ICA No. E11-7 (1986)

37

L'Espérance A., Herzog P., Diagle G.A. e Nicolas J.R., Heuristic Model for Outdoor sound Propagation Based on an Extension of the Geometrical Ray Theory in the Case of a linear sound speed Profile, Applied Acoustics 36 (1992) 111