I have a C# game program that i'm developing. it uses sound samples and winsock.
when i test run the game most of the audio works fine but from time to time if it is multiple samples being played sequentially the application form shakes a little bit and then goes back to its old position.
how do i go about debugging this or present it to you folks in a manageable manner? i'm sure no one is going to want the whole app code in fear of virus attacks.
please guide me..
EDIT: i have not been able to pin down any code section that produces this result. it just does and i cannot explain it.
EDIT: no the x/y position are not changing. the window like shakes around a few pixels and then goes back to the position were it was before the shake.
if (audio)
{
Stream stream;
SoundPlayer player;
stream = Properties.Resources.ResourceManager.GetStream("_home");
player = new System.Media.SoundPlayer(stream);
player.PlaySync();
player.Dispose();
string ShipID = fireResult.DestroyedShipType.ToString();
stream = Properties.Resources.ResourceManager.GetStream("_" + ShipID);
player = new System.Media.SoundPlayer(stream);
player.PlaySync();
player.Dispose();
stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
player = new System.Media.SoundPlayer(stream);
player.PlaySync();
player.Dispose();
}
can you see anything in the above code that would produce this shake?
EDIT: yes the code is being executed within a: this.Invoke(new Action(delegate(){ ....})); could this be it? how do i resolve this?
EDIT:
stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
player = new System.Media.SoundPlayer(stream);
player.PlaySync();
player.Dispose();
stream.Dispose();
if the take out the above code, then it works fine! any ideas?
EDIT: i replaced the line with:
stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
to a different file name but the problem is still there but at least it is not the audio file is corrupt.
EDIT: MSN when someone sends a nudge? it is bit like that but only happens 2 or 3 times.
EDIT: Are you using any 3rd party libraries? - no i am not using any 3rd party libs.
EDIT: it seems no matter what file, the 3rd sample always causes this.
EDIT: happens everywhere i use sound samples. if i play 3 samples, the situation happens.
EDIT: #nobugz: yes think you are right. the problem is holding up the UI thread for too long. as i have tried just using a merged audio file and the problem is there given its original duration.
EDIT: i solved this issue by putting Application.DoEvents(); after each sample play command. no shakes :)
EDIT: the above solution did not really work. as the number of player samples grew the application GUI got stuck again. a solution using QueueUserWorkItem has been employed instead. this still remains to be proven as a satisfactory solution as cross therading occurs i.e. a new thread of samples can be started while an old one is still playing.
will update this as more knowledge comes to light.
Calling PlaySync on the UI thread isn't so great. It will make your main window unresponsive as your UI thread is busy waiting for the sound to finish, it doesn't get around to pumping messages like it should do. If that takes long enough, Windows steps in and overlaps the window with a "ghost", it usually says "Not Responding" in the title bar (if it has one). This ghost window might not quite match your own window, that could explain the "shaking".
Using Play() instead will solve that problem. But gets you a new one, sequencing sounds becomes difficult. Making the calls from a thread can solve both. Check out NAudio for better control over sound.
Make a copy of your program. Delete as many game elements from the copy as possible. Remove modules, chop out game logic, shift functions between classes to reduce abstraction (so that you can delete classes), and generally hack up the game.
Each time you do so, check if the bug still exists. Initially you'll be deleting bigger chunks of the program but over time the amount of deletion will reduce.
If you find something which, when deleted, fixes the bug, there are two possibilities: Either you found the bug, or there is some sort of synergy with the rest of the program to cause the bug. In the latter case, continue deleting more of the program.
Eventually, you will end up with a minimal program that has the bug. Post that here (or in a pastebin if it's too big).
This is one of the last-resort strategies I use when I encounter a bug that I am unable to locate at all.
Related
I have a heatmap plugin integrated in my Unity VR game(with SteamVR). The plugin uses eye tracking information to generate live heatmaps as the user gazes at different elements in the game. As the heatmaps are generated, the whole camera view(user's) is overlayed with heatmaps info and written to a MP4 file using FFMPEG.
The whole process works fine. But I have an annoying problem where during the recording the user's camera view is not stable and keeps flickering and stops only when the recording is stopped. It interrupts the smooth flow of his game
For now, I've narrowed down the code which causes the trouble,
public void Write(byte[] data)
{
if (_subprocess == null) return;
_stdin.Write(data);
_stdin.Flush();
}
From my understanding, It is in this part of the code stdinput is invoked to write to the file system. So, I surmise that the problem must be with accessing the file system which in turn must have caused some time delay when each frame is written in the update method. Correct me if i am wrong here.
The loading screen which appears during every frame write looks something like above. It interrupts the smooth flow of the game and also makes the recording useless as the user keeps focusing on the flicker rather than the actual objects of interest. I would really be grateful if someone shows light on the issue here?
Accessing the file system always takes a huge amount of time. Try offloading that work to another thread or a Coroutine.
I have a single WMA file which contains lots of different pieces of audio.
Is there any way I can play part of a sound stream?
Something like:
public static void Play(Stream soundStream, long start, long end);
You may be able to do this using NAudio, it is a audio library for .Net.
Using the example here I was able to throw a quick test application up to try it. Using the WaveSteam.Skip(int seconds) method you are able to start at a specific position in the file. I have not been able to work out how to get the end position though. Below is the modified sample that starts a wma file at the 30 second mark:
IWavePlayer waveOutDevice = new WaveOut();
WaveStream mainOutputStream;
WaveChannel32 volumeStream;
WaveStream wmaReader = new WMAFileReader(#"F:\My Music\The Prodigy\Music for the Jilted Generation\01 Intro.wma");
volumeStream = new WaveChannel32(wmaReader);
mainOutputStream = volumeStream;
mainOutputStream.Skip(30); //start 30 seconds into the file
waveOutDevice.Init(mainOutputStream);
waveOutDevice.Play();
The above sample omits the cleanup code to stop playback and dispose of the streams however. Hope that helps a bit.
Not in the way you want, no.
I assume this is within a WinForms or WPF context. The solution is to host the WMP ActiveX control in your project, then load the WMA file into it and set the Position/Seek property and then play it for a while and stop it when the Timer reaches a certain point. I don't believe the WMP ActiveX control has a timer event, so you'd need to watch it on another thread and stop the playback when it's reached.
It's a hack, but should work. You should be able to get something that "works" within a few hours if you're familiar with hosting ActiveX controls within .NET applications. Note that you'll want to make your application x86-only because of compatibility issues with the 64-bit WMP ActiveX control.
The, much harder, alternative is to work with DirectShow from within your application and create a Render Graph for WMA files and do the manipulation, seeking and playback yourself. DS has a very steep learning curve, expect this to take you at least a few days to even a few weeks if you've never worked with COM before.
I'm trying to play a sound file in monotouch but it gets cut off after a second or two. Here is the code I'm using to play the sound:
SoundFileName = filename;
var sound = SystemSound.FromFile(filename);
sound.PlaySystemSound();
It's an MP3 file that I'm trying to play. Again, I hear it for a brief second and then it gets cut. I added a thread.sleep() line afterwards and THEN it'll play throughout.
But that's not ideal because the length of the mp3 files that I'm playing could vary. Any help would be greatly appreciated. Thank you.
You need to declare your sound object at the form or class level. In your posted sample, sound is only scoped to the function, so as soon as the method ends the variable goes out of scope and is disposed before the sound finished playing. Thread.sleep works because that call prevents the method from ending for a while (and thus prevents sound from going out of scope).
You may also want to look at this question: Playing a sound with MonoTouch
I don't think SystemSound is intended to use with MP3's of open duration.
I am using WebCam_Capture code I found online to access through C# a web cam. On a computer with one video source it works like a charm! (Program starts up at start up, finds the webcam and it works).
Though on a computer with many video sources (Say a web cam and then manycam running on top of that), the program starts and queries the user which source to use. I would love my program to start up autonomously at the restart of a machine so this waiting for user input throws a wrench in that, anyway I can force it to just select say the first found source and go with that?
So i have some webcam code I yes indeed found online here:
http://channel9.msdn.com/forums/TechOff/93476-Programatically-Using-A-Webcam-In-C/?CommentID=94149
and now in preparing this post I did do more research and found out that my issue lies in this line from the above code:
SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);
That is what connects the webcam up, the only issue is that the above brings up this annoying video source dialog if I have more than one source. I want it to just use the first source so that dialog doesn't come up. I tried passing in different values where the 0's are, sure enough the dialog doesn't come up but it doesn't work either. Anyone know if there is a value I can pass to the SendMessage to suspend the dialog and yet have it select the first video source it finds?
The only hint I found is that the first 0 is the camera index:
SendMessage(_windowHandle, WM_CAP_CONNECT, _videoSourceIndex, 0)
Try to give 0,1,2 until the desired camera is connected. Note it may take up to 5 sec until a webcam responds. Some of them are pretty slow.
But the best suggestion would be to try out DirectShow.NET library as it is much more capable than the API you're currently using.
I'm looking for an audio library that works with .NET that allows for smooth looping. I've tried DirectX AudioVideoPlayback and Mentalis. Both are easy to use, but the looping skips a bit. I'm wondering if that's my fault or theirs. I have sound samples that I know can loop cleanly (WinAmp can do it fine) but I can't get my C# app to do the same. What library could I use, or what could I fix in my app to get it to loop cleanly with the libraries I have?
UPDATE: FMOD has been able to loop my audio, but the problem is that the .net wrapper I have only loads files one way. I can't play a sound effect more than once because they get disposed when playback finishes, and sometimes it hangs whenever a sound is supposed to be played. I know I could just reload the sound to play it again, but I don't want to hit the disk every time a gunshot is fired. Should I just reach into the C++ layer myself and skip the .NET wrappers?
You could try FMOD which is free for non-commercial use.
I would double-check that the sound really loops cleanly - specifically, that the first sample and the last sample are close (or equal), otherwise you'll hear a click. WinAMP could conceivably do some special processing to eliminate the click.
UPDATE: FMOD comes with a whole bunch of samples in C# that show the right way to do stuff. The example called "3d" shows, among other things, a cleanly looping sound. You should be able to rip out the code that handles the looping without utilising the 3D features.