Some general questions:
1) GetBlocksRemainingToPlay() seems to depend on the accuracy of m_dGranularity. Where do we get m_dGranularity and how do we know it's accurate? 2) This seems to round either up or down: > ulBlocksPlayed = (ULONG32)(ulCurTime/m_dGranularity+.5); but I would think we would always want to round up, right? Then we would be always err on the side of sometimes *over-estimating* the number of blocks played, which would tend to make us err on the side of writing more to the device quicker. 3) Are there any concurrency issues? Do we know that the code that's modifying m_ulBlocksWritten is on the same thread as the code that's running GetBlocksRemainingToPlay()? Perhaps we might want to read m_ulBlocksWritten into a local variable.... Changes themselves look good. Eric > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Greg Wright > Sent: Tuesday, August 16, 2005 5:11 PM > To: [EMAIL PROTECTED]; > [EMAIL PROTECTED] > Subject: [Audio-dev] CR-Client: Make audio pushdown > calculations more robust. > > > 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 > _______________________________________________ Audio-dev mailing list [email protected] http://lists.helixcommunity.org/mailman/listinfo/audio-dev
