• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

"GaugeSound.dll Mystery Solved... Sorta..."

n4gix

Resource contributor
Messages
11,674
Country
unitedstates
As those who've ever "converted" an EasyGauge project to a multi-gauge knows,
one of the problems I (and everyone else) have encountered when trying to use
the GaugeStopSound function in MSVC++ is that -well- the darn sound won't stop!

I spent most of today trying to find out why the function works when compiled
with MinGW (a la EasyGauge) but will NOT work when the same gauge is compiled
by any other means (Borland, MSVC++ .NET 2003, et cetera)...

While I still don't know why an LPTSTR "string" isn't being passed by the function,
but after several hours of study and frustration, it finally occured to me to try
passing an integer instead... Well I'll be darned... it works!

First, I changed the "Sound declarations" as follows:

Code:
// Sound declarations
typedef VOID (*TGaugePlaySound)(LPTSTR,int,int);  // 2nd param changed from LPTSTR to int
typedef VOID (*TGaugeStopSound)(int);  // param changed from LPTSTR to int
TGaugePlaySound GaugePlaySound;
TGaugeStopSound GaugeStopSound;
HMODULE MGaugeSound;
Then, I substituted an integer value in the function call like this:
Code:
            if ( *rotarytest == 1 )
                { (GaugePlaySound)("sound\\esdg\\fire.wav",4,1) ; }
            else { (GaugeStopSound)(4); }
Granted, the integer 4 isn't nearly as descriptive as -say - "firetest"
but at least the bloody thing works now!
 
Last edited:
I've seen things like that when passing pointer to strings between different threads. It could be because either the memory map changes as the context switches and so the pointer memory value is not valid in the new context, or the memory to which the pointer references is transient.

Similarly, I've found that if I request strings from the sim (with aircraft_varget), like the aircraft name or ATC code, I have to copy the contents of the string immediately into my own local variables because by the time the next sim processing cycle happens the memory the pointer points to has changed and the string is invalid.

Si
 
Similarly, I've found that if I request strings from the sim (with aircraft_varget), like the aircraft name or ATC code, I have to copy the contents of the string immediately into my own local variables because by the time the next sim processing cycle happens the memory the pointer points to has changed and the string is invalid.

Si

Something similar also happened to me, ie variables of type "string" are overwritten on the next cycle, no matter they are public in the dll project. However, fixed char vars work fine. It seems FS in some point does not allocate memory at runtime to handle string data of variable length; I guess that's the main reason XML LVars with "string" units are not supported.

Tom
 
When you declare a pointer as public in the dll, all you're doing is declaring the pointer. FS is simply filling that pointer with the address of memory within its space. So you don't have ownership of the memory the string is in, only the local pointer to it.

I don't like to use methods like that in any of my programs. It's how memory leaks happen. For example some coding methodologies would malloc the memory, return you a pointer to it and then expect you to free the memory when you're done. Others don't and will free the memory themselves.

The only clue you get in the SDK as to how MS expects you to use this is that the type is a pointer to const data, which implies you shouldn't try to do anything to it.

Si
 
I've seen things like that when passing pointer to strings between different threads. It could be because either the memory map changes as the context switches and so the pointer memory value is not valid in the new context, or the memory to which the pointer references is transient.

The GaugeSound.dll is supplied with EasyGauge. I don't know who programmed the library originally, and haven't a clue what it does internally. The only clues available are the "goesinta" stuff and the fact that the "comesouta" either works or not... :tongue-ti

Marcel & his brother programmed EasyGauge to make use of GaugeSound.dll (which uses DirectX btw), but have since disappeared from public view. In fact, neither of them will even respond to email any longer... :(

What is clear though is that obviously MinGW's compiler, include.h files and libraries do support LPTSTR differently than any other compiler (Borland and MS are the only one's I've tried). Since I have a TON of "legacy C/C++ code" to maintain, I have been struggling to find a workaround for this one issue of not being able to "stop" a specific "sound loop." At any given time, I might have ten (or more) sound loops running, so this GaugeStopSound function was critical!

Not understanding and quite honestly lacking the background to determine the exact, proximate cause of the problem, I am at least satisfied now to have found a "workaround."

I can at least solve the problem of identification by creating a list of #define(s) that will tie a name to the number:

#define firetest 1;
#define masteralarm 2;

et cetera... :D
 
It must be down to the compiler's implementation of the wchar_t type as that's what all MS's convoluted typedefs resolve to in one way or another.

If you do a "go to definition" in VS2008 (and before presumably) on LPTSTR when you eventually get back to wchar_t there's even a note about Macintosh compilers (in WinNT header).

Googling wchar_t seems to suggest the Unicode standard is a bit un-standard at best in this regard.

Anyway, good to know you've a workaround. I've got to write custom sounds into what I'm doing at the moment and I shall probably try and do it from scratch with DirectSound myself. Good to know it's at least possible!

Si
 
Unfortunately, GaugeSound.dll only supports three functions:

1. Play a one-shot sound .wav file.

2. Loop a sound .wav file until you send a stop sound call.

3. Terminate all .wav sounds immediately.

Ideally, such a module should have both volume control as well as stereo pan control... :speanut:
 
I'm looking at writing sound functions that do stereo panning, but to do that I need to be able to either a) grab FS's sound buffers in order to interrogate what settings they're using, or b) get the user's view location from the sim in order to derive it for myself. Unfortunately, as I've described in another thread, this doesn't appear to work too well.

Si
 
A fellow programmer at another site pointed out to me that my "kludge" -while apparently working- isn't truly "safe hex..." (my term, not his).

What worries me about your method of replacing the LPTSTR with an int is that the int you pass is effectively an address in memory (in this case 0x000000004). That is fine and good UNLESS that particular memory has been allocated by windows for something else - and if it has, kaboom - you get a page fault, and you crash the sim (or, under Vista, you get a Data Execution Prevention fault). Whether the crash occurs or not will depend on many things - what software is running, what hardware is installed (as different drivers will be resident in different addresses, etc), so it is likely to give you many headaches later as you try to repro a failure reported by a customer. And then watch as the thing explodes even more brightly under the 64 bit versions of windows, because there the memory addresses use up two words (long ints) rather than one!

Instead, he suggested the following (which works splendidly) as a safe alternative. Change the int in the 2nd param to an LPSTR, then explicitly create the necessary LPSTR buffers and initialize them with constants:

Code:
// Sound declarations
	typedef VOID (*TGaugePlaySound)(LPTSTR,LPSTR,int);
	typedef VOID (*TGaugeStopSound)(LPSTR);
	typedef VOID (*TTerminateSounds)();
	TGaugePlaySound GaugePlaySound;
	TGaugeStopSound GaugeStopSound;
	TTerminateSounds TerminateSounds;
	HMODULE MGaugeSound;

	LPSTR flap = "flap";
	LPSTR gearhorn = "gearhorn";
	LPSTR overspeed = "overspeed";
	LPSTR firetest = "firetest";
	LPSTR geartest = "geartest";
	LPSTR speedtest = "speedtest";
	LPSTR warning = "warning";

Then, in the gauge's function calls, use the named pointer:

Code:
			if ( *rotartest == 1 ) 
				{ (GaugePlaySound)("sound\\esdg\\fire.wav",firetest,1) ; }
			else { (GaugeStopSound)(firetest); }
 
Back
Top