+        ULONG32 ulTime   = 0;

We are deprecating ULONG32s in favor of UINT32s.

HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE

I think this might be confusing with our current fake timeline
if someone sees it in a .pf file. Can we rename it to something
like *_DEVICE_DRIFT_DETECTION or something that doesn't have
the word 'fake' in it.


rest looks good.
--greg.



On Jul 7, 2009, at 4:41 PM, Daniel Yek wrote:


Modified by: d...@real.com
Date: 7/7/2009
Project: RealPlayer for Netbook

Synopsis:
Imlemented New Helix Audio Device Simple Fake Timeline And Drift Detection

Overview:
When I was "bootstrapping" PulseAudio support implementation,
I wanted to test pushing of audio data, pa_xxxxxx_write(),
before I knew how accurate audio timing can be implemented.

So, I needed fake timeline support to drive the (rest of the)
Helix client engine to make available audio data
to enable the push model.

However, I found that if a clip contains an audio stream (necessary),
it is very difficult to get the Original Helix Fake Timeline support
working.

It is impossible to fake the audio timing
by incrementing it by a constant.
So, this HX_GET_TICKCOUNT() based fake timeline is necessary
to bootstrap an audio device support implementation.


New Helix Audio Device Simple Fake Timeline:
--------------------------------------------

I documented this New Helix Audio Device Simple Fake Timeline here:
https://audio.helixcommunity.org/2009/devdocs/HelixAudioDeviceFakeTimeline

To compile this New Helix Audio Device Simple Fake Timeline support
into hxmedplyeng, the macro:
HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
must be defined

In scenarios where this New Helix Audio Device Simple Fake Timeline
is useful, it can be turned on by setting the following Helix Preference:
FakeHelixAudioDeviceTimeline=1

Drift Detection:
----------------

Even when this New Helix Audio Device Simple Fake Timeline
isn't turned on (the default):
FakeHelixAudioDeviceTimeline=0
this implementation offers actual audio device timeline drift detection, by comparing the actual audio device timeline against HX_GET_TICKCOUNT().

If a full second of timeline drift is detected
(which will prevent playback from functioning normally),
a throttled message is shown (in the terminal).

A seek operation will restart the drift detection and
playback often recovers (from the stuck timeline.)




Files Modified:
audio/device/platform/unix/audUnix.cpp
audio/device/pub/platform/unix/audUnix.h

Image Size and Heap Use impact (Client -Only):
None.

Platforms and Profiles Affected:
Linux

Distribution Libraries Affected:
None.

Distribution library impact and planned action:
None.

Platforms and Profiles Build Verified:
Profile: helix_client_moblin
Platform: linux-2.2-libc6-gcc32-i586

Platforms and Profiles Functionality verified:
Profile: helix_client_moblin
Platform: linux-2.2-libc6-gcc32-i586

Branch: 347Atlas, 310Atlas.

Copyright assignment: I am a RealNetworks employee.


--
Daniel Yek.

Index: audio/device/platform/unix/audUnix.cpp
===================================================================
RCS file: /cvsroot/audio/device/platform/unix/audUnix.cpp,v
retrieving revision 1.12.2.3.14.1
diff -u -w -r1.12.2.3.14.1 audUnix.cpp
--- audio/device/platform/unix/audUnix.cpp 29 Jan 2009 09:57:09 -0000 1.12.2.3.14.1
+++ audio/device/platform/unix/audUnix.cpp      22 Jun 2009 23:13:51 -0000
@@ -69,15 +69,16 @@

#include <errno.h>

-#if defined(_THREADED_AUDIO) && defined(_UNIX_THREADS_SUPPORTED)
#include "hxprefs.h"
-#endif
+#include "hxprefutil.h"

#include "hxtlogutil.h"
#include "ihxtlogsystem.h"
#include "baseobj.h"
#include "nestbuff.h"

+#include "thrdutil.h"
+
//-1 is usually considered to be no file descriptor.
const int CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;

@@ -96,16 +100,22 @@
    m_pPlaybackCountCBTime(0),
    m_PendingCallbackID (0),
    m_bCallbackPending(FALSE),
+#ifdef HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+    m_bEnableFakeHelixAudioDeviceTimeline(FALSE),
+    m_ulFakeHelixAudioDeviceStartTime(0),
+    m_ulFakeHelixAudioDeviceCurrentTime(0),
+    m_ulTimelinesDeltaSecs(0),
+#endif // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
    m_pWriteList(NULL),
    m_wLastError( RA_AOE_NOERR ),
    m_ulDeviceBufferSize(0),
    m_pRollbackBuffer(NULL),
@@ -521,18 +587,19 @@
    m_wState = RA_AOS_OPEN_PLAYING;
    UNLOCK(m_mtxWriteListPlayStateLock);

- //XXXgfw If the two branches of the if are the same maybe get rid of one????
-    if( !_HardwarePauseSupported() )
+#ifdef HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+    // No harm setting.
+    m_ulFakeHelixAudioDeviceStartTime = HX_GET_TICKCOUNT();
+    m_ulTimelinesDeltaSecs = 0;
+
+    if (m_pContext)
    {
-        _Resume();
-        _Imp_Write(NULL);
+ ReadPrefBOOL(m_pContext, "FakeHelixAudioDeviceTimeline", m_bEnableFakeHelixAudioDeviceTimeline);
    }
-    else
-    {
-        //The hardware device handles the Pause/Resume.
+#endif // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
        _Resume();
        _Imp_Write(NULL);
-    }

    m_wLastError = HXR_OK;
    return m_wLastError;
@@ -560,6 +627,10 @@
        m_ulLastNumBytes  = 0;
    }

+#ifdef HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+    m_ulTimelinesDeltaSecs = 0;
+#endif // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
    m_wLastError = retCode;
    return m_wLastError;
}
@@ -607,6 +678,77 @@
    return m_wLastError;
}

+
+#ifdef HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
+// Time unit: msec.
+HX_RESULT CAudioOutUNIX::_Imp_GetCurrentTime( ULONG32& ulCurrentTime )
+{
+    if (m_bEnableFakeHelixAudioDeviceTimeline)
+    {
+ // When Helix Preference, FakeHelixAudioDeviceTimeline, is set to 1,
+        // Helix Audio Device fake timeline feature is enabled.
+ ulCurrentTime = m_ulFakeHelixAudioDeviceCurrentTime = (HX_GET_TICKCOUNT() - m_ulFakeHelixAudioDeviceStartTime);
+
+ HXLOGL4 (HXLOG_ADEV, "CAudioOutUNIX::_Imp_GetCurrentTime() = %i.", ulCurrentTime);
+
+        m_wLastError = HXR_OK;
+        return HXR_OK;
+    }
+    else
+    {
+        ULONG32 ulTime   = 0;
+        UINT64  ulBytes  = 0;
+
+ // Locking WriteListPlayStateLock first appears to cause deadlock in PulseAudio mainloop lock.
+        //LOCK(m_mtxWriteListPlayStateLock);
+        ulBytes = _GetBytesActualyPlayed();
+        //UNLOCK(m_mtxWriteListPlayStateLock);
+
+ ulTime = (ULONG32)(( ( (double)ulBytes/(double) m_uSampFrameSize)/(double)m_unSampleRate) * 1000.0 / (double) m_unNumChannels);
+
+        // XXXdyek:
+ // When Helix Preference, FakeHelixAudioDeviceTimeline, is set to 0,
+        // Helix Audio Device fake-timeline feature is disabled.
+        // However, in this case, the feature implements checking of
+        // timeline from real sound card driver
+        // against HX_GET_TICKCOUNT() reference.
+ // This enables easy runtime troubleshooting of timing information from sound card driver. + // This is likely to produce noise if PlaybackVelocity is used.
+        //   To disable check once PlaybackVelocity is employed.
+        UINT32 delta_secs = 0;
+ m_ulFakeHelixAudioDeviceCurrentTime = (HX_GET_TICKCOUNT() - m_ulFakeHelixAudioDeviceStartTime);
+
+ delta_secs = abs(ulTime - m_ulFakeHelixAudioDeviceCurrentTime) / 1000 ;
+
+        if (!m_ulTimelinesDeltaSecs)
+        {
+ m_ulTimelinesDeltaSecs = delta_secs; // Suppress messages for pause and resume.
+        }
+
+        if ( delta_secs > m_ulTimelinesDeltaSecs &&
+ ulTime // Avoid the spurious case where m_ulTimelinesDeltaSecs isn't reset in _Imp_Resume() yet.
+           )
+        {
+ fprintf(stderr, "Audio time line drifted %lu secs. from %lu ms to %lu ms\n", delta_secs, m_ulFakeHelixAudioDeviceCurrentTime, ulTime); + HXLOGL2 (HXLOG_ADEV, "CAudioOutUNIX::_Imp_GetCurrentTime () Audio time line drifted %lu secs. from %lu ms to %lu ms", delta_secs, m_ulFakeHelixAudioDeviceCurrentTime, ulTime);
+            m_ulTimelinesDeltaSecs = delta_secs;
+        }
+
+ // Not used anywhere but belongs to CHXAudioDevice so we must set it.
+        m_ulCurrentTime  = ulTime;
+
+        // Set the answer.
+        ulCurrentTime = ulTime;
+
+        m_wLastError = HXR_OK;
+        return HXR_OK;
+    }
+}
+
+#else // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
+// Original implementation.
HX_RESULT CAudioOutUNIX::_Imp_GetCurrentTime( ULONG32& ulCurrentTime )
{
    ULONG32 ulTime   = 0;
@@ -629,6 +771,9 @@

}

+#endif // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
+
void CAudioOutUNIX::DoTimeSyncs()
{
    ReschedPlaybackCheck();
Index: audio/device/pub/platform/unix/audUnix.h
===================================================================
RCS file: /cvsroot/audio/device/pub/platform/unix/audUnix.h,v
retrieving revision 1.8.2.2.14.1
diff -u -w -r1.8.2.2.14.1 audUnix.h
--- audio/device/pub/platform/unix/audUnix.h 29 Jan 2009 10:08:57 -0000 1.8.2.2.14.1 +++ audio/device/pub/platform/unix/audUnix.h 22 Jun 2009 23:13:51 -0000
@@ -256,6 +265,18 @@
ULONG32 m_PendingCallbackID; // Used for fake time sync HXBOOL m_bCallbackPending; // Used for fake time sync

+
+#ifdef HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+    // Used to implement fake Helix Audio Device Timeline.
+    // This implementation allows easy identification of
+    // broken timing information in sound card driver.
+    HXBOOL            m_bEnableFakeHelixAudioDeviceTimeline;
+    UINT32            m_ulFakeHelixAudioDeviceStartTime;
+    UINT32            m_ulFakeHelixAudioDeviceCurrentTime;
+ UINT32 m_ulTimelinesDeltaSecs; // Compare actual time line with fake Helix Audio Device timeline
+
+#endif // HELIX_FEATURE_FAKE_AUDIO_DEVICE_TIMELINE
+
    CHXSimpleList*    m_pWriteList;
    UINT32            m_unSampleRate;
    UINT32            m_unNumChannels;

_______________________________________________
Audio-dev mailing list
Audio-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio-dev


_______________________________________________
Audio-dev mailing list
Audio-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio-dev

Reply via email to