VS85 Team's profileXNALearnersBlogListsGuestbook Tools Help

Blog


    4/13/2008

    Audio

    Eseguire audio in un progetto XNA

    By Giulia Costantini

    [English Version] 

     

    Introduzione

    In questo tutorial impareremo ad caricare ed eseguire suoni nelle nostre applicazioni XNA. Lo strumento che useremo e' il programma XACT (Cross-platform Audio Creation Tool), uno strumento multipiattaforma (Windows + Xbox360) per la creazione dell'audio. Questo programma viene automaticamente installato insieme ad XNA, quindi se avete gia' installato XNA sul vostro PC avete tutto quello che serve per seguire questo tutorial. Trovate XACT tramite "tutti i programmi"à "Microsoft XNA Game Studio 2.0" à "tools" à "Microsoft Cross-Platform Audio Creation Tool". Per ascoltare suoni all'interno di XACT (invece di dovere aprire un player apposito) potete usare il seguente programma (anch'esso installato insieme ad XNA): "tutti i programmi"à "Microsoft XNA Game Studio 2.0" à "tools" à"XACT Auditioning Utility".

     

    Concetti di base di XACT

    Cominciamo facendo conoscenza con la terminologia usata da XACT e XNA per quanto riguarda i suoni.

    Un wave e' un buffer di dati audio, ossia un file che contiene un suono. I formati audio supportati da XACT sono wav, aiff e xma.

    Un sound invece e' insieme di tracce eseguite contemporaneamente; per ciascuna traccia si possono impostare diverse proprieta' tra cui il wave che quella traccia esegue, il volume, ecc...

    Il termine cue si riferisce al suono logico, ossia cio' che viene effettivamente usato nel codice per riprodurre un suono. Ogni cue puo' contenere uno o piu' suoni; nel caso in cui essa contenga piu' suoni, quando viene eseguita viene scelto uno dei suoni che essa contiene. Tramite XACT possiamo decidere come viene effettuata la scelta del suono da eseguire: ad esempio possiamo impostare una scelta casuale, oppure che i suoni vengano riprodotti nell'ordine in cui li abbiamo inseriti, e cosi' via.

    Una wave bank e' una collezione di waves, ovvero una collezione di file audio. Il formato di file di una wave bank e' .xwb. Anche per ogni wave bank possiamo impostare varie proprieta', come ad esempio il metodo di compressione per i file audio, se la riproduzione viene effettuata in streaming o se il file viene tenuto tutto in memoria, ecc...

    Una sound bank invece e' una collezione di sounds e cues. Il formato di file di una sound bank e' .xsb.

    Come vedremo tra poco, un progetto XACT puo' essere visto come l'insieme di tre files:

    • un file .xgs che contiene impostazioni globali;
    • un file .xwb, cioe' la wave bank che contiene tutti i nostri file wave;
    • un file .xsb, cioe' la sound bank che contiene tutti i sounds e le cues.

     

    Creare un progetto XACT

    Prima di tutto creiamo un progetto XNA 2.0 tramite Visual Studio ("file" à "new" à "project" à "windows game 2.0") e aggiungiamo al progetto Content (tasto destro su Content à "add" à "new folder") una cartella chiamata "Sound".

     

    A questo punto siamo pronti per creare il nostro progetto XACT. Dopo avere aperto il programma XACT, clicchiamo su "file" à "new project" e inseriamo come path il percorso del nostro progetto XNA appena creato, precisamente "path_progetto_xna\Content\sound". Chiamiamo il nostro progetto XACT myFirstXACTProject.

     

    Ora dobbiamo creare una nuova wave bank e una nuova sound bank. Per fare cio' basta cliccare col tasto destro su "Wave Banks" e su "Sound Banks" e selezionare rispettivamente "New Wave Bank" e "New Sound Bank".

    .

     

    A questo punto nella parte destra dello schermo sono comparse le nostre banks (che di default si chiamano "Wave Bank" e "Sound Bank" ma che possiamo tranquillamente chiamare come vogliamo, semplicemente cliccando F2 sul nome e inserendo il nuovo nome seguito dalla pressione di Invio).

    Aggiungere suoni (file audio) alla wave bank non potrebbe essere piu' facile: dobbiamo selezionare i file audio da inserire nella wave bank e trascinarli sopra alla wave bank stessa. Vi ricordo che i formati supportati da XACT sono wav, aiff e xma.

    Abbiamo importato nella nostra wave bank due files, chiamati "industry.wav" e "menu.wav". Il risultato e' il seguente:

    Abbiamo visto che una sound bank contiene una collezione di sounds e di cues; in effetti se osserviamo la finestra della nostra sound bank possiamo osservare che e' divisa in due zone, una riservata ai sound e una riservata alle cues:

    Per creare un nuovo suono e' sufficiente trascinare un file della wave bank nella zona dedicata ai sounds della sound bank. Trascinando il wave "industry" otteniamo:

    Cosi' facendo abbiamo creato il suono "industry" (ma possiamo cambiargli nome) che consiste di una sola traccia, ovvero il wave "industry.wav". Possiamo aggiungere altre tracce al suono (trascinando un altro wave sul sound industry), ma ricordiamo che le tracce di un suono vengono riprodotte in contemporanea.

    Creiamo un altro suono, collegato al file wav "menu", trascinando il wave "menu" dalla wave bank alla sound bank:

    A questo punto abbiamo due suoni, ciascuno collegato ad un solo wave. Per creare una cue e' sufficiente trascinare un sound nella zona delle cues. Trascinando il sound "industry" nelle cues otteniamo:

    Abbiamo creato una cue chiamata "industry" (anche qui ovviamente possiamo cambiargli nome) collegata al suono "industry".

    Ricordiamoci alla fine di salvare il progetto XACT!

     

    Importare il progetto XACT in XNA

    Torniamo finalmente a Visual Studio, al nostro progetto XNA. Dobbiamo includere nel progetto Content il file del progetto XACT su cui abbiamo appena lavorato. Per fare cio', clicchiamo sul progetto Content, poi clicchiamo su "Show all files" per poter vedere il file di progetto XACT

    ,

    poi clicchiamo col tasto destro sul file .xap ("myFirstXACTProject.xap") appena comparso

    e infine selezioniamo "Include in Project". Dall'output della compilazione del nostro progetto

    vediamo che la Content Pipeline di XNA (che vedrete in un tutorial successivo) ci ha prodotto 3 files, che sono quelli di cui vi avevo parlato all'inizio del tutorial: un file di configurazione generale riguardante l'audio (.xgs), un file per la wave bank (.xwb) e uno per la sound bank (.xsb).

     

    Eseguire suoni nell'applicazione

    E' giunta finalmente l'ora di scrivere del codice J Cominciamo creando tre oggetti:

    AudioEngine engine;

    WaveBank waveBank;

    SoundBank soundBank;

     

    E inizializziamoli nella funzione "LoadContent":

    engine = new AudioEngine("Content\\sound\\myFirstXACTProject.xgs");

    waveBank = new WaveBank(engine, "Content\\sound\\Wave Bank.xwb");

    soundBank = new SoundBank(engine, "Content\\sound\\Sound Bank.xsb");

     

    Abbiamo dunque caricato i 3 files che caratterizzano il nostro progetto XACT, ossia il file di impostazioni .xgs (che va memorizzato nell'AudioEngine), la wave bank .xwb (che viene memorizzata nell'oggetto di tipo WaveBank) e la sound bank .xsb (che viene memorizzata nell'oggetto di tipo SoundBank). Alla waveBank e alla soundBank va anche passato l'engine di riferimento.

    A questo punto abbiamo due possibilita' per riprodurre un suono. La prima possibilita' e':

    soundBank.PlayCue("industry");

     

    ovvero utilizzare la sound bank per riprodurre direttamente una cue, identificata per nome (nel nostro caso abbiamo scelto di riprodurre la cue "industry"). Se inseriamo questo codice nella funzione LoadContent (subito dopo la creazione degli oggetti engine, waveBank e soundBank) otterremo che all'avvio dell'applicazione XNA verra' riprodotto il suono collegato alla cue "industry".

    La seconda possibilita' e' definire un altro oggetto

    Cue cue;

     

    di tipo Cue, e nella LoadContent scrivere:

     

    cue = soundBank.GetCue("industry");

    cue.Play();

     

    Cosa abbiamo fatto? Ci siamo fatti dare la cue di nome "industry" dalla sound bank, l'abbiamo salvata in un oggetto di tipo Cue e l'abbiamo riprodotta. L'effetto e' esattamente lo stesso visto prima, ossia all'avvio dell'applicazione viene riprodotto il suono collegato alla cue "industry").

    Se pero' volessimo che il suono venisse riprodotto solo quando viene premuto un certo tasto? Bastera' scrivere il seguente codice nella funzione "Update":

    if (Keyboard.GetState().IsKeyDown(Keys.Space))

    {

    cue = soundBank.GetCue("industry");

        cue.Play();

    }

    In questo modo quando premeremo il tasto spazio, verra' riprodotto il suono desiderato.

    C'e' pero' un problema: la funzione Update, come sappiamo, viene chiamata molte volte (anche centinaia) al secondo. Quindi durante la nostra pressione del tasto spazio la funzione Update viene chiamata piu' volte e ogni volta essa comincera' la riproduzione della cue "industry". Il risultato e' che il suono viene riprodotto piu' volte, ciascuna a distanza di millesimi di secondo dalla precedente. Inoltre se premiamo spazio una seconda volta (dopo qualche secondo), mentre il suono sta ancora venendo riprodotto, partira' una seconda istanza del suono che si sovrapporra' alla prima. Come possiamo evitare queste spiacevoli situazioni? Grazie alla proprieta' isPlaying che ci fornisce l'oggetto di tipo Cue! Tale proprieta' ci dice se la cue sta venendo riprodotta; in questo modo possiamo evitare di cominciare un'altra riproduzione del suono se ce n'e' gia' una attiva. In codice:

    if (cue != null && cue.IsPlaying == false)

    cue = null;

     

    if (Keyboard.GetState().IsKeyDown(Keys.Space) && cue == null)

    {

    cue = soundBank.GetCue("industry");

    cue.Play();

    }

    Nel codice qui sopra abbiamo imposto che la cue sia null quando non sta venendo eseguita. Infatti se la cue non e' null e sta eseguendo un suono e questo suono finisce, la sua proprieta' isPlaying diventera' falsa e quindi cue verra' impostata a null. La pressione del tasto spazio viene considerata solamente se cue e' null, ovvero se la cue non sta eseguendo un suono.

    Abbiamo dunque risolto il problema citato prima: la pressione prolungata del tasto spazio non provoca l'esecuzione dello stesso suono un sacco di volte uno sopra l'altro; inoltre pressioni di spazio effettuate durante l'esecuzione del suono non vengono considerate. Ricapitolando: la cue "industry" verra' eseguita solo se viene premuto il tasto spazio e se non e' gia' in esecuzione (che e' esattamente quello che volevamo ottenere)!

    Nota da tenere ben presente: la cue che otteniamo tramite il metodo GetCue puo' venire riprodotta una sola volta, dopodiche' la cue e' stata "consumata" e non e' piu' valida. E' per questo motivo che prima di ogni "cue.Play()" dobbiamo ri-estrarre la cue dalla sound bank con il metodo GetCue.

     

    Aspetti leggermente piu' avanzati di XACT

    L'utilizzo del programma XACT rende il tecnico dell'audio completamente indipendente dai programmatori. Come? Abbiamo visto che nel codice ci riferiamo alle cue per nome (ad esempio noi eseguivamo la cue "industry"). Dal momento in cui il tecnico del suono si limita a modificare solamente i wave associati alla cue, e non il nome della cue stessa, puo' lavorare per conto suo e il nostro codice continuera' a funzionare. Quindi il tecnico puo' apportare migliorie e modifiche alle cue tramite XACT, e con una semplice ricompilazione del nostro progetto XNA (durante cui vengono ricreati, se necessario, i 3 file xgs, xwb e xsb) avremo i suoni aggiornati senza dover cambiare una riga di codice.

    Ma cosa puo' fare esattamente un tecnico del suono con XACT?

    Abbiamo detto che ad un sound si possono associare piu' tracce (trascinando il nome di ciascun wave sul nome del sound): queste tracce verranno pero' riprodotte contemporaneamente. Si puo' anche cancellare una traccia da un sound cliccando sulla traccia e poi premendo "canc". Nell'immagine sotto vedete un suono ("industry") a cui sono associate due tracce (il wave "industry" e il wave "menu"):

    Nella sound bank possono stare piu' suoni, ciascuno associato a particolari tracce:

    A ciascuna cue possono venire associati piu' suoni, semplicemente trascinandoli sul nome della cue. Nell'immagine qui sotto vedete che alla cue chiamata "cue1" ho associato tutti e due i suoni presenti nella sound bank, ossia "industry" e "menu".

    Se in una cue si sono piu' suoni, possiamo impostare il metodo con cui viene scelto quale dei suoni riprodurre quando viene eseguita la cue.

    Nell'immagine vedete il menu a tendina con cui si imposta tale proprieta' e vedete che le possibilita' non sono poche.

     

    Trovate qui il codice sorgente e qui il webcast ad alta risoluzione in cui Alessandro Piva spiega XACT e la scrittura del codice in diretta. Una versione embedded a risoluzione piu' bassa e' qui sotto: