4 Äänet ja musikki. 4.1 Wav-tiedostojen soittaminen SoundEffect-luokka

Samankaltaiset tiedostot
XNA grafiikka laajennus opas. Paavo Räisänen. Tämän oppaan lähdekoodit ovat ladattavissa näiden sivujen Ladattavat osiossa.

XNA 2D ohjelmoinnin perusteet. Paavo Räisänen.

10 Lock Lock-lause

5 Näppäimistö. 5.1 Näppäimistön eventit

Olio-ohjelmointi Javalla

Mainosankkuri.fi-palvelun käyttöohjeita

Jypelin käyttöohjeet» Ruutukentän luominen

Web Services tietokantaohjelmoinnin perusteet

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Kylänetti projektin sivustojen käyttöohjeita Dokumentin versio 2.10 Historia : 1.0, 1.2, 1.6 Tero Liljamo / Deserthouse, päivitetty 25.8.

C# Windows ohjelmointi perusopas

Pong-peli, vaihe Aliohjelmakutsu laskureita varten. 2. Laskurin luominen. Muilla kielillä: English Suomi

Jypelin käyttöohjeet» Ruutukentän luominen

Osio 4: Tietovirrat. Properties- eli ominaisuustiedostot Logger: lokitietojen käsittely

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

BlueJ ohjelman pitäisi löytyä Development valikon alta mikroluokkien koneista. Muissa koneissa BlueJ voi löytyä esim. omana ikonina työpöydältä

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2007

Peliohjelmointi Windows Phone 8:lle

Eclipse, SVN ja HelloWorld

Mikä yhteyssuhde on?

LUE ENSIN KOKO OHJE LÄPI JA KYSY NEUVOA! 5. Klikkaa Audacity-ohjelmassa mikrofonikuvakkeen vieressä tekstiä Napsautus käynnistää seurannan.

1. Miten tehdään peliin toinen maila?

Skype for Business ohjelman asennus- ja käyttöohje Sisällys

Eclipse 3.1 Pikaopas versio 1.0

1. Taustatietoa näppäimistönkuuntelusta

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Ajolista: Adobe Connect 8 yhteyden avaaminen

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

LP-Levyn digitointi tiedostoksi

RACE-KEEPER COMPARO PC-OHJELMAN PIKAOHJE

Cubase perusteet pähkinänkuoressa. Mikä Cubase on? Projektin aloitus

TEHTÄVÄ 1.1 RATKAISUOHJEET

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Eclipse 3.2 pikku opas versio 1.0. Esittely Uuden projektin perustaminen Sovelluksen luominen Koodin siistiminen Vinkkejä

TW-LTE 4G/3G. USB-modeemi (USB 2.0)

ELOKUVATYÖKALUN KÄYTTÖ ANIMAATION LEIKKAAMISESSA. Kun aloitetaan uusi projekti, on se ensimmäisenä syytä tallentaa.

H5P-työkalut Moodlessa

Skype for Business ohjelman asennus- ja käyttöohje Sisällys

Laskuharjoitus 9, tehtävä 6

Jypelin käyttöohjeet» Miten saan peliin pistelaskurin?

Metodien tekeminen Javalla

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

EASY Tiedostopalvelin - mobiilin käyttöopas

Delegaatit ja tapahtumakäsittelijät

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

Pikaohje formaatin valmistamiseen

Pong-peli, vaihe Rajojen tarkistus Yläreunan tarkistus. Muilla kielillä: English Suomi

4. Luokan testaus ja käyttö olion kautta 4.1

Share-työkalu (AC 9.1)

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Pong-peli, vaihe Koordinaatistosta. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 2/7. Tämän vaiheen aikana

Kuvaruudun striimaus tai nauhoitus. Open Broadcaster Software V.20. Tero Keso, Atso Arat, Niina Järvinen & Valtteri Virtanen (muokattu 20.2.

Internet Explorer 7 & 8 pop-up asetukset

Automaattinen sovitus-, sävellys- ja harjoitteluohjelma. Suppea opas Band-In-A-Box, jäljempänä BIAB, ohjelman käyttöön Musiikkitalon Mac-luokassa.

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

MITEN KIRJAUDUN ADOBE CONNECTIIN?

Graafisen käyttöliittymän ohjelmointi Syksy 2013

Testivetoinen ohjelmistokehitys

Sisällysluettelo 1. Sony Vegas editorin pääikkuna Uuden projektin aloittaminen Tiedostojen lisääminen projektin mediakirjastoon

Videokuvan siirtäminen kamerasta tietokoneelle Windows Movie Maker -ohjelman avulla

Valikot ja työkalupalkit. 2008

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Microsoft Visual Studio 2005

FinFamily Installation and importing data ( ) FinFamily Asennus / Installation

AdobeConnect peruskäyttövinkkejä

UCOT-Sovellusprojekti. Käyttöohje

PERUSEDITOINTI: HIT FILM EXPRESS. Jukka Savilampi 2017

Sisältö. 2. Taulukot. Yleistä. Yleistä

Adobe Premiere Elements ohjeet

C# olio-ohjelmointi perusopas

NUUO ETÄOHJELMA PIKAOPAS. Maahantuoja Dasys Oy Kaivolahdenkatu HELSINKI helpdesk@dasys.fi

Lab SBS3.FARM_Hyper-V - Navigating a SharePoint site

1. Laitteen käyttöönotto ja käynnistys. 4. Kappaleitten soittaminen ja Auto-DJ. 5. Volume kontrollit sekä Ekvalisaattori ja Transponointi

C-kasetin digitointi Audacity-ohjelmalla

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

14. Poikkeukset 14.1

TIETORAKENTEET JA ALGORITMIT

LP-levyn digitointi Audacity-ohjelmalla

Graafisen käyttöliittymän ohjelmointi

KOHDELUOKAN MÄÄRITTELY

CLOUDBACKUP TSM varmistusohjelmiston asennus

Adobe Premiere 6.0 ohjelmasta

Ohjelmointi 2 / 2010 Välikoe / 26.3

EASY Tiedostopalvelin - mobiilin käyttöopas

SSH Secure Shell & SSH File Transfer

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2008

Kuvaruudun striimaus tai nauhoitus. Open Broadcaster Software V.20. Tero Keso, Atso Arat & Niina Järvinen (muokattu )

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

MITEN KIRJAUDUN ADOBE CONNECTIIN?

VHS-kasetin kopiointi DVD-levylle Adobe Premiere Elements -ohjelmalla

16. Javan omat luokat 16.1

Audio- ja videotiedostoja sisältävän PowerPoint-esityksen pakkaaminen

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Adobe Connect ohjeita etäopettajille ja etäkokousten järjestäjille

Pedacode Pikaopas. Java-kehitysympäristön pystyttäminen

Alkuun HTML5 peliohjelmoinnissa

Videoeditointi: Adobe Premiere Pro CS4

Avid Pro Tools Äänityksen perusteet. Petri Myllys 2013 / Taideyliopisto, Sibelius-Akatemia tp48 Äänitekniikan perusteet

Interaktiivinen tarinankerronta

Transkriptio:

4 Äänet ja musikki XNA Framework -luokkakirjasto sisältää useita luokkia, joiden avulla voidaan XNApeliohjelmassa toteuttaa taustamusiikin ja äänitehosteiden soittaminen. XNApeliohjelmissa yksittäiset äänitiedostot ovat tavallisesti.wav- tai.mp3-formaatissa. Yksinkertaisin tapa soittaa.wav-formaatissa olevia äänitiedostoja on käyttää SoundEffect-luokkaa. MP3-formaatissa olevien äänitiedostojen soittamiseen XNA Framework -luokkakirjastossa on MediaPlayer-luokat. XNA Framework sisältää näiden pääasiassa yksittäisten äänitiedostojen soittamiseen tarkoitettujen luokkien lisäksi myös muutamia muita luokkia, joita käytetään useammista äänitiedostoista koostuvien monipuolisempien äänimaailmojen toteuttamisessa. Nämä luokat toimivat yhdessä Microsoft Cross-Platform Audio Creation Tool -sovelluksen (XACT) kanssa. Microsoft Cross-Platform Audio Creation Tool -sovellus on ohjelma, jonka avulla voidaan hallita XNA-peliohjelmassa käytettäviä äänitiedostoja ja näiden soittamista. 4.1 Wav-tiedostojen soittaminen Aaltotiedostojen (.wav) soittamiseen XNA Framework -luokkakirjastossa on seuraavat luokat: o SoundEffect o SoundEffectInstance o DynamicSoundEffectInstance XNA-peliohjelmissa, joissa ei tarvita kovin montaa äänitiedostoa, niin näiden luokkien avulla voidaan toteuttaa kaikki XNA-peliohjelmassa tarvittavien.wav-formaatissa olevien äänitiedostojen soittaminen. 4.1.1 SoundEffect-luokka SoundEffect-luokka mahdollistaa yksittäisten äänitiedostojen soittamisen XNApeliohjelmassa. Yksinkertaisimmillaan peliohjelmaprojektiin mukaan otettu.wavformaatissa oleva äänitiedosto voidaan soittaa seuraavalla tavalla: SoundEffect wavsoundeffect; // Load a XnaBounce.wav wave file. wavsoundeffect = Content.Load<SoundEffect>("Audio\\XnaBounce"); wavsoundeffect.play(); SoundEffect-luokassa on Play()-metodin lisäksi muitakin metodeja ja ominaisuuksia, joiden avulla voidaan vaikuttaa äänitiedoston soittoon. Osa SoundEffect-luokan www.stickmansoft.com 95

metodeista on staattisia eli niitä voidaan käyttää ilman, että SoundEffect-luokasta luodaan objektia. Esimerkiksi, staattisen MasterVolume-ominaisuuden avulla voidaan säätää soittoäänen voimakkuus. XNA-peliohjelmassa soittoäänen voimakkuuden säätö voitaisiin suorittaa seuraavalla tavalla: // Volume, ranging from 0.0f (Silence) to 1.0f (Device volume). SoundEffect.MasterVolume = 0.5f; SoundEffect-luokka sisältää seuraavat ominaisuudet: o DistanceScale o DopplerScale o Duration o IsDisposed o MasterVolume o Name o SpeedofSound Edellä lueteltujen ominaisuuksien lisäksi SoundEffect-luokka sisältää joitakin metodeja. SoundEffect-luokka sisältää seuraavat public-tyyppiset metodit: o CreateInstance() o Dispose() o Equals() o FromStreams() o GetHasGode() o GetSampleDuration() o GetSampleSizeInByte(() o GetType() o Play() o ToString() 4.1.2 SoundEffectInstance-luokka SoundEffectInstance-luokan avulla SoundEffect-tyyppiseen äänitiedostojen soittamiseen saadaan tuotua mukaan lisää soiton hallinan toimintoja. Esimerkiksi, äänitiedoston soitto voidaan pysäyttää (Stop), keskeyttää (Pause) ja jatkaa taas soittoa (Resume). SoundEffectInstance-luokka mahdollistaa myös SoundEffect-tyyppisten äänitiedostojen soiton monipuolisemman säätämisen. Äänitiedoston soiton erilaisia ominaisuuksia kuten pan, pitch ja loop asetuksia voidaan tehdä. SoundEffectInstanceluokkassa olevan Apply3D()-metodin avulla voidaan lisäksi suorittaa 3D-äänimaailman asetuksia (3D positioning) käyttäen XNA Framework -luokkakirjaston AutoEmiter- ja AutoListener-luokkaa. Ääniefektiä varten eli SoundEffect-tyyppistä objektia varten SoundEffectInstance-luokan tyyppisen objektin saa luotua siten, että SoundEffectobjektin suhteen kutsutaan SoundEffect-luokan CreateInstance()-metodia. CreateInstance()-metodi palauttaa SoundEffectInstance-luokan tyyppisen objektin, 96 XNA Peliohjelmointi

jonka äänitiedoston soittamista voidaan kontrolloida käyttämällä SoundEffectInstanceluokan ominaisuuksia ja metodeja. SoundEffectInstance-tyyppisen objektin saa luotua seuraavalla tavalla: wavsoundeffectinstance = wavsoundeffect.createinstance(); SoundEffectInstance-tyyppisen objektin luomisen jälkeen, objektia voidaan käyttää äänitiedoston soittamiseen SoundEffect-objektin asemasta. SoundEffectInstanceluokassa on seuraavat ominaisuudet: o IsDisposed o IsLooped o Pan o Pitch o State o Volume Edellä lueteltujen ominaisuuksien lisäksi SoundEffectInstance-luokka sisältää joitakin metodeja. SoundEffectInstance-luokka sisältää seuraavat public-tyyppiset metodit: o Apply3D() o Dispose() o Equals() o GetHashCode() o GetType() o Pause() o Play() o Resume() o Stop() o ToString() 4.1.2.1 XnaSounds-ohjelma XnaSounds-ohjelma on esimerkki siitä, kuinka XNA-peliohjelmassa voidaan soittaa.wav-formaatissa olevia äänitiedostoja. Ohjelmassa soitetaan XnaLaser.wav nimistä äänitiedostoa. Äänitiedoston soittaminen suoritetaan SoundEffect- ja SoundEffectInstance-luokan avulla. Soittaminen käynnistetään painamalla Xbox 360 - peliohjaimen nappia A (Play). Soittaminen pysähtyy painamalla nappia B (Pause). Soittaminen jatkuu painamalla nappia X (Resume). Ohjelma koostuu Program.cs- ja XnaGame.cs-tiedostosta sekä XnaLaser.wav-äänitiedostosta ja XnaFont.spritefontfonttitiedostosta. Seuraavassa on esitelty edellä mainittujen lähdetekstitiedostojen sisältämät ohjelmakoodit. www.stickmansoft.com 97

Program.cs Program.cs-lähdetekstitiedosto sisältää Main()-metodin eli ohjelman aloituskohdan. Kuvassa 4-1 on esitetty Program.cs-tiedoston ohjelmakoodi. /* Program.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; namespace XnaGame static class Program static void Main(string[] args) using (XnaGame game = new XnaGame()) game.run(); XnaGame.cs Kuva 4-1. XnaSounds-ohjelman Program.cs-tiedosto. XnaGame.cs-lähdetekstitiedosto sisältää edellä mainitut Xbox 360 -peliohjaimen käsittelyssä ja äänitiedoston soittamisessa tarvittavat ohjelmarakenteet Kuvassa 4-2 on esitetty XnaGame.cs-tiedoston ohjelmakoodi. /* XnaGame.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; 98 XNA Peliohjelmointi

namespace XnaGame public class XnaGame : Microsoft.Xna.Framework.Game // HW GraphicsDeviceManager graphics; SpriteBatch spritebatch; // Screen static int windowheight = 85; static int windowwidth = 300; Rectangle titlesafearea; // GamePad GamePadState gamepadstate; Int32 buttonfilter = 0; // Text SpriteFont infofont; // Sounds SoundEffect wavsoundeffect; SoundEffectInstance wavsoundeffectinstance; public XnaGame() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Set default screen width and height. graphics.preferredbackbufferheight = windowheight; graphics.preferredbackbufferwidth = windowwidth; graphics.applychanges(); // Screen Window.Title = "XnaSounds"; protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); protected override void LoadContent() // Screen titlesafearea = GraphicsDevice.Viewport.TitleSafeArea; // Create a new SpriteBatch, which // can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); www.stickmansoft.com 99

// Text infofont = Content.Load<SpriteFont>( "Fonts\\XnaFont"); // Sounds wavsoundeffect = Content.Load<SoundEffect>( "Audio\\Wav\\XnaLaser"); SoundEffect.MasterVolume = 0.5f; // Create a dynamic sound effect instance. wavsoundeffectinstance = wavsoundeffect.createinstance(); protected override void UnloadContent() // TODO: Unload any non ContentManager content here protected override void Update(GameTime gametime) // Allows the game to exit. if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape) GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); // Read the GamePad state. gamepadstate = GamePad.GetState(PlayerIndex.One); // Play the sound. if (gamepadstate.buttons.a == ButtonState.Pressed && buttonfilter <= 0) buttonfilter = 20; wavsoundeffectinstance.play(); else buttonfilter--; // Pause if (gamepadstate.buttons.b == ButtonState.Pressed) wavsoundeffectinstance.pause(); 100 XNA Peliohjelmointi

// Resume if (gamepadstate.buttons.x == ButtonState.Pressed) wavsoundeffectinstance.resume(); base.update(gametime); protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.White); spritebatch.begin(); spritebatch.drawstring(infofont, "Play - Press button 'A'", new Vector2(10.0f, 10.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, "Pause - Press button 'B'", new Vector2(10.0f, 30.0f), new Color(0, 0, 0)); spritebatch.drawstring( infofont, "Resume - Press button 'X'", new Vector2(10.0f, 50.0f), new Color(0, 0, 0)); spritebatch.end(); base.draw(gametime); Kuva 4-2. XnaSounds-ohjelman XnaGame.cs-tiedosto. Kun XnaSounds-projektin toteuttaa, suorittaa ohjelman kääntämisen ja käynnistää ohjelman, niin kuvan 4-3 mukainen ikkuna aukeaa näytölle. Kuva 4-3. XnaSounds-ohjelman ohjelmaikkuna. www.stickmansoft.com 101

4.1.3 DynamicSoundEffectInstance-luokka DynamicSoundEffectInstance-luokka sisältää ominaisuuksia, metodeja ja eventtejä soittopuskurin (Audio Buffer) sisällön soittamiseen (Play back). DynamicSoundEffectInstance-tyyppisen objektin avulla päästään suoraan käsiksi soittopuskurin sisältöön. Tämä mahdollistaa soittoäänen manipuloinnin, äänitiedoston paloittelun pienempiin osiin ja äänen streemauksen. DynamicSoundEffectInstanceluokka sisältää samat ominaisuudet ja metodit, kuin SoundEffectInstance-luokka. Näiden lisäksi luokassa on joitakin lähinnä soittopuskurin (Audio Buffer) käsittelyyn tarkoitettuja ominaisuuksia, metodeja ja eventtejä. DynamicSoundEffectInstanceluokassa on SoundEffectInstance-luokassa olevien ominaisuuksien lisäksi seuraava ominaisuus: o PendingBufferCount DynamicSoundEffectInstance-luokassa on SoundEffectInstance-luokassa olevien metodien lisäksi seuraava metodit: o GetSampleDuration() o GetSampleSizeInBytes() o SubmitBuffer() DynamicSoundEffectInstance-luokassa on edellä esitettyjen ominaisuuksien ja metodien lisäksi seuraava eventti: o BufferNeeded 4.1.3.1 XnaSoundStream-ohjelma XnaSoundsStream-ohjelma on esimerkki siitä, kuinka XNA-peliohjelmassa voidaan streemata soittodataa.wav-formaatissa olevasta äänitiedostosta. Ohjelmassa käytetään äänitiedostona edellisessä esimerkissä käytettyä XnaLaser.wav-äänitiedostoa. Äänitiedoston streemaaminen käynnistetään painamalla Xbox 360 -peliohjaimen nappia A (Play). Streemaaminen pysäytetään painamalla nappia B (Stop). Ohjelma koostuu Program.cs- ja XnaGame.cs-tiedostosta sekä XnaLaser.wav-äänitiedostosta ja XnaFont.spritefont-fonttitiedostosta. Seuraavassa on esitelty edellä mainittujen lähdetekstitiedostojen sisältämät ohjelmakoodit. Program.cs Program.cs-lähdetekstitiedosto sisältää Main()-metodin eli ohjelman aloituskohdan. Kuvassa 4-4 on esitetty Program.cs-tiedoston ohjelmakoodi. /* Program.cs Copyright Markku Rahikainen. 102 XNA Peliohjelmointi

www.stickmansoft.com */ using System; namespace XnaGame static class Program static void Main(string[] args) using (XnaGame game = new XnaGame()) game.run(); XnaGame.cs Kuva 4-4. XnaSoundStream-ohjelman Program.cs-tiedosto. XnaGame.cs-lähdetekstitiedosto sisältää edellä mainitut Xbox 360 -peliohjaimen käsittelyssä ja äänitiedoston streemaamisessa tarvittavat ohjelmarakenteet. Kuvassa 4-5 on esitetty XnaGame.cs-tiedoston ohjelmakoodi. /* XnaGame.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using System.IO; namespace XnaGame public class XnaGame : Microsoft.Xna.Framework.Game // HW GraphicsDeviceManager graphics; www.stickmansoft.com 103

SpriteBatch spritebatch; // Screen static int windowheight = 600; static int windowwidth = 800; Rectangle titlesafearea; // GamePad GamePadState gamepadstate; GamePadState keyboardstateold; // Text SpriteFont infofont; // Stream DynamicSoundEffectInstance dynamicsound; int position; int counter; byte[] bytesoundarray; BinaryReader binaryreader; public XnaGame() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Set default screen width and height. graphics.preferredbackbufferheight = windowheight; graphics.preferredbackbufferwidth = windowwidth; graphics.applychanges(); // Screen Window.Title = "XnaSoundStream"; protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); protected override void LoadContent() // Screen titlesafearea = GraphicsDevice.Viewport.TitleSafeArea; // Create a new SpriteBatch, which // can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Text infofont = Content.Load<SpriteFont>("Fonts\\XnaFont"); 104 XNA Peliohjelmointi

// Stream // - Open the audio data. Stream wavefilestream = TitleContainer.OpenStream( "Content\\Audio\\Wav\\XnaLaser.wav"); // - Create a new binary reader to // read from the audio stream. binaryreader = new BinaryReader( wavefilestream); // - Read the wave file header from the buffer. int ChunkID = binaryreader.readint32(); int FileSize = binaryreader.readint32(); int RiffType = binaryreader.readint32(); int FmtID = binaryreader.readint32(); int FmtSize = binaryreader.readint32(); int FmtCode = binaryreader.readint16(); int Channels = binaryreader.readint16(); int SampleRate = binaryreader.readint32(); int FmtAvgBPS = binaryreader.readint32(); int FmtBlockAlign = binaryreader.readint16(); int BitDepth = binaryreader.readint16(); if (FmtSize == 18) // - Read any extra values. int FmtExtraSize = binaryreader.readint16(); binaryreader.readbytes(fmtextrasize); int DataID = binaryreader.readint32(); int DataSize = binaryreader.readint32(); // - Store the audio data of the // wave file to a byte array. bytesoundarray = binaryreader.readbytes(datasize); // - Create the new dynamic sound effect instance using // the sample rate and channel information extracted // from the sound file. dynamicsound = new DynamicSoundEffectInstance( SampleRate, (AudioChannels)Channels); // - Store the size of the audio buffer that // is needed in the count variable. Submit // data in 100 ms chunks. counter = dynamicsound.getsamplesizeinbytes( TimeSpan.FromMilliseconds(100)); www.stickmansoft.com 105

// - Set up the dynamic sound effect's // buffer needed event handler so // audio data can be read when it // needs more data. dynamicsound.bufferneeded += new EventHandler<EventArgs>( DynamicSound_BufferNeeded); // The buffer needed event handler. void DynamicSound_BufferNeeded(object sender, EventArgs e) dynamicsound.submitbuffer(bytesoundarray, position, counter / 2); dynamicsound.submitbuffer(bytesoundarray, position + counter / 2, counter / 2); position += counter; if (position + counter > bytesoundarray.length) position = 0; protected override void UnloadContent() // TODO: Unload any non ContentManager content here protected override void Update(GameTime gametime) // Allows the game to exit. if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape) GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); gamepadstate = GamePad.GetState(PlayerIndex.One); if (keyboardstateold!= gamepadstate) 106 XNA Peliohjelmointi

if (gamepadstate.buttons.a == ButtonState.Pressed) dynamicsound.play(); if (gamepadstate.buttons.b == ButtonState.Pressed) dynamicsound.stop(); keyboardstateold = gamepadstate; base.update(gametime); protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.White); spritebatch.begin(); spritebatch.drawstring(infofont, "Play - Press button 'A'", new Vector2(10.0f, 10.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, "Stop - Press button 'B'", new Vector2(10.0f, 30.0f), new Color(0, 0, 0)); spritebatch.end(); base.draw(gametime); Kuva 4-5. XnaSoundsStream-ohjelman XnaGame.cs-tiedosto. Kun XnaSoundsStream-projektin toteuttaa, suorittaa ohjelman kääntämisen ja käynnistää ohjelman, niin kuvan 4-6 mukainen ikkuna aukeaa näytölle. Kuva 4-6. XnaSounds-ohjelman ohjelmaikkuna. www.stickmansoft.com 107

4.2 MP3-tiedostojen soittaminen XNA-peliohjelmissa.mp3-formaatissa olevia musiikkitiedostoja voidaan soittaa käyttämällä Song- ja MediaPlayer-luokkaa. 4.2.1 Song-luokka Song-luokka mahdollistaa.mp3-formaatissa olevan musiikkitiedoston käyttämisen XNA-peliohjelmassa. Song-luokan tyyppiseen objektiin voidaan ladata.mp3- formaatissa olevan musiikkitiedoston sisältö. Musiikitiedostot on otettava XNApeliohjelman projektiin mukaan projektitiedostoiksi aivan samalla tavalla, kuin jos ne olisivat esimerkiksi.cs-lähdetetkstitiedostoja. Tällöin musiikkitiedostot tulevat käännettyä ja näin niistä tuotetaan.xnb-formaatissa olevia tiedostoja, joita voidaan ladata ohjelman käyttöön. Musiikkitiedoston, jonka nimi on esimerkiksi Music.mp3 lataaminen voidaan suorittaa seuraavalla tavalla: Song song; Song song = Content.Load<Song>("Audio\\Music"); Musiikkitiedoston lataamisen jälkeen Song-luokan ominaisuuksien avulla voidaan selvittää esimerkiksi albumi, artisti, kappaleen nimi ja kappaleen soittoaika. Musiikkitiedoston soittaminen voidaan lataamisen jälkeen suorittaa MediaPlayerluokan avulla. Song-luokka sisältää seuraavat ominaisuudet: o Album o Artist o Duration o Genre o IsDisposed o IsProtected o IsRated o Name o PlayCount o Rating o TrackNumber Song-luokassa on edellä esitettyjen ominaisuuksien lisäksi seuraavat metodit: o Dispose() o Equals() o FromUri() o GetHasCode() o GetType() o op_equality() 108 XNA Peliohjelmointi

o op_inequality() o ToString() Musiikkitiedoston lataamisen jälkeen Song-luokan ominaisuuksien avulla voidaan selvittää musiikkitiedostoon liittyvää informaatiota. Seuraavassa on joitakin esimerkkejä Song-luokan ominaisuuksien käytöstä: Album album = song.album; TimeSpan duration = song.duration; String name = song.name; Int32 palycount = song.playcount; Int32 rating = song.rating; Int32 tracknumber = song.tracknumber; 4.2.2 MediaPlayer-luokka MediaPlayer-luokka mahdollistaa Song-tyyppisiin objekteihin ladattujen musiikkitiedostojen soittamisen. MediaPlayer-luokassa on ominaisuuksia ja metodeja, joiden avulla musiikkitiedoston soittamista voidaan hallita (Play(), Pause(), Stop(), Resume(), jne.) MediaPlayer-luokassa on seuraavat ominaisuudet: o GameHasControl o IsMuted o IsRepeating o IsShuffled o IsVisualizationEnabled o PlayPosition o Queue o State o Volume MediaPlayer-luokassa on edellä esitettyjen ominaisuuksien lisäksi seuraavat metodit: o GetVisualizationData() o MoveNext() o MovePrevious() o Pause() o Play() o Resume() o Stop() Song-luokan tyyppiseen objektiin ladattu musiikkitiedosto voidaan soittaa MediaPlayer-luokan avulla seuraavalla tavalla: MediaPlayer.Play(song); www.stickmansoft.com 109

4.2.2.1 XnaSoundMp3-ohjelma XnaSoundsMp3-ohjelma on esimerkki siitä, kuinka XNA-peliohjelmassa voidaan soittaa.wav-formaatissa olevia äänitiedostoja. Ohjelmassa soitetaan yhtä.mp3- formaatissa olevaa äänitiedostoa. Äänitiedoston soittaminen suoritetaan Song- ja MediaPlayer-luokan avulla. Soittaminen käynnistetään painamalla Xbox 360 - peliohjaimen nappia A (Play). Soittaminen pysähtyy painamalla nappia B (Stop). Soittaminen keskeytyy painamalla nappia X (Pause). Soittaminen jatkuu keskeytyksen jälkeen painamalla nappia Y (Resume). Edellä mainittujen toimintojen lisäksi näytölle tulostetaan kappaleen kokonaiskesto ja kuinka kauan kappletta on jo soitettu. Ohjelma koostuu Program.cs- ja XnaGame.cs-tiedostosta sekä Piano.mp3-äänitiedostosta ja XnaFont.spritefont-fonttitiedostosta. Seuraavassa on esitelty edellä mainittujen lähdetekstitiedostojen sisältämät ohjelmakoodit. Program.cs Program.cs-lähdetekstitiedosto sisältää Main()-metodin eli ohjelman aloituskohdan. Kuvassa 4-7 on esitetty Program.cs-tiedoston ohjelmakoodi. /* Program.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; namespace XnaGame static class Program static void Main(string[] args) using (XnaGame game = new XnaGame()) game.run(); XnaGame.cs Kuva 4-7. XnaSoundMp3-ohjelman Program.cs-tiedosto. XnaGame.cs-lähdetekstitiedosto sisältää edellä mainitut Xbox 360 -peliohjaimen käsittelyssä ja äänitiedoston soittamisessa tarvittavat ohjelmarakenteet. Kuvassa 4-8 on esitetty XnaGame.cs-tiedoston ohjelmakoodi. 110 XNA Peliohjelmointi

/* XnaGame.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace XnaGame public class XnaGame : Microsoft.Xna.Framework.Game // HW GraphicsDeviceManager graphics; SpriteBatch spritebatch; // Screen static int windowheight = 160; static int windowwidth = 270; Rectangle titlesafearea; // Text SpriteFont infofont; // GamePad GamePadState gamepadstate; // Sounds Song song; public XnaGame() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Set default screen width and height. graphics.preferredbackbufferheight = windowheight; graphics.preferredbackbufferwidth = windowwidth; graphics.applychanges(); // Screen Window.Title = "XnaSoundsMP3"; www.stickmansoft.com 111

protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); protected override void LoadContent() // Screen titlesafearea = GraphicsDevice.Viewport.TitleSafeArea; // Create a new SpriteBatch, which // can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Text infofont = Content.Load<SpriteFont>( "Fonts\\XnaFont"); // Sounds song = Content.Load<Song>("Audio\\Mp3\\Piano"); protected override void UnloadContent() // TODO: Unload any non ContentManager content here protected override void Update(GameTime gametime) // Allows the game to exit if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape) GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); // Read the GamePad state. gamepadstate = GamePad.GetState(PlayerIndex.One); // Sounds if (gamepadstate.buttons.a == ButtonState.Pressed) MediaPlayer.Play(song); 112 XNA Peliohjelmointi

if (gamepadstate.buttons.b == ButtonState.Pressed) MediaPlayer.Stop(); if (gamepadstate.buttons.x == ButtonState.Pressed) MediaPlayer.Pause(); if (gamepadstate.buttons.y == ButtonState.Pressed) MediaPlayer.Resume(); base.update(gametime); protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.White); spritebatch.begin(); spritebatch.drawstring(infofont, "Play - Press button 'A'", new Vector2(10.0f, 10.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, "Stop - Press button 'B'", new Vector2(10.0f, 30.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, "Pause - Press button 'X'", new Vector2(10.0f, 50.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, "Resume - Press button 'Y'", new Vector2(10.0f, 70.0f), new Color(0, 0, 0)); spritebatch.end(); spritebatch.begin(); spritebatch.drawstring(infofont, "Name: " + song.name, new Vector2(10.0f, 110.0f), new Color(0, 0, 0)); spritebatch.drawstring(infofont, CreateTimeString( MediaPlayer.PlayPosition) + " / " + CreateTimeString(song.Duration), new Vector2(10.0f, 130.0f), new Color(0, 0, 0)); spritebatch.end(); base.draw(gametime); www.stickmansoft.com 113

public string CreateTimeString(TimeSpan TimeData) int Minutes = TimeData.Minutes; int Seconds = TimeData.Seconds; if (Seconds < 10) return Minutes + ":0" + Seconds; else return Minutes + ":" + Seconds; Kuva 4-8. XnaSoundMp3-ohjelman XnaGame.cs-tiedosto. Kun XnaSoundMp3-projektin toteuttaa, suorittaa ohjelman kääntämisen ja käynnistää ohjelman, niin kuvan 4-9 mukainen ikkuna aukeaa näytölle. Kuva 4-9. XnaSoundMp3-ohjelman ohjelmaikkuna. 4.3 Cross-Platform Audio Creation Tool XNA Game Studio -ohjelmiston mukana tulee Microsoftin Cross-Platform Audio Creation Tool -työkaluohjelmisto (XACT-ohjelma). XACT-ohjelmaa käytetään äänitiedostojen hallintaan ja organisointiin sekä pelissä käytettävien äänitehosteiden ja musiikin suunnitteluun. XACT-ohjelman avulla XNA-peliohjelmaa varten voidaan paketoida valmiita äänitiedostoja sopiviksi kokonaisuuksiksi, jotka saadaan Content Pipeline -prosessiin mukaan ja tätä kautta XNA-peliohjelman käyttöön. XACT-ohjelma mahdollistaa äänitiedostojen paketoinnin lisäksi sen, että paketoitujen musiikki- ja 114 XNA Peliohjelmointi

äänitiedostojen soittamista voidaan säätää yksinkertaisten efektien avulla. Esimerkiksi, äänenkorkeutta (Pitch) ja äänenvoimakkuutta (Volume) voidaan säätää. Vaikka XACTohjelma mahdollistaa edellä mainittujen kaltaisten efektien lisäämisen soitettaviin ääniin, niin tästä huolimatta XACT-ohjelma ei ole kuitenkaan äänitiedostojen editointiohjelma. XACT-ohjelma vastaanottaa valmiita äänitiedostoja ja muokkaa näistä paketteja, joita voidaan ottaa XNA-peliohjelmassa käyttöön. XACT-ohjelma on näin ennemminkin äänitiedostojen ryhmittely-, organisointi-, hallinta- ja suunnittelutyökalu, joka helpottaa XNA-peliohjelmissa monimutkaisten äänimaailmojen toteuttamista. XACT-ohjelma paketoi musiikki- ja äänitiedostot XACT-projektitiedostoon (.xap). XACT-projektitiedosto on sellaisessa muodossa, jonka Content Pipeline pystyy käsittelemään. Tällä tavalla musiikki- ja äänitiedostot saadaan XNA-peliohjelmassa käyttöön. XACT-ohjelmalla voidaan paketoida WAV (.wav), AIFF (.aif) ja XMA (.xma) formaatissa olevia äänitiedostoja. XACTprojektitiedostoon paketoitujen äänitiedostojen soittamiseen XNA Framework - luokkakirjastossa on Audio API -rajapinta. Kuvassa 4-10 on esitetty kaavio äänitiedostojen soittamisen eri vaiheista XNA-peliohjelmissa, kun äänitiedostot paketoidaan XACT-ohjelman avulla. Kuva 4-10. Kaavio äänitiedostojen soittamisen eri vaiheista XNA-peliohjelmassa, kun äänitiedostot paketoidaan XACT-ohjelman avulla. 4.3.1 XACT-projektitiedosto XACT-projektitiedoston tekeminen tarkoittaa sitä, että XACT-ohjelman avulla suoritetaan XNA-peliohjelmassa tarvittavien musiikki- ja äänitiedostojen paketointi yhdeksi XACT-projektitiedostoksi. XACT-projektitiedosto on tekstitiedosto, joka sisältää tiedot pelissä käytettävistä äänitiedostoista sekä äänitiedostojen soittamiseen liittyvästä soittoinformaatiosta. Kun tämä XACT-projektitiedosto otetaan XNApeliprojektiin mukaan lähdetekstitiedostona ja käännetään projektin mukana eli ContentPipeline käsittelee tiedoston, niin saadaan generoitua seuraavat kolme tiedostoa. o Wave Bank (.xwb) www.stickmansoft.com 115

o Sound Bank (.xsb) o General settings (.xgs) Wave Bank (Aaltopankki) Wave Bank -tiedosto pitää sisällään äänitiedostoja (wav, aif jne.). Wave Bank - tiedostoja voi yhdessä XNA-peliohjelmassa olla yksi tai useampia. Yksi Wave Bank - tiedosto voi sisältää yhden tai useamman äänitiedoston. Wave Bank -tiedostojen yksi keskeisin tarkoitus on se, että eri äänitiedostot saadaan ryhmitelty käyttötarkoituksiensa mukaan. Esimerkiksi, yhteen Wave Bank -tiedostoon voitaisiin sijoittaa sellaiset äänitiedostot, jotka tulee olla koko ajan muistissa ja toiseen voitaisiin sijoittaa sellaiset äänitiedostot, jotka ladataan muistiin aina tarvittaessa eli näiden ei tarvitse olla koko ajan käytettävissä. Sound Bank (Äänipankki) Äänipankki sisältää informaation siitä, kuinka aaltopankissa olevia äänitiedostoja soitetaan. Äänitiedostossa on esimerkiksi tietoja soittoäänien taajuuksista, tiedostojen soiton ajoituksista sekä äänitiedostojen soittosekvensseistä. Sound Bank -tiedosto koostuu soittoäänistä ja soittorepliikeistä (Cues) sekä näiden soittoinformaatiosta. Aaltopankkien ja äänipankkien yksi keskeisimmistä tarkoituksista on se, että näiden avulla soitettavat äänet voidaan ryhmitellä loogisiksi kokonaisuuksiksi. Sound Bank - tiedosto ei kuitenkaan sisällä varsinaisia äänitiedostoja, vaan ainoastaan tiedon siitä mikä tai mitkä soittoäänet kuuluvat kuhunkin soittorepliikkiin (Cue) ja tiedon siitä, kuinka äänitiedostot soitetaan. Soittoäänet eli äänitiedostot ovat yhdessä tai useammassa Wave Bank -tiedostossa. Tätä kautta Sound Bank ja Wave Bank ovat sidoksissa toisiinsa. Sound Bank -tiedostoja voi XNA-peliohjelmassa olla useita. General settings (Soittoasetukset) Yleiset asetukset -tiedosto sisältää sellaisia asetuksia, joita ei ole yksinomaan sidottu joko Wave Bank - tai Sound Bank -tiedostoon. Esimerkiksi, voidaan määrittää soittoäänien ryhmä ja sitten muuttaa tähän ryhmään kuuluvien soittoäänien äänen voimakkuuksia yhdellä asetuksella, jolloin kaikkien ryhmän soittoäänien äänen voimakkuus nousee tai laskee. 4.3.1.1 XACT-projektitiedoston luonti XACT-projektitiedosto luodaan XACT-työkalulla. Kun XACT-työkalun käynnistää, niin kuvan 4-11 mukainen ikkuna aukeaa näytölle. XACT-projektitiedosto luodaan siten, että XACT-työkalussa suoritetaan seuraavat menuvalinnat: File -> New Project. Tämän jälkeen kuvaruudulle aukeaa New Project Path -dialogi, jossa projektille valitaan hakemisto ja annetaan nimi. Lopuksi klikataan Save-nappia, jolloin valittuun hakemistoon luodaan.xap-formaatissa oleva XACT-projektitiedosto. 116 XNA Peliohjelmointi

Kuva 4-11. XACT-ohjelman pääikkuna. XACT-projektitiedoston luomisen jälkeen projektitiedostoon voidaan luoda Wave Bank -tiedostoja eli aaltopankkeja. Aaltopankin saa tehtyä siten, että Wave Banks -valikosta valitsee New Wave Bank -valinnan. Toinen vaihtoehto on se, että klikkaa hiiren vasemman puoleisella napilla XACT-ohjelman vasemmassa reunassa näkyvässä tiedostopuussa olevaa Wave Banks -kansiota ja esiin tulevasta Popup-valikosta valitsee New Wave Bank -valinnan. Tällöin XACT-ohjelman pääikkunan työalueelle aukeaa kuvan 4-12 mukainen Wave Bank -ikkuna. Kuva 4-12. Wave Bank -ikkuna. www.stickmansoft.com 117

Oletuksena aaltopankki saa nimekseen Wave Bank. Aaltopankin nimen voi muuttaa sopivammaksi siten, että hiiren oikeanpuoleisella napilla klikka XACT-ohjelman pääikkunan vasemmalla reunalla näkyvän tiedostopuun Wave Banks -kansion alle luotua Wave Bank -tiedostoa ja Rename-toiminnolla vaihtaa nimen. Kuvassa 4-12 esitetyn aaltopankin nimeksi on annettu Xna Wave Bank. Aaltopankki tarvitsee kaverikseen Sound Bank -tiedoston eli äänipankin. Äänipankin saa tehtyä siten, että Sound Banks -valikosta valitsee New Sound Bank -valinnan. Toinen vaihtoehto on se, että klikkaa hiiren vasemman puoleisella napilla XACT-ohjelman vasemmassa reunassa näkyvässä tiedostopuussa olevaa Sound Banks -kansiota ja esiin tulevasta Popupvalikosta valitsee New Sound Bank -valinnan. Tällöin XACT-ohjelman pääikkunan työalueelle aukeaa kuvan 4-13 mukainen Sound Bank -ikkuna. Kuva 4-13. Sound Bank -ikkuna. Oletuksena äänipankki saa nimekseen Sound Bank. Äänipankin saa nimettyä uudelleen samaan tapaan, kuin on tehty edellä esitetyn aaltopankin uudelleen nimeäminen. Kuvassa 4-13 esitetyn äänipankin nimeksi on annettu Xna Sound Bank. Äänitiedostojen lisääminen aalto- ja äänipankkiin Äänitiedosto saadaan lisättyä aaltopankkiin siten, että viedään hiiren kursori aaltopankki-ikkunan päälle ja klikataan hiiren oikeanpuoleista nappia, jolloin näytölle aukeaa Popup-valikko. Tästä valikosta valitaan Insert Wave File(s)... -valinta, jolloin esiin aukeavan Open-dialogin avulla aaltopankkiin lisätään yksi tai useampi äänitiedosto. Äänitiedostojen lisäämisen jälkeen edellä luodun aaltopankin Xna Wave Bank -ikkuna näyttää kuvan 4-14 mukaiselta. 118 XNA Peliohjelmointi

Kuva 4-14. Xna Wave Bank -aaltopankki sisältää kolme.wav-formaatissa olevaa äänitiedostoa. Seuraavaksi aaltopankissa olevat eli Xna Wave Bank -ikkunassa punaisella näkyvät äänitiedostot raahataan äänipankin vasemmassa yläreunassa olevaan ikkunaan (Sounds frame). Tämän jälkeen äänitiedostoille voidaan luoda soittorepliikit (Cues). Soittoäänen soittorepliikin (Cue) saa luotua siten, että äänipankin vasemmassa ylänurkassa olevasta ikkunasta (Sounds frame) raahataan haluttu ääni äänipankin vasemmassa alanurkassa olevaan ikkunaan (Cues frame), jolloin äänitiedostoille luodaan automaattisesti soittorepliikki. Kuvassa 4-15 on Xna Sound Bank -ikkuna edellä mainitun operaation jälkeen, kun kaikki kolme aaltopankissa olevaa äänitiedostoa on raahattu äänipankkiin ja näille on luotu soittorepliikit. Kuva 4-15. Xna Sound Bank -ikkuna. www.stickmansoft.com 119

Äänipankki ei siis sisällä äänitiedostojen sisältämää dataa, mutta sen sijaan erilaista informaatiota siitä, kuinka äänitiedostoja soitetaan. Äänipankissa voidaan määrittää hyvin monipuolisesti se, kuinka äänitiedostojen soitto tapahtuu. Soittorepliikkien soittamista voidaan säätää esimerkiksi siten, että klikataan äänipankin vasemmassa ylänurkassa olevassa ikkunassa jokin äänitiedosto valituksi. Tämän jälkeen klikataan äänipankin oikeassa ylänurkassa olevassa ikkunassa Play Wave -teksti aktiiviseksi. Tämän jälkeen XACT-ohjelman pääikkunan vasemmassa alareunassa olevassa ikkunassa tehdään halutut soittorepliikkiin liittyvät asetukset. Esimerkiksi, näissä asetuksissa kyseisen soittorepliikin Looping-säätö voitaisiin asettaa tilaan Infinite. Tämä tarkoittaisi sitä, että kun XNA-peliohjelmassa kyseisen äänitiedoston soitto käynnistettäisiin, niin sitä soitettaisiin luupissa uudelleen ja uudelleen kertasoiton asemasta siihen saakka, kunnes sen soittaminen ohjelmassa pysäytetään. Edellä mainitun kaltaisten asetusten tekemisen lisäksi XACT-ohjelma mahdollistaa äänitiedostojen monipuolisen organisoinnin ja hallinnan sekä pelissä soitettavien äänitehosteiden ja musiikin kokonaisvaltaisen suunnittelun. Lopuksi XACTprojektitiedosto nimetään sopivaksi esimerkiksi XnaAudio.xap ja talletetaan sopivaan paikkaan. Tämän jälkeen, kun XNA-ohjelmassa halutaan käyttää XACTprojektitiedostoon paketoituja äänitiedostoja, niin riittää kun XACT-projektitiedosto eli tässä tapauksessa XnaAudio.xap otetaan XNA-peliohjelmaprojektiin mukaan yhtenä projektitiedostona. Tämän jälkeen XACT-projektitiedostoon paketoituja äänitiedostoja voi soittaa peliohjelmassa Audio API:n avulla. 4.3.1.2 Äänitiedostojen soittaminen XACT-ohjelmasta Äänitiedostoja voidaan soittaa suoraan myös XACT-ohjelmassa. Tämä edellyttää sitä, että XNA Game Studio -ohjelmiston mukana tuleva XACT Auditioning Utility - ohjelma on oltava käynnissä samaan aikaan, kun XACT-ohjelmassa soitetaan äänitiedostoja. Kuvassa 4-16 on esitetty XACT Auditioning Utility -ohjelman ohjelmaikkuna. Kuva 4-16. XACT Auditioning Utility -ohjelman ohjelmaikkuna. 120 XNA Peliohjelmointi

XACT-ohjelmassa äänitiedoston soittaminen voidaan käynnistää esimerkiksi siten, että ensin hiirellä valitaan soitettava äänitiedosto ja tämän jälkeen käynnistetään soitto painamalla Space-nappia. Soittamisen saa pysäytettyä painamalla Esc-nappia. Soittamisen voi käynnistää ja pysäyttää myös XACT-ohjelman menuvalikon kautta. Näiden tapojen lisäksi soittamisen voi aloittaa ja lopettaa myös siten, että klikkaa hiiren vasemman puoleisen napin avulla soitettavan äänitiedoston päällä, jolloin esiin aukeaa dialogi, josta soiton voi käynnistää Play-valinnalla ja pysäyttää Stop-valinnalla. 4.3.2 Audio API -ohjelmointirajapinta Edellisessä osiossa esitettiin kuinka XACT-projektitiedosto tehdään ja kuinka siihen lisätään äänitiedostoja ja kuinka äänitiedostoihin voi tehdä soittoon liittyviä asetuksia. Tuloksena saatiin XACT-projektitiedosto (XnaAudio.xap). Tässä osiossa esitetään kuinka XACT-projektitiedostoon paketoidut äänitiedostot otetaan käyttöön ja kuinka niitä soitetaan XNA-peliohjelmassa. XACT-projektitiedostoon paketoidut äänitiedostot saadaan XNA-peliohjelmassa käyttöön siten, että XACT-projektitiedosto otetaan XNApeliohjelmaprojektissa mukaan yhtenä lähdetekstitiedostona. Kuvassa 4-17 on esitetty myöhempänä esitettävän XnaSoundXACT-ohjelman projektitiedostot Solution Explorer -ikkunassa, jossa yhtenä tiedostona muiden mukana on XnaAudio.xap. Kuva 4-17. XnaSoundXACT-ohjelman Solution Explorer -ikkuna. www.stickmansoft.com 121

XACT-projektitiedostot ovat tekstitiedostoja ja niille suoritetaan kääntäminen muiden lähdetekstitiedostojen tapaan. Kääntämisen yhteydessä generoidaan aaltopankki- (.xwb), äänipankki- (.xsb) ja soittoasetukset tiedosto (.xgs). Tämän jälkeen XACTtiedostoon paketoidut äänitiedostot voidaan ottaa XNA-peliohjelmassa käyttöön. Äänitiedostojen käyttöönotto XACT-projektitiedoston kääntämisen jälkeen generoidut äänitiedostot saadaan ladattua XNA-peliohjelman käyttöön siten, että soitonasetus- (.xgs), aaltopankki- (.xwb) ja äänipankkitiedostoa (.xsb) varten luodaan audio-objektit, joihin edellä mainittujen tiedostojen sisältö ladataan. Ennen audio-objektien luontia ohjelmassa on määritettävä näitä varten muuttujat esimerkiksi seuraavalla tavalla: AudioEngine audioengine; WaveBank wavebank; SoundBank soundbank; Muuttujien määrittämisen jälkeen voidaan suorittaa audio-objektien luonti. Ensin on luotava soittoasetukset sisältävä audio-objekti eli AudioEngine-tyyppinen objekti. Tämän avulla päästään luomaan WaveBank- ja SoundBank-objekti. audioengine = new AudioEngine("Content\\Audio\\XnaAudio.xgs"); wavebank = new WaveBank(audioEngine, "Content\\Audio\\Xna Wave Bank.xwb"); soundbank = new SoundBank(audioEngine, "Content\\Audio\\Xna Sound Bank.xsb"); Kun soittoasetus-, aaltopankki- ja äänipankki-objektit on luotu, niin kaikki XACTprojektitiedostoon XACT-ohjelmalla pakatut äänitiedostot, soittorepliikit (Cues) ja soittamiseen liittyvät asetukset ovat XNA-peliohjelman käytettävissä Sound API - rajapinnan kautta. SoundBank-luokka XACT-projektitiedostoon paketoitujen äänitiedostojen soittaminen voidaan suorittaa suoraan SoundBank-luokan avulla. Tällöin tiedostojen soittaminen vaatii hyvin vähän ohjelmakoodia. Ohjelmassa yksinkertaisesti kutsutaan SoundBank-objektin suhteen SoundBank-luokassa olevaa PlayCue-metodi, jolle välitetään parametrina minkä niminen soittorepliikki soitetaan. soundbank.playcue("helicopter"); Tässä menetelmässä varjopuolena on se, että kun soittaminen on aloitettu, niin soittamisen kontrollointi on ohjelmallisesti hyvin rajoitettua. XACT-projektitiedostoon pakattu soittamiseen liittyvä soittoinformaatio ohjaa tällöin pääasiassa soittamista. 122 XNA Peliohjelmointi

Cue-luokka Cue-luokan eli soittorepliikkiluokan avulla soittamisen kontrollointi on monipuolisempaa. Tällöin soittamista voidaan ohjata paremmin myös Sound API - rajapinnan kautta. Voidaan esimerkiksi tutkia onko soitto käynnissä, voidaan keskeyttää ja jatkaa soittamista uudelleen. Cue-luokkaa käytettäessä tarvitaan Cue-tyyppinen muuttuja. Cue cue = null; Kun Cue-tyyppinen muuttuja on luotu, niin SoundBank-objektin suhteen voidaan kutsua SoundBank-luokan GetCue()-metodia ja valita näin soittorepliikki sekä käynnistää soittorepliikki Play()-metodilla. cue = soundbank.getcue("alarm"); cue.play(); Soittaminen voidaan keskeyttää Cue-luokassa olevan Pause()-metodin avulla. cue.pause(); Pause()-metodilla pysäytettyä soittoa voidaan jatkaa Cue-luokassa olevan Resume()- metodin avulla. cue.resume(); Soittaminen voidaan pysäyttää Cue-luokassa olevalla Stop()-metodilla. cue.stop(); Edellä mainittujen metodien lisäksi Cue-luokassa on myös joitakin muita metodeja soittorepliikkien käsittelyä varten. Metodien lisäksi Cue-luokassa on seuraavat ominaisuudet soittorepliikkien soittamisen hallintaa varten: o Name o IsCreated o IsDisposed o IsPaused o IsPlaying o IsPrepared o IsPreparing o IsStopped o IsStopping Edellä luetelluista ominaisuuksista Name-ominaisuus palauttaa soittorepliikin nimen. Muut ominaisuudet eli Is-alkuiset ominaisuudet kertovat jotakin soittorepliikin tilasta. Nämä Is-alkuiset soittorepliikit palauttavat arvon true tai false riippuen siitä, missä tilassa soittorepliikki on kyseisellä hetkellä. Esimerkiksi, Cue-luokan IsPalying- www.stickmansoft.com 123

ominaisuuden avulla voidaan selvittää se, ollaanko soittorepliikkiä parhaillaan soittamassa vai ei. if (cue.isplaying) // Playing is in progress! AudioEngine-luokka AudioEngine-objektin suhteen täytyy jokaisen pelisyklin (Frame) aikana kutsua kerran AudioEngine-luokan Update()-metodia. Update()-metodi pitää yllä äänitiedostojen soittamiseen liittyviä audio-toimintoja. // Performs periodic work required by the audio engine. This method // drives the audio engine, and must be called once per frame. audioengine.update(); WaveBank-luokka WaveBank-luokka sisältää joitakin ominaisuuksia ja metodeja, joita voidaan käyttää soitonhallinnassa. WaveBank-luokkaa ei tavallisesti kuitenkaan tarvita enää WaveBank-objektin luonnin jälkeen. Tästä huolimatta WaveBank-objekti on kuitenkin luotava, jotta äänitiedostot tulevat ohjelman käytettäväksi eli liitettyä AudioEngineobjektiin. 4.3.2.1 XnaSoundXACT-ohjelma XnaSoundXACT-ohjelma on esimerkki siitä, kuinka XNA-peliohjelmissa voidaan soittaa äänitiedostoja. Ohjelmassa käytetään kahta äänitiedostoa Alarm.wav ja Helicopter.wav. Nämä äänitiedostot on paketoitu XACT-projektitiedostoon nimeltään XnaAudio.xap. Ohjelman käynnistyessä SoundBank-luokan PlayCue()-metodilla käynnistetään taustaäänen soittaminen (Helicopter.wav). XACT-projektitiedostossa taustaäänen soittoasetuksissa tiedosto on määritetty soitettavaksi ikiluupissa. Toista soittoääntä (Alarm.wav) soitetaan ohjelmassa aina silloin, kun Xbox 360 -peliohjaimen A -nappi on alas painettuna. Ohjelman koostuu Program.cs ja XnaGame.cs lähdetekstitiedostoista, Background.bmp-kuvatiedostosta sekä XnaAudio.xapprojektitiedostosta. Seuraavassa on esitelty edellä mainittujen lähdetekstitiedostojen sisältämät ohjelmakoodit. Program.cs Program.cs-lähdetekstitiedosto sisältää Main()-metodin eli ohjelman aloituskohdan. Kuvassa 4-18 on esitetty Program.cs-tiedoston ohjelmakoodi. 124 XNA Peliohjelmointi

/* Program.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; namespace XnaGame static class Program static void Main(string[] args) using (XnaGame game = new XnaGame()) game.run(); XnaGame.cs Kuva 4-18. XnaSoundXACT-ohjelman Program.cs-tiedosto. XnaGame.cs-lähdetekstitiedosto sisältää edellä mainitut Xbox 360 -peliohjaimen käsittelyssä ja äänitiedoston soittamisessa tarvittavat ohjelmarakenteet. Kuvassa 4-19 on esitetty XnaGame.cs-tiedoston ohjelmakoodi. /* XnaGame.cs Copyright Markku Rahikainen. www.stickmansoft.com */ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace XnaGame public class XnaGame : Microsoft.Xna.Framework.Game www.stickmansoft.com 125

// HW GraphicsDeviceManager graphics; SpriteBatch spritebatch; // Screen static int windowheight = 200; static int windowwidth = 300; Rectangle titlesafearea; // Graphics Texture2D backgroundtexture; Vector2 backgroundposition; // GamePad GamePadState gamepadstate; // Sounds AudioEngine audioengine; WaveBank wavebank; SoundBank soundbank; Cue cue = null; public XnaGame() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Set default screen width and height. graphics.preferredbackbufferheight = windowheight; graphics.preferredbackbufferwidth = windowwidth; graphics.applychanges(); // Screen Window.Title = "XnaSoundXACT"; protected override void Initialize() // Graphics backgroundposition = new Vector2(0, 0); base.initialize(); protected override void LoadContent() // Screen titlesafearea = GraphicsDevice.Viewport.TitleSafeArea; // Create a new SpriteBatch, which // can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); 126 XNA Peliohjelmointi

// Graphics backgroundtexture = Content.Load<Texture2D>( "Graphics\\Background"); // Sounds audioengine = new AudioEngine( "Content\\Audio\\XnaAudio.xgs"); wavebank = new WaveBank(audioEngine, "Content\\Audio\\Xna Wave Bank.xwb"); soundbank = new SoundBank(audioEngine, "Content\\Audio\\Xna Sound Bank.xsb"); // Start playing the background sound. soundbank.playcue("helicopter"); protected override void UnloadContent() // TODO: Unload any non ContentManager content here protected override void Update(GameTime gametime) // Allows the game to exit. if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape) GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); // Read the GamePad state. gamepadstate = GamePad.GetState(PlayerIndex.One); // If 'A' button is pressed play the effect sound. if (gamepadstate.buttons.a == ButtonState.Pressed) if (cue == null) cue = soundbank.getcue("alarm"); cue.play(); else if (cue.ispaused) cue.resume(); www.stickmansoft.com 127

else if (cue!= null && cue.isplaying) cue.pause(); // Performs periodic work required by the audio // engine. This method drives the audio engine, // and must be called once per frame. audioengine.update(); base.update(gametime); protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.DarkSlateBlue); // Draw the background. spritebatch.begin(); spritebatch.draw(backgroundtexture, backgroundposition, Color.White); spritebatch.end(); base.draw(gametime); Kuva 4-19. XnaSoundXACT-ohjelman XnaGame.cs-tiedosto. Kun XnaSoundXACT-projektin toteuttaa, suorittaa ohjelman kääntämisen ja käynnistää ohjelman, niin kuvan 4-20 mukainen ikkuna aukeaa näytölle. 128 XNA Peliohjelmointi

Kuva 4-20. XnaSoundXACT-ohjelman ohjelmaikkuna. www.stickmansoft.com 129

130 XNA Peliohjelmointi