• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
trinith_006

Cleanup of XAudio2 device.

6 posts in this topic

Hey all,

So I've got a question about object cleanup. I've created some sound playback functionality using SlimDX for a project I'm working on and it's working great; however I've got one hitch.

Right now I'm creating only one, static instance of my XAudio2 device that all my sounds will use to play. This is for the entire application. A while back I was having some problems with this and the advice I got was to only have once device ([url="http://www.gamedev.net/topic/618436-corruption-when-playing-sound-via-memory-stream-xaudio2/"]http://www.gamedev.n...stream-xaudio2/[/url]). This worked out well and to manage it, I created a static class called SoundEngine that would control instantiating and disposing of that XAudio2 object with the startup and shut down of my program so that everything would dispose nicely.

Now for the hitch. The product this is integrated with allows scripting and this scripting is allowed access to any DLL. This is intentional and actually fits with the goals I had in mind for this functionality. I want scripts to be able to create and play sounds. However, what I do not want is for the scripts to have access to SoundEngine, as I only want the hosting application to be able to start up and shut down the sound engine (ie, create or dispose of the XAudio2 object).

So I ran through a bunch of ideas and the simplest/easiest I could think of was to just not allow the creation/destruction of the XAudio2 object. Just create it at start up and let it get destroyed with all the other objects when the application is turned off. So I've been experimenting with this and now I'm getting the following output...

[quote]Object of type SlimDX.XAudio2.XAudio2 was not disposed. Stack trace of object creation:
Total of 1 objects still alive.[/quote]

... which makes sense. I've purposely not disposed of the XAudio2 device. So after all that rambling and backstory, my question is this: Is this a problem?

I don't intend for my device to ever get destroyed except when the application shuts down, and all my sound objects will properly dispose themselves so, under ideal circumstances, we should never see this message with more than that single object still alive. But I figured it might be a good idea to check and see if anyone had any thoughts on this and if, should any SlimDX developers be watching this forum, whether or not there could be any unintended side effects of this behaviour.

Thanks for reading, and thanks for any insight provided [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
0

Share this post


Link to post
Share on other sites
The operating system will clean up after your process exits, so it's probably not a big deal if you leave just the one object instead of disposing of it.

With that being said, I'm wondering why you can't expose a reduced sound playing API for scripts to access.
0

Share this post


Link to post
Share on other sites
Cool, that's what I was thinking too.

And the reason is that our scripting allows the use of any .NET assembly. We don't directly control what they are able to use, so there would be no way to stop them from using this functionality. Whether or not that's good, this is the way that functionality got implemented so I'll just have to work around it I guess :)

Thanks for your feedback, much appreciated!
0

Share this post


Link to post
Share on other sites
So a bit of a follow up to this... everything works great in the C# world but unfortunately there appear to be some problems in the unmanaged/managed mixed C++ world. When I run in the application I'm integrating with, I'm getting a crash message that says "string binding is invalid" along with some other dump info. I went back to disposing of my device when the program exits and still got it. Turns out I have to dispose of both the device and the mastering voice, then no crash.

I was able to boil this down to a separate project, outside the main application, that can reproduce the issue. Create a C# class library with the following code:

[code]using System;
using System.Collections.Generic;
using System.Text;

using SlimDX;
using SlimDX.XAudio2;
using SlimDX.Multimedia;

namespace TestingSlimDX
{
public class SomeTest
{
public static XAudio2 device = null;
public static MasteringVoice masteringVoice = null;

public static void PlayWarning()
{
device = new XAudio2();
masteringVoice = new MasteringVoice(device);

WaveStream waveStream = new WaveStream("c:\\temp\\warn2.wav"); // Whatever sound you want here
AudioBuffer buffer = new AudioBuffer();
buffer.AudioData = waveStream;
buffer.AudioBytes = (int)waveStream.Length;
buffer.Flags = BufferFlags.EndOfStream;

SourceVoice sourceVoice = new SourceVoice(device, waveStream.Format);

buffer.AudioData.Position = 0;
sourceVoice.SubmitSourceBuffer(buffer);
sourceVoice.Start();

while (sourceVoice.State.BuffersQueued > 0) ;

sourceVoice.Dispose();
buffer.Dispose();
//waveStream.Dispose();

//Console.Write("Disposing of mastering voice... ");
//masteringVoice.Dispose();
//Console.WriteLine("Finished.");
//Console.WriteLine();

//Console.Write("Disposing of device... ");
//device.Dispose();
//Console.WriteLine("Finished.");
//Console.WriteLine();
}
}
}[/code]

Build this, then create a new C++ console application. Use the following code:
[code]#include <iostream>
#include <windows.h>

using namespace std;
using namespace System;

using namespace TestingSlimDX;

int StartPoint(void);

//#pragma unmanaged
//int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow)
//{
// int retVal = StartPoint();
//
// return retVal;
//}

#pragma unmanaged
int main(void)
{
int retVal = StartPoint();

return retVal;
}

#pragma managed
int StartPoint(void)
{

Console::WriteLine("Starting execution of main...");
try
{
Console::WriteLine("Starting sound playback...");
SomeTest::PlayWarning();
Console::WriteLine("Sound playback complete!");
}
catch (Exception^ e)
{
Console::WriteLine("Exception occurred!" + Environment::NewLine + e->ToString());
}
Console::WriteLine("Execution of main complete.");

return 0;
}[/code]

So build the c++ application and run it. For me, I had to run it twice for some strange reason. The first run wouldn't crash, but the second would... then every run after that. If an undetermined period of time passed, it would then succeed on first run again. I have no idea how long that is... it just seems to work like that. The crash also happens after main exits, so I'm not getting any debug information out of this. I'm not sure how our application gets it either. All I get is a windows dialog saying "blahbityblah.exe has stopped working".

Now, if I change the C# code so to uncomment the disposes for device and masteringVoice, build it and then rebuild the C++ project to update the dll, no crashes at all. Everything works fine.

I've downloaded the SlimDX source and I don't see anything that would be funny... the destructors both do NULL checks before trying to dispose. I'm attempting to get it building on my machine so that I can set some breakpoints and see if I can figure it out that way but I figured I'd also post here to see if anybody else had encountered this and/or had any insights.

Thanks!
0

Share this post


Link to post
Share on other sites
I have no idea what's causing this, but I can make a few guesses that might be useful to you when trying to track it down.

My guess is that the unmanaged entry point causes the CLR to spool up in slightly different way with regards to the COM state of the thread. XAudio2 requires a CoInitialize call and when everything gets torn down at the end something might be going wrong with that.

Hope that ends up being helpful.
0

Share this post


Link to post
Share on other sites
Hmmm, perhaps... though I'm not sure why disposing of the items would cause the crash to go away.

Is SlimDX doing the CoInitialize call for XAudio2 somewhere? I searched through XAudio2.cpp and MasteringVoice.cpp and didn't get any hits. Our main application does have a CoInitialize call (and subsequent CoUninitialize at the end) and exhibits the same behvaiour as the test app, which doesn't have it's own CoInitialize calls.

(Also, I should mention, I know very little about these... the bulk of my experience is on the C# end of things but I find myself getting mixed into unmanaged C++ code :D)

I appreciate the help and if I can get the debug working maybe I'll have a bit more information, which is taking a while to set up. Yay slow networks.
0

Share this post


Link to post
Share on other sites
Just to update this...

I ran out of time and had to go with a work around solution that I'm not entirely happy with, but I guess them's the breaks. I'll try to revisit the problem at a later date and if I make any headway on it, I'll post back here.

Thanks for your help though, Mike. I appreciate the comments!
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0