DirectSound output is silent

For Windows specific issues

DirectSound output is silent

Postby gyohng » Wed Oct 12, 2011 8:47 pm

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.
gyohng
JUCE Weenie
 
Posts: 6
Joined: Sat Oct 01, 2011 11:11 pm

Re: DirectSound output is silent

Postby gyohng » Wed Oct 12, 2011 9:28 pm

Seems to be, that this inner loop is having the problem:
Code: Select all
                  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.

Code: Select all
                  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:

Code: Select all
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.)
gyohng
JUCE Weenie
 
Posts: 6
Joined: Sat Oct 01, 2011 11:11 pm

Re: DirectSound output is silent

Postby jules » Thu Oct 13, 2011 2:11 pm

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

Perhaps something like this would fix it?

Code: Select all
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
}
User avatar
jules
Fearless Leader
 
Posts: 17218
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: DirectSound output is silent

Postby gyohng » Fri Oct 14, 2011 2:34 pm

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)
gyohng
JUCE Weenie
 
Posts: 6
Joined: Sat Oct 01, 2011 11:11 pm

Re: DirectSound output is silent

Postby jules » Fri Oct 14, 2011 3:31 pm

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

Code: Select all
#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 <typename FloatType>
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

User avatar
jules
Fearless Leader
 
Posts: 17218
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK


Return to Windows

Who is online

Users browsing this forum: No registered users and 0 guests