Synopsis
========

MIN_HEAP Playback. With MIN_HEAP builds (or very low latency
modes) it was possible to have glitches in the audio. This was
from audio underflows as a result of not being able to accurately
determine how much push down we had across platforms. This was
mostly due to differences in how different platforms calculated
the number of block remaining to play, but also had to do with
differences in certain constants used.

Fix
===

The first thing to do was to bring all the different defines into
one place, they were in 3 separate files. All defines that control
the pushdown, granularity and scheduling are now in one big section.
This should keep problem from occurring when one of these was changed
without knowledge of the others. Here is the pertinent part of that
chage:

+// These defines control how much audio PCM data we push down into the
+// audio device. MINIMUM_AUDIO_STARTUP_PUSHDOWN determines how much we
+// push before calling Resume() on the device (and starting playback)
+// and MINIMUM_AUDIO_PUSHDOWN determines how much PCM data we push
+// down during steady state playback. It is also important that the
+// granularity be less then or equal to MINIMUM_AUDIO_PUSHDOWN/2. If
+// not, underflows could result because only 1 block will be in the
+// audio device at any given time. Currently MINIMUM_AUDIO_GRANULARITY
+// is not used. In CHXAudioPlayer::Setup() hardcodes this:
+//
+//     m_ulGranularity = MAXIMUM_AUDIO_GRANULARITY;
+//
+// The CHECK_AUDIO_INTERVAL define tells the audio session how often
+// to check how much data we have pushed down in the audio device.
+// for min heap builds it is more important to check often because we
+// have very few blocks pushed down at any one time. The value for
+// this define is a percentage (0-100) of the granularity in
+// milliseconds. IE, 40 means 40% of whatever granulatiry is in use.
+//
+#ifdef HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
+#  define MINIMUM_AUDIO_GRANULARITY       50
+#  define MAXIMUM_AUDIO_GRANULARITY       MINIMUM_AUDIO_GRANULARITY
+#  define MINIMUM_AUDIO_PUSHDOWN          100
+#  define MINIMUM_AUDIO_STARTUP_PUSHDOWN  MINIMUM_AUDIO_PUSHDOWN
+#  define CHECK_AUDIO_INTERVAL            40
+#else
+#  define MINIMUM_AUDIO_GRANULARITY       50
+#  define MAXIMUM_AUDIO_GRANULARITY       100
+#  define MINIMUM_AUDIO_PUSHDOWN          1000
+#  define MINIMUM_AUDIO_STARTUP_PUSHDOWN  100
+#  define CHECK_AUDIO_INTERVAL            90
+#endif

The second thing to do was to re-do our logic on how we calculate the
amount of audio pushdown, given the above defines. The new logic makes
sure that we are conservative with regards to block count and that all
the calculated and defined values make sense together. The changes are
to UpdateMinimumPushdown() but the diffs are hard to read, here is the
new version:

void CHXAudioSession::UpdateMinimumPushdown()
{
    //This is called whenever the granularity or audio pushdown
    //changes.  In this method we need to make sure that the
    //granularity is results in at least 2 blocks being the min
    //pushdown. If we are left with only one block, it can be hard to
    //prevent underflow in the audio device. You don't have to
    //increase the amount of PCM pushdown, just decrease the
    //granularity.
    if( m_ulGranularity )
    {
        //Basically, integer versions of 'ceil' function.
        m_ulMinBlocksTobeQueued = 
(m_ulMinimumPushdown+m_ulGranularity-1)/m_ulGranularity;
        m_ulMinBlocksTobeQueuedAtStart = 
(m_ulMinimumStartupPushdown+m_ulGranularity-1)/m_ulGranularity;

#if defined(HELIX_FEATURE_PREFERENCES)
        HXBOOL bRestore = FALSE;
        ReadPrefBOOL( m_pPreferences, "RestoreMinimumPushdown", bRestore );
        if( bRestore)
        {
            m_ulMinBlocksTobeQueuedAtStart = m_ulMinBlocksTobeQueued;
        }
#endif

        //Invarients to ensure glitch free audio playback.
        HX_ASSERT( m_ulGranularity <= m_ulMinimumPushdown/2 );
        HX_ASSERT( m_ulMinBlocksTobeQueued>1 );
        HX_ASSERT( m_ulMinBlocksTobeQueued >= m_ulMinBlocksTobeQueuedAtStart );
        HX_ASSERT( m_ulMinimumPushdown >= m_ulMinimumStartupPushdown );
    }
}


Next, we had to fix the problem with each platform calculating the number of
blocks remaining to play differently. One implementation might return values
1 greater or 1 less then another. This is a problem for the core when the total
pushdown was just 1 or 2 blocks, we could run into underflow pretty easily.
Even if I did go and fix each platform, it is possible that new platforms
would not be correct or that old ones would get changed again. This is mostly
because it is hard to tell if you are doing it correctly in normal operations.
It takes a MIN_HEAP build and some testing to figure it out. However, one thing
each platform's audio code *must* do correctly is return a smooth accurate
time-line. If they don't it is very obvious. So, I have opted to use that
information instead of relying on the buggy NumberOfBlocksRemainingToPlay()
method. This was already being done for audio code that returned FALSE from
IsWaveOutDevice(). Currently, this only includes the DirectSound driver being
used on Window's player builds. This change results in a lot cleaner code
and some image size reduction. It also moves the calculation of audio pushdown
to a single spot in the code base. A new method, GetBlocksRemainingToPlay():

ULONG32 CHXAudioSession::GetBlocksRemainingToPlay()
{
    ULONG32 ulRetVal        = 0;
    ULONG32 ulBlocksPlayed  = 0;
    ULONG32 ulCurTime       = 0;
    if( m_pAudioDev->GetCurrentAudioTime(ulCurTime) == HXR_OK )
    {
        ulBlocksPlayed = (ULONG32)(ulCurTime/m_dGranularity+.5);
        if( m_ulBlocksWritten>ulBlocksPlayed )
        {
            ulRetVal = m_ulBlocksWritten-ulBlocksPlayed;
        }
    }
    return ulRetVal;
}


So that this code:


-        if ( (!m_bReplacedDev) && 
(((CHXAudioDevice*)m_pAudioDev)->IsWaveOutDevice()) )
-        {
-            m_uNumToBePlayed = uNumBlocks = 
((CHXAudioDevice*)m_pAudioDev)->NumberOfBlocksRemainingToPlay();
-
-
-
-            /* Now that m_ulMinimumPushdown can be set by the user, it is 
possible
-             * for MIN_BLOCKS_TOBEQUEUED to be 0.
-             */
-            if (uNumBlocks == 0 ||
-                uNumBlocks < m_ulMinBlocksTobeQueued)
-            {
-                bPlay = TRUE;
-            }
-        }
-        else
-        {
-            ULONG32 ulCurTime = 0;
-            if (m_pAudioDev->GetCurrentAudioTime(ulCurTime) == HXR_OK)
-            {
-                UINT32 ulNumBlocksPlayed = (UINT32) ((double) ulCurTime / 
m_dGranularity);
-                if (m_ulBlocksWritten > ulNumBlocksPlayed)
-                {
-                    m_uNumToBePlayed = uNumBlocks = (UINT16) 
(m_ulBlocksWritten - ulNumBlocksPlayed);
-                }
-
-                /* Now that m_ulMinimumPushdown can be set by the user, it is 
possible
-                 * for MIN_BLOCKS_TOBEQUEUED to be 0.
-                 */
-                if (uNumBlocks == 0 ||
-                    uNumBlocks < m_ulMinBlocksTobeQueued)
-                {
-                    bPlay = TRUE;
-                }
-            }
-        }
-        HXLOGL4(HXLOG_ADEV, "CHXAudioSession[%p]::CheckToPlayMoreAudio(): block count = %lu (min to 
queue = %lu); play = '%s'", this, uNumBlocks, m_ulMinBlocksTobeQueued, bPlay ? "true" : 
"false");
-

simply becomes:

+        m_uNumToBePushed = uNumBlocks = GetBlocksRemainingToPlay();
+        bPlay = (uNumBlocks<m_ulMinBlocksTobeQueued) ? TRUE : FALSE;
+        HXLOGL4( HXLOG_ADEV,
+                 "CHXAudioSession[%p]::CheckToPlayMoreAudio(): block count = 
%lu",
+                 this,
+                 uNumBlocks);


The rest of the changes are just general clean changes that should not
have any affect except on readability.

A few things left to do:

o CHXAudioDevice::NumberOfBlocksRemainingToPlay is not longer used by the core.
  So, we could go through and remove it to reduce image size in some of the
  platform audio code (assuming it isn't used internally by the platform).
o Same with IsWaveOutDevice(). We no longer use it.
o Granularities were originally designed to be set programmatically, but
  they have been hardcoded historically. We might look into the usefulness of
  removing the hardcoded value and letting it change for each clip depending
  on the audio pushdown set by the renderer. This would be required to get
  audio pushdown values less then 100ms (which is about our lowest pushdown
  we can do right now without audio glitches). This would also require more
  testing.


Files Modified
==============
    client/audiosvc/hxaudply.cpp
    audio/device/pub/hxaudev.h
    client/audiosvc/hxaudses.cpp
    client/audiosvc/pub/hxaudses.h


Branch(s)
=========
HEAD, 150Cay.


Image Size and Heap Use impact
==============================
Small reduction in image size, no heap changes.


Platforms and Profiles Affected
===============================
All platforms, all profiles.


Distribution Libraries affected
===============================
None.


Platforms and Profiles Build Verified
=====================================
Windows min heap. Linux/all-defines/min-heap.


Platforms and Profiles Functionality verified
=============================================
Windows min heap. Linux/all-defines/min-heap.


--greg.



Index: hxaudply.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
retrieving revision 1.36.2.6
diff -u -w -r1.36.2.6 hxaudply.cpp
--- hxaudply.cpp        3 May 2005 22:19:26 -0000       1.36.2.6
+++ hxaudply.cpp        16 Aug 2005 19:37:04 -0000
@@ -97,8 +97,7 @@
 #include "hxprefutil.h"
 #endif /* HELIX_FEATURE_PREFERENCES */

-#define MINIMUM_AUDIO_GRANULARITY       50
-#define MAXIMUM_AUDIO_GRANULARITY       100
+
 #define MAX_WAIT_AT_SAME_TIME           (MAXIMUM_AUDIO_GRANULARITY+50)

 CHXAudioPlayer::CHXAudioPlayer( CHXAudioSession* owner )


Index: pub/hxaudev.h
===================================================================
RCS file: /cvsroot/audio/device/pub/hxaudev.h,v
retrieving revision 1.11.6.1
diff -u -w -r1.11.6.1 hxaudev.h
--- pub/hxaudev.hernalCl5 May 2005 09:19:33 -0000       1.11.6.1
+++ pub/hxaudev.h       16 Aug 2005 19:30:19 -0000
@@ -59,11 +59,6 @@String("BEFORE CALL TO:Register\r\n");
 #  define kUSound            4
 #endif
        return HXR_OK;
-#ifdef HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
-#define MINIMUM_AUDIO_PUSHDOWN    100RUE;
-#else  }
-#define MINIMUM_AUDIO_PUSHDOWN    1000
-#endifOutputDebugString("BEFORE CALL TO:CreateWindow\r\n");
     // Now create an instance of the window


Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.52.2.11
diff -u -w -r1.52.2.11 hxaudses.cpp
--- hxaudses.cpp        9 Jun 2005 17:03:19 -0000       1.52.2.11
+++ hxaudses.cpp        16 Aug 2005 20:27:47 -0000
@@ -66,13 +66,9 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-
 #if defined (_WINDOWS) || defined (_WIN32)
-
 #include <io.h>
-
 #endif
-
 #endif

 //#include "racodec.h"
@@ -125,15 +121,6 @@
 static const char HX_THIS_FILE[] = __FILE__;
 #endif

-#if defined(HELIX_FEATURE_MIN_HEAP)
-#define MINIMUM_AUDIO_STARTUP_PUSHDOWN  200 //ms
-#define CHECK_AUDIO_INTERVAL            40  //%
-#else
-#define MINIMUM_AUDIO_STARTUP_PUSHDOWN  100 //ms
-#define CHECK_AUDIO_INTERVAL            90  //%
-#endif
-
-
 #define SOME_INSANELY_LARGE_VALUE       3600000 /* 1 hour */

 #ifdef _WIN32
@@ -643,20 +630,18 @@
     {
         ReadPrefUINT32(m_pPreferences, "MinimumAudioPushdown", 
m_ulMinimumPushdown);
         ReadPrefUINT32(m_pPreferences, "MinimumAudioStartupInitalPushdown", 
m_ulMinimumStartupPushdown);
+        ReadPrefUINT32(m_pPreferences, "CheckAudioPct", m_nPercentage);
+    }
+#endif /* HELIX_FEATURE_PREFERENCES */

         if (m_ulMinimumStartupPushdown > m_ulMinimumPushdown)
         {
             m_ulMinimumPushdown = m_ulMinimumStartupPushdown;
         }
         HXLOGL3(HXLOG_ADEV, "CHXAudioSession[%p]::Init(): min audio push = %lu; min 
startup = %lu ", this, m_ulMinimumPushdown, m_ulMinimumStartupPushdown);
-    }
-
-    ReadPrefUINT32(m_pPreferences, "CheckAudioPct", m_nPercentage);
     HXLOGL2(HXLOG_ADEV, "Setting callback granulatiry percentage to %d", 
m_nPercentage );


-#endif /* HELIX_FEATURE_PREFERENCES */
-
     // Create a device volume interface.
     if ( !theErr )
     {
@@ -2942,7 +2927,9 @@
     m_ulMinimumPushdown = ulMinimumPushdown;
     UpdateMinimumPushdown();

-    HXLOGL3(HXLOG_ADEV, "CHXAudioSession[%p]::SetAudioPushdown(): push down = 
%lu", this, ulMinimumPushdown);
+    HXLOGL3(HXLOG_ADEV,
+            "CHXAudioSession[%p]::SetAudioPushdown(): push down = %lu",
+            this, ulMinimumPushdown);
     return HXR_OK;
 }

@@ -2972,38 +2959,38 @@
 CHXAudioSession::GetCurrentAudioDevicePushdown(REF(UINT32) /*OUT*/ 
ulAudioPusheddown)
 {
     HX_RESULT   rc = HXR_OK;
-    UINT16      uNumBlocks = 0;
-    UINT32      ulNumBlocksPlayed = 0;
-    UINT32      ulCurTime = 0;

     ulAudioPusheddown = 0;

-    if (m_bToBeReOpened || !m_pAudioDev)
+    if( !m_bToBeReOpened && m_pAudioDev )
     {
-        goto cleanup;
+        ulAudioPusheddown = (UINT32)(GetBlocksRemainingToPlay() * 
m_dGranularity);
     }

-    if ( (!m_bReplacedDev) && 
(((CHXAudioDevice*)m_pAudioDev)->IsWaveOutDevice()) )
-    {
-        uNumBlocks = 
((CHXAudioDevice*)m_pAudioDev)->NumberOfBlocksRemainingToPlay();
+    return rc;
     }
-    else
+
+// We no longer use CHXAudioDevice::NumberOfBlocksRemainingToPlay() to
+// determine how much data is left in the audio device. Not only did
+// we have the problem of differences on how it was calculated between
+// different platforms but each platform already has to give back very
+// accurate timeline information. Since we keep track of how many
+// blocks we have written, we just use that and the current playback
+// time to determine how much data is down in the device.
+ULONG32 CHXAudioSession::GetBlocksRemainingToPlay()
     {
+    ULONG32 ulRetVal        = 0;
+    ULONG32 ulBlocksPlayed  = 0;
+    ULONG32 ulCurTime       = 0;
         if (m_pAudioDev->GetCurrentAudioTime(ulCurTime) == HXR_OK)
         {
-            ulNumBlocksPlayed = (UINT32) ((double) ulCurTime / m_dGranularity);
-            if (m_ulBlocksWritten > ulNumBlocksPlayed)
+        ulBlocksPlayed = (ULONG32)(ulCurTime/m_dGranularity+.5);
+        if( m_ulBlocksWritten>ulBlocksPlayed )
             {
-                uNumBlocks = (UINT16) (m_ulBlocksWritten - ulNumBlocksPlayed);
+            ulRetVal = m_ulBlocksWritten-ulBlocksPlayed;
             }
         }
-    }
-
-    ulAudioPusheddown = (UINT32)(uNumBlocks * m_dGranularity);
-
-cleanup:
-
-    return rc;
+    return ulRetVal;
 }

 /************************************************************************
@@ -3129,39 +3116,35 @@
     return theErr;
 }

-void
-CHXAudioSession::UpdateMinimumPushdown()
+void CHXAudioSession::UpdateMinimumPushdown()
 {
+    //This is called whenever the granularity or audio pushdown
+    //changes.  In this method we need to make sure that the
+    //granularity is results in at least 2 blocks being the min
+    //pushdown. If we are left with only one block, it can be hard to
+    //prevent underflow in the audio device. You don't have to
+    //increase the amount of PCM pushdown, just decrease the
+    //granularity.
     if (m_ulGranularity)
     {
-        m_ulMinBlocksTobeQueued = (UINT32) 
(m_ulMinimumPushdown*1.0/m_ulGranularity);
-        if ((m_ulMinBlocksTobeQueued == 0) ||
-            (m_ulMinBlocksTobeQueued*m_ulGranularity < m_ulMinimumPushdown))
-        {
-            m_ulMinBlocksTobeQueued++;
-        }
-
-        if ((m_ulMinBlocksTobeQueued * m_ulGranularity) >= 
m_ulMinimumStartupPushdown)
-        {
-            m_ulMinBlocksTobeQueuedAtStart = (UINT32) 
(m_ulMinimumStartupPushdown*1.0/m_ulGranularity);
-        }
-        else
-        {
-            m_ulMinBlocksTobeQueuedAtStart = m_ulMinBlocksTobeQueued;
-        }
+        //Basically, integer versions of 'ceil' function.
+        m_ulMinBlocksTobeQueued = 
(m_ulMinimumPushdown+m_ulGranularity-1)/m_ulGranularity;
+        m_ulMinBlocksTobeQueuedAtStart = 
(m_ulMinimumStartupPushdown+m_ulGranularity-1)/m_ulGranularity;

 #if defined(HELIX_FEATURE_PREFERENCES)
-        IHXBuffer* pBuffer = NULL;
-        if (m_pPreferences &&
-            m_pPreferences->ReadPref("RestoreMinimumPushdown", pBuffer) == HXR_OK 
&&
-            pBuffer &&
-            ::atoi((char*) pBuffer->GetBuffer()) == 1)
+        HXBOOL bRestore = FALSE;
+        ReadPrefBOOL( m_pPreferences, "RestoreMinimumPushdown", bRestore );
+        if( bRestore)
         {
             m_ulMinBlocksTobeQueuedAtStart = m_ulMinBlocksTobeQueued;
         }
+#endif

-        HX_RELEASE(pBuffer);
-#endif /* HELIX_FEATURE_PREFERENCES */
+        //Invarients to ensure glitch free audio playback.
+        HX_ASSERT( m_ulGranularity <= m_ulMinimumPushdown/2 );
+        HX_ASSERT( m_ulMinBlocksTobeQueued>1 );
+        HX_ASSERT( m_ulMinBlocksTobeQueued >= m_ulMinBlocksTobeQueuedAtStart );
+        HX_ASSERT( m_ulMinimumPushdown >= m_ulMinimumStartupPushdown );
     }
 }

@@ -3527,65 +3510,17 @@
     }
     else
     {
-        if ( (!m_bReplacedDev) && 
(((CHXAudioDevice*)m_pAudioDev)->IsWaveOutDevice()) )
-        {
-            m_uNumToBePlayed = uNumBlocks = 
((CHXAudioDevice*)m_pAudioDev)->NumberOfBlocksRemainingToPlay();
-
-
-
-            /* Now that m_ulMinimumPushdown can be set by the user, it is 
possible
-             * for MIN_BLOCKS_TOBEQUEUED to be 0.
-             */
-            if (uNumBlocks == 0 ||
-                uNumBlocks < m_ulMinBlocksTobeQueued)
-            {
-                bPlay = TRUE;
-            }
-        }
-        else
-        {
-            ULONG32 ulCurTime = 0;
-            if (m_pAudioDev->GetCurrentAudioTime(ulCurTime) == HXR_OK)
-            {
-                UINT32 ulNumBlocksPlayed = (UINT32) ((double) ulCurTime / 
m_dGranularity);
-                if (m_ulBlocksWritten > ulNumBlocksPlayed)
-                {
-                    m_uNumToBePlayed = uNumBlocks = (UINT16) 
(m_ulBlocksWritten - ulNumBlocksPlayed);
-                }
-
-                /* Now that m_ulMinimumPushdown can be set by the user, it is 
possible
-                 * for MIN_BLOCKS_TOBEQUEUED to be 0.
-                 */
-                if (uNumBlocks == 0 ||
-                    uNumBlocks < m_ulMinBlocksTobeQueued)
-                {
-                    bPlay = TRUE;
-                }
-            }
-        }
-        HXLOGL4(HXLOG_ADEV, "CHXAudioSession[%p]::CheckToPlayMoreAudio(): block count = %lu (min to 
queue = %lu); play = '%s'", this, uNumBlocks, m_ulMinBlocksTobeQueued, bPlay ? "true" : 
"false");
-
+        m_uNumToBePushed = uNumBlocks = GetBlocksRemainingToPlay();
+        bPlay = (uNumBlocks<m_ulMinBlocksTobeQueued) ? TRUE : FALSE;
+        HXLOGL4( HXLOG_ADEV,
+                 "CHXAudioSession[%p]::CheckToPlayMoreAudio(): block count = 
%lu",
+                 this,
+                 uNumBlocks);
     }

     if (bPlay)
     {
         HX_ASSERT(!m_pAudioDev || m_ulMinBlocksTobeQueued > uNumBlocks);
-        /* Currently we break transcoding feature of jukwbox because:
-         * - overriden audio device plays much faster than realtime
-         * - mp3 datatype does not implement drynotification interface.
-         * - we therefore play silence instead of halting the timeline
-         *   when we run out of data.
-         *
-         * Patch: revert back to old behavior: i.e. push only one
-         * block at a time for replaced audio device
-         *
-         * correct fix: We should fix mp3 renderer to support drynotification
-         *
-         * XXXRA
-         *
-         * Update Removing this hack for replaced devices since MP3 renderer
-         * now supports dry notification. -- RA 07/18/01:
-         */
         if (m_pAudioDev && m_ulMinBlocksTobeQueued > uNumBlocks)
         {
             uNumBlocks = (UINT16) m_ulMinBlocksTobeQueued - uNumBlocks;
@@ -4138,7 +4073,7 @@
         HXLOGL2( "IsRebufferRequired: num: %d  start: %lu  numblk()=%d",
                  m_uNumToBePlayed,
                  m_ulMinBlocksTobeQueuedAtStart,
-                 
((CHXAudioDevice*)m_pAudioDev)->NumberOfBlocksRemainingToPlay());
+                 GetBlocksRemainingToPlay());
     }

     return bRetVal;
Index: pub/hxaudses.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudses.h,v
retrieving revision 1.18.6.2
diff -u -w -r1.18.6.2 hxaudses.h
--- pub/hxaudses.h      5 May 2005 09:33:29 -0000       1.18.6.2
+++ pub/hxaudses.h      16 Aug 2005 20:27:47 -0000
@@ -63,6 +63,52 @@
 #  define TLW_CLOSE    3
 #  define TLW_TIMESYNC 4

+
+// These defines control how much audio PCM data we push down into the
+// audio device. MINIMUM_AUDIO_STARTUP_PUSHDOWN determines how much we
+// push before calling Resume() on the device (and starting playback)
+// and MINIMUM_AUDIO_PUSHDOWN determines how much PCM data we push
+// down during steady state playback. It is also important that the
+// granularity be less then or equal to MINIMUM_AUDIO_PUSHDOWN/2. If
+// not, underflows could result because only 1 block will be in the
+// audio device at any given time. Currently MINIMUM_AUDIO_GRANULARITY
+// is not used. In CHXAudioPlayer::Setup() hardcodes this:
+//
+//     m_ulGranularity = MAXIMUM_AUDIO_GRANULARITY;
+//
+// The CHECK_AUDIO_INTERVAL define tells the audio session how often
+// to check how much data we have pushed down in the audio device.
+// for min heap builds it is more important to check often because we
+// have very few blocks pushed down at any one time. The value for
+// this define is a percentage (0-100) of the granularity in
+// milliseconds. IE, 40 means 40% of whatever granulatiry is in use.
+//
+#ifdef HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
+#  define MINIMUM_AUDIO_GRANULARITY       50
+#  define MAXIMUM_AUDIO_GRANULARITY       MINIMUM_AUDIO_GRANULARITY
+#  define MINIMUM_AUDIO_PUSHDOWN          100
+#  define MINIMUM_AUDIO_STARTUP_PUSHDOWN  MINIMUM_AUDIO_PUSHDOWN
+#  define CHECK_AUDIO_INTERVAL            40
+#else
+#  define MINIMUM_AUDIO_GRANULARITY       50
+#  define MAXIMUM_AUDIO_GRANULARITY       100
+#  define MINIMUM_AUDIO_PUSHDOWN          1000
+#  define MINIMUM_AUDIO_STARTUP_PUSHDOWN  100
+#  define CHECK_AUDIO_INTERVAL            90
+#endif
+


@@ -349,9 +395,7 @@
      */
     virtual HX_RESULT CreateAudioPlayer(CHXAudioPlayer**  ppAudioPlayer);
     HX_RESULT         _CreateAudioPlayer(CHXAudioPlayer** ppAudioPlayer);
-
     HX_RESULT       CloseAudioPlayer( CHXAudioPlayer*   pAudioPlayer);
-
     void            Close(void);

     /* The session object determines the audio device format based
@@ -362,7 +406,6 @@
     /* Open is called to open the audio device.
      */
     HX_RESULT       OpenAudio    (void);
-
     HX_RESULT       OpenDevice   (void);

     /* PlayAudio is called by Audio Player object.
@@ -383,8 +426,7 @@

     /* Seek is called by Audio Player object.
      */
-    HX_RESULT       Seek    (
-        CHXAudioPlayer* pPlayerToExclude,
+    HX_RESULT       Seek ( CHXAudioPlayer* pPlayerToExclude,
         const UINT32    ulSeekTime
         );

@@ -518,9 +560,10 @@
     friend class CHXAudioSession::HXDeviceSetupCallback;
   protected:
     ~CHXAudioSession(void);
-
     void _ConstructIfNeeded();

+    ULONG32 GetBlocksRemainingToPlay();
+
   private:

 #ifdef _MACINTOSH
@@ -606,8 +649,7 @@
     /* CheckAudioFormat Interface is called by audio player to
      * check resample audio format with audio device format.
      */
-    HX_RESULT               CheckAudioFormat(
-        HXAudioFormat* pAudioFormat );
+    HX_RESULT CheckAudioFormat( HXAudioFormat* pAudioFormat );

     /* Create the playback buffer.
      */
@@ -619,8 +661,7 @@


     /* Write audio data to post mix hooks. */
-    HX_RESULT               ProcessPostMixHooks(
-        CHXAudioPlayer* pPlayer,
+    HX_RESULT ProcessPostMixHooks( CHXAudioPlayer* pPlayer,
         IHXBuffer*&    pInBuffer,
         BOOL*           bDisableWrite,
         UINT32          ulBufTime,
@@ -631,7 +672,6 @@

     /* Convert 16-bit buffer to 8-bit */
     void                    ConvertToEight(void);
-
     BOOL                    IsAudioOnlyTrue(void);

     UINT32                  AnchorDeviceTime(UINT32 ulCurTime);


_______________________________________________
Audio-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/audio-dev

Reply via email to