![]() |
|
|||||||
| Register | Wiki | Downloads | FAQ | Members List | Social Groups | Calendar | Search | Today's Posts | Mark Forums Read |
| Sound Use this forum for all sound related discussions |
![]() |
|
|
Thread Tools | Display Modes |
|
#1
|
|||
|
|||
|
directsound dll for gauge crackles/pops when FSX sound also playing
I've (almost) successfully written a glider variometer sound DLL in VC++ 2008 & directsound. The basic requirement is to vary the frequency of the tone with a 'lift/sink' xml variable written by the gauge. There was something called fssound.dll that did this for FS2002/4 written by someone else but nothing for FSX.
After much iteration and testing I've got the DLL running like a charm, connected to an XML gauge that can write the 'lift' value to the DLL so it alters the sound as appropriate. ***BUT*** unless I have the 'sound' option in FSX disabled (so you only hear the DLL sound) I get crackles and pops on the sound coming from the DLL. If I disable FSX sound, the vario sound DLL is as clear as a bell. (I have XP, a recent creative XFi card and DirectX 9, and no problems with any other software, so I think this is a programming/setup problem not my config) I thought I knew the answer and changed a line in my code from hr = lpds->SetCooperativeLevel(hwnd,DSSCL_NORMAL); to hr = lpds->SetCooperativeLevel(hwnd,DSSCL_PRIORITY); but this made *no* difference whatsoever - I still get pops and glitches when both sets of sounds are playing. Any advice *greatly* appreciated. Thanks B21 Last edited by B21; 07 Aug 2008 at 15:43. |
|
#2
|
|||
|
|||
|
p.s. I've also increased the priority of the thread that handles the notify events to keep the streaming buffer full - made no difference.
But I've also found that if fill the sound buffer once, play it looping, and disable the notify thread from updating the buffer, there's no crackle & pop. I've set two notify positions, one at the start of the buffer (A), one half way through (B), and when I get position notify A I fill buffer from B and vice versa. I increased the size of the buffer to maybe half a second long, and the pops/crackles didn't change. Ta, B21 |
|
#3
|
|||
|
|||
|
In case this helps anyone else... I didn't find the cause, but by using Audacity to record the sound and setting the volume sliders for each FSX sound to zero, I could the output waveform in detail and see where the glitches were occurring. The problem didn't occur if I simply set FSX sounds to 'off' instead of slider volumes to zero.
My workaround (for the glider vario) was to change the method entirely, and instead of using a streaming buffer being dynamically updated with the calculated variable frequency waveform I used a static buffer containing a segment of 440Hz waveform loaded only once and played in a loop, and used the directsound 'setFrequency()' call to adjust the playback rate and vary the tone that way. I'm pretty sure this is what other software implementations of vario sounds do, and works for a variable tone, but wouldn't work if you actually wanted to play a WAV. B21 |
|
#4
|
|||
|
|||
|
I think the problem is that DX needs to continually remix the secondary buffer with everything else that's playing at runtime if you keep changing the playback frequency. That's quite processor intensive.
Is there a particular reason why you've opted not to use the in-built variometer as used by the DG-80S glider? Out of interest, have you tried (and been successful) in changing the volume level at runtime using SetVolume()? I've been struggling with that, (and gave up.) I've got my custom cockpit generating and playing all sorts of sounds, but there are some I'd like to be able to adjust the volume for, and it just never works... Si |
|
#5
|
|||
|
|||
|
Hi Si,
fair point about the remix - the issue was with my straightforward writing of the streaming buffer though, running it at a fixed frequency. E.g. I can write a simple sinewave - doing the floating point math - streaming the waveform into the idle half of the buffer at each 'notify', and adjust the parameters of the waveform as it is written to give smooth frequency (and volume) changes. The code is very similar to me continuously feeding a WAV file into a streaming buffer, except I'm generating the 'output' values on the fly. Oddly, this has hiccups when mixed with the FSX sound. My new technique is to load the buffer once and vary the the directsound playback frequency, and so-far-so-good. I'm pretty sure this is what some other applications do because (for example) the soaring simulator 'Condor' actually has the vario sound as a very short 'WAV' file so I'm guessing this is loaded into a static buffer of exactly the right length and played in a loop with the playback rate varied... The DG808S vario sound is great *except* the driving variable (A:VARIOMETER RATE) is non-writeable, and the FSX calculation of VARIOMETER RATE is a pure rate-of-climb indication, not the 'total energy' value that's been used in gliding since circa 1930. The end result with the stock DG is you get 'stick thermals' - i.e. the vario beeping enthusiastically when you pull up into what you think is a thermal, even though you could be in completely still air. For my purposes I am calculating total energy, netto (the pure outside air vertical movement), and speed-to-fly (a derivative of netto that just tells you whether to speed up or slow down) - each of these has to drive the audio tone depending on whether you are cruising or climbing. The 'computation' side of the vario has gone very smoothly although I've realised I've written the same software that must be embedded inside a $2,000 glider instrument... Re adjusting the volume - I have this working like a charm using SetVolume(LONG vol). The only point of confusion I can think of is the parameter runs from ZERO (DSBVOLUME_MAX) to -10,000 (DSBVOLUME_MIN) with that range representing 100dB. My gauge has a volume control feeding a float variable (GAUGE_VOL) that I normalise to 0.0 (off) .. 1.0 (max). From memory my code is *something* like lpdsbuffer->SetVolume((LONG) (pow(1-GAUGE_VOL,2.0))*DSBVOLUME_MIN ) so you can see GAUGE_VOL=0 => SetVolume(-10000) and GAUGE_VOL=1 => SetVolume(0) Also from memory, the actual 'power' of GAUGE_VOL to get the appropriate subjective linearity from 0..1 was by trial-and-error - don't rely on my 2.0. (Example GAUGE_VOL=0.5 means SetVolume (-2500) which means -25dB which is pretty damn quiet) For what it's worth I have found the SetVolume call to be very responsive, to the extent that on startup I can 'fade in' a continuous tone over 10-20milliseconds by adjusting the volume 5 times, avoiding the 'click' you would otherwise get if you immediately played a sine wave even starting at the zero point. If you are playing a non-repeating WAV this is a non-issue as you'd assume the WAV file has some sensible lead-in. Thanks very much for your advice/comments. B21 Last edited by B21; 11 Aug 2008 at 09:06. |
|
#6
|
|||
|
|||
|
I've driven myself crazy tonight with the SetVolume malarky, and finally learnt a very important lesson about DirectSound..
I went through my code (several times) and couldn't see why SetVolume() wasn't working. In my VS debugger I was interrupting the program, setting a call the SetVolume() and then continuing, and it would have no effect. Well, it turns out that SetVolume() does not work if your application containing the DirectSound buffer is not in focus, and of course, as I'm interrupting the code with the debugger, focus is being switched! I now have it working nicely... finally! ![]() Si |
|
#7
|
|||
|
|||
|
eeek unlucky - I can see that would take a while to find.
fyi I improved the effectiveness of the linear-to-non-linear volume control for the actual code mapping a linear 0..1 input setting (c_volume) to a suitable DirectSound volume: Code:
volume = log(c_volume*0.98+0.02)/log(0.02)* DSBVOLUME_MIN; // volume = 0..-10000
// set general volume level
hr = lpdsbuffer->SetVolume(volume);
|
|
#8
|
|||
|
|||
|
These are the functions I use for converting Log to Lin and back. I found them browsing a book on Amazon. (I think it's called "Games Sound Programming":
Code:
int LinearToLogVol(double fLevel)
{
const int MIN_VAL = 0.0;
const int MAX_VAL = 1.0;
if (fLevel <= MIN_VAL)
return DSBVOLUME_MIN;
else if (fLevel >= MAX_VAL)
return DSBVOLUME_MAX;
return (int) (-2000.0 * log10(1.0 / fLevel));
}
double LogToLinearVol(int iLevel)
{
if (iLevel <= -9600)
return 0.0;
else if (iLevel >= 0)
return 1.0;
return pow(10.0,double(iLevel + 2000) / 2000.0) / 10.0;
}
Si |
![]() |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Adding sound to effects | sgtjoebear | Special Effects General | 6 | 01 Aug 2007 20:18 |
| Sound level variation in sound effects. | HugoA | Special Effects General | 0 | 23 Jul 2007 04:33 |
| AI Sound engine | statesman | Sound | 2 | 13 Jun 2007 03:56 |