XACT 3.0 Content DrivenThis page describes how to use the full features of XACT with the audio creation tool. This is the normal way to use XACT but to use the XACT API purely from code see the XACT code driven notes. For a break down of XACT file types and terminology see below. XACT Audio Creation ToolThe SDK comes with a tool for use by designers in creating and managing the sound effects of the game. It allows waves to be loaded into a wave bank. These are the core building blocks of your sounds. You then create sounds in sound banks that can use the waves in different ways e.g. you can simply play the sound as is or could alter its pitch, apply effects etc. The tool is fairly intuitive to use as you can just drag and drop and right click to add items. A basic set of steps for a basic sound from one wav may be: - Right click on Wave Banks and select "New Wave Bank"
- Drag a sound file on to the Wave Bank window e.g. a wav file. It will appear in red italics until it is used.
- Right click on Sound Banks and select "New Sound Bank". you may want to rearrange the windows here a bit so you can see both
- Right click in the Sound Bank window and select "New Sound" and give it a new name if required
- Right click on the New Sound and select "New Track"
- Right click on Track 1 and select Add Event -> Play Wave
- Drag the wave file from the Wave Bank window on to the Play Wave event, it should get added as with the drumroll in the screenshot above
- Right click in the Cue part of the Sound Bank window and select New Cue. It will add a New Cue which you can rename as required
- Drag your New Sound onto the right hand area to the right of the cue name. This links the cue to the sound.
- From the File menu select Build, it will create two directories called Win and Xbox within the folder the tool's project file is (.xap). Within the win directory you will find a .xwb file which is the wave bank, a .xsb file which is the sound bank and a .xgs file which contains settings (see file types below).
To write the code to load the sounds into your application see the next section. Code for playing back XACT soundsOnce you have created the required wave bank (.xwb) and sound bank (.xwb) files from the content tool you are ready to load these into your game for play back. Firstly you need to include <xact3.h>. Note: there is no specific library file for XACT (unlike other DirectX APIs) but note that the choice of dll (debug or not) is controlled via the DirectX Control Panel. Starting the XACT EngineWhen your application starts up you need to create and initialise the XACT engine. XACT, under Windows, uses the COM object model like other DirectX APIs however unlike them you need to make sure COM is initialised first. Note that if you are using other DirectX APIs like Direct3D you may have already initialised COM. CoInitializeEx(NUILL, COINT_MULTITHREADED); The next step is to create the XACT engine. The function prototype is: HRESULT XACT3CreateEngine(DWORD dwCreationFlags,IXACT3Engine **ppEngine) This function takes some flags and creates the XACT engine. If successful it creates an engine instance and assigns your provided pointer to it. This pointer then gives you access to the important XACT functions. The flags can be XACT_FLAG_API_AUDITION_MODE or XACT_FLAG_API_DEBUG_MODE. Note that for debug mode you need to also set XACT to debug libraries via the DirectX control panel. To audition sounds you need to also use the Audio Console tool (I have not tried this myself yet). You will need to create a pointer for the engine object and keep this until your game shuts down e.g. IXACT3Engine *m_XACT3Engine;
if (FAILED(XACT3CreateEngine( 0, &m_XACT3Engine ))) return false; Note that all the XACT calls return a HRESULT (just like in Direct3D) and these codes should be tested for failure. For clarities sake though from now on I will exclude them from the sample code. Next we need to initialise XACT. This is achieved via the initialise interface member function of the XACT engine. This function takes the address of an engine parameters structure that you can fill to set a number of global settings including enabling 3D audio and setting music and sound volumes. If you wish you can also load settings from the tool generated .xgs file. Defaults are used below: XACT_RUNTIME_PARAMETERS EngineParameters = {0}; m_XACT3Engine->Initialize( &EngineParameters ) ; Loading the Wave Bank (.xwb)At the beginning of your game, or perhaps the beginning of each level, you will want to load in the sounds you created using the tool described above. You need to load in the wave banks and the sound banks. You need to point XACT at the wave bank data. This leaves you with a couple of options. you could load the whole file into memory or you could stream the sounds from disk. XACT supports both methods via its CreatinInMemoryWaveBank and CreateStreamingWaveBank functions. More work is involved with streaming and also there are potential problems including performance issues so I tend to prefer to load the file into memory. However as you can imagine a wave bank file can get extremely big and using new and loading it all into memory will take time and will use a lot of memory. An alternative approach is therefore to use the file memory mapping facilities in Windows. Windows memory mapping allows you to treat a file on disk as if it were in memory. The OS in the background will handle loading blocks of the file into memory as required and will even keep the memory and disk images in sync (should you make changes). Memory mapped files are also often used to share memory between two or more processes. In the example below I use memory mapping to load the wave file: // Get a handle to the file HANDLE hFile = CreateFile( waveBankFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return false;
// Get the file size DWORD dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize == -1 ) return false;
// Map the file into memory HANDLE hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL ); if( !hMapFile ) return false;
// Get a mapping pointer to the file data m_waveBankMapping = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if (!m_waveBankMapping) return false; We now have a pointer to the mapped file called m_waveBankMapping. You need to keep this so you can unmap the memory when you have finished with it (via the UnmapViewOfFile function). This pointer can now be used in a call to the XACT function to create the wave bank. The function if successful assigns your pointer to a wave bank to an instance of a wave bank object. This needs to be kept until the end as well. IXACT3WaveBank* m_waveBank; m_XACT3Engine->CreateInMemoryWaveBank(m_waveBankMapping,dwFileSize,0,0,&m_waveBank); Note: you can now close the file handles as they are no longer needed CloseHandle( hMapFile ); CloseHandle( hFile ); Loading the Sound Bank (.xsb)The sound bank does not need to be file memory mapped as it is always quite small. The following code shows how to load it using normal Windows file handling functions: HANDLE hFile = CreateFile( soundBankFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (hFile==INVALID_HANDLE_VALUE) return false;
DWORD dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize == -1 ) return false;
// Allocate memory, only delete it when sound bank destroyed m_soundBankMemory = new BYTE[dwFileSize]; EsAssert(m_soundBankMemory);
DWORD bytesRead; if (ReadFile( hFile, m_soundBankMemory, dwFileSize, &bytesRead, NULL )!=0) { You now need to call the XACT engine CreateSoundBank function to create the sound bank itself. This function, if successful, will return a pointer to the sound bank object. m_XACT3Engine->CreateSoundBank(m_soundBankMemory, dwFileSize, 0,0, &m_soundBank ) Note: the flags are only used on the XBox 360 so set to 0 here. Finally remember to close the file now you have finished with it: CloseHandle( hFile ); Playing SoundsXACT needs to be updated regularly. To do this you call the DoWork() function each game loop e.g. m_XACT3Engine->DoWork(); To trigger playback of a sound you can use the Cue name that was specified in the authoring tool. XACT provides a function to return the index of the sound from its Cue name e.g. if you made a Cue name "explosion": XACTINDEX cueIndex=m_soundBank->GetCueIndex("explosion"); You can then play the sound by calling the Play function of the sound bank object as shown below. Note that for speed you would want to look up the indexes of all your cues in advance and store them. m_soundBank->Play(cueIndex,0,0,NULL); The above simply plays the sound to completion and then stops. The third parameter is an optional time offset into the cue (in milliseconds). This call works fine as it is but for more control you can prepare the Cue in advance and get an IXACT3Cue object back from the call that allows you to query the state of the sound, access variables, pause, play and stop the sound. There is a lot of power in this especially with respect to the variables as for example you could control the pitch of an engine sound based on a speed variable in your game, Hopefully in the future I will be able to add more notes on this. For most sounds the above will be all you need to do but if you wish to stop the sound before completion you can call: m_soudBank->Stop(cueIndex,0); Cleaning UpBefore closing your program needs to clean up behind itself. The main thing is to shut down the engine, unmap any filememory maps e.g. if (m_XACT3Engine) { m_XACT3Engine->ShutDown(); m_XACT3Engine->Release(); }
delete []m_soundBankMemory;
if (m_waveBankMapping) UnmapViewOfFile(m_waveBankMapping);
CoUninitialize(); XACT Terminology and File Types- Content Creation Tool Projects (.xap)
- Sound Banks (.xsb) - a collection of sounds and cues.
- Sounds - a sound has one or more waves together with properties like volume and pitch. Sounds are made up of tracks.
- Tracks - tracks are made up events E.g. the simplest track has a Play Wave event
- Events - various actions that take place within a track. Actions include: Play, Stop, Set Volume, Set Pitch etc.
- Cues - a cue is used in code to trigger sounds. Each cue is made up of one or more sounds
- Wave Banks (.xwb ) - a file format containing a collection of waves
- Waves - the raw wave data in wav, aiff or xma format
- Global Settings (.xgs) - defines rules and settings for sounds.
- Categories - sounds can be assigned to a category (only one each) that specifies certain rules like number of instances along with settings like volume. You could create a category for the sounds of one character in your game so they all have the same volume. There are three predefined categories: global, default and Music.
- Variables - these can be defined in the design stage and then referenced by the programmer in code to control Run-Time Parameter Controls
- Run-Time Parameter Controls - also known as 'sliders'. These allow the control of sound parameters as the sound plays. For example they could be used to control the pitch of a car engine sound so as the accelerator is pressed the pitch is changed
- DSP Effect Path Presets (DSPs) - allow effects like reverb to be applied to sounds
- Compression Presets - compression can be applied to waves or wave banks
Further Reading |