DirectSound output is silent


#1

Hello,

Somehow DirectSound output is silent in my custom application. ASIO and Windows Audio work fine. However selecting DirectSound device makes the output silent. Callback is called, buffers are passed and filled, however no sound is heard.

The difference seems to be in the way Juce is compiled. I’m using MSVS2010 SP1. Once adding /O1 or /O2 to the compilation flags, the sound disappears. With /Od or no optimization flag at all - the sound comes fine.

Doing #pragma optimize( “”, off ) / #pragma optimize( “”, on ) around juce_win32_DirectSound.cpp amalgamation part doesn’t help.

This was tested with Juce 1.53 and the latest GIT amalgamation. I wonder if there might be any suggestion here, before me spending a lot of time going deeper into this problem?

Thanks,
George.


#2

Seems to be, that this inner loop is having the problem:

						while (--samples1 >= 0)
						{
							const int l = convertInputValue (*left++);
							const int r = convertInputValue (*right++);
							*dest++ = (r << 16) | (0xffff & l);
						}

The problem seems to be in the function roundToInt. Replacing it with the body of convertToInt (manually inlining) and replacing roundToInt(…) with int(…) brings the sound back.

						while (--samples1 >= 0)
						{
							const int l = jlimit (-32768, 32767, int(32767.0f * (*left++)));//convertInputValue (*left++);
							const int r = jlimit (-32768, 32767, int(32767.0f * (*right++)));//convertInputValue (*right++);
							*dest++ = (r << 16) | (0xffff & l);
						}

Maybe something in the way roundToInt works breaks the optimizer in this particular case, as the function is rather scary.

I replaced it with something like this, and everything started to work then:

template <typename FloatType>
inline int roundToInt (const FloatType value) noexcept
{
    return int(value+((value>=FloatType(0.0))?FloatType(0.5):FloatType(-0.5)));
}

(Obviously, the above code is less than optimal.)


#3

Yikes! That MSVC optimiser can get a bit carried away sometimes!

Perhaps something like this would fix it?

[code]inline int roundToInt (const FloatType value) noexcept
{
#if JUCE_MSVC && JUCE_DEBUG
#pragma optimize (“p”, on)
#endif

union { int asInt[2]; double asDouble; } n;
n.asDouble = ((double) value) + 6755399441055744.0;

#if JUCE_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt [0];
#endif

#if JUCE_MSVC && JUCE_DEBUG
#pragma optimize ("", on) // resets optimisations to the project defaults
#endif
}
[/code]


#4

I will test.

What exactly is JUCE_DEBUG? Does it get defined even in the release builds? (since the problem apparently is in the release build)


#5

Sorry, obviously that was just some example code to give you the gist, here’s a more realistic version:

[code]#if JUCE_MSVC
#pragma optimize (“t”, off)
#endif

/** Fast floating-point-to-integer conversion.

This is faster than using the normal c++ cast to convert a float to an int, and
it will round the value to the nearest integer, rather than rounding it down
like the normal cast does.

Note that this routine gets its speed at the expense of some accuracy, and when
rounding values whose floating point component is exactly 0.5, odd numbers and
even numbers will be rounded up or down differently.

*/
template
inline int roundToInt (const FloatType value) noexcept
{
union { int asInt[2]; double asDouble; } n;
n.asDouble = ((double) value) + 6755399441055744.0;

#if JUCE_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt [0];
#endif
}

#if JUCE_MSVC
#pragma optimize ("", on) // resets optimisations to the project defaults
#endif

[/code]