Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.8 KiB

  1. // Copyright (c) 1996-2000 Microsoft Corporation. All rights reserved.
  2. /* CPhaseLockClock
  3. */
  4. #include "common.h"
  5. #define STR_MODULENAME "DDKSynth.sys:PLClock: "
  6. #include "plclock.h"
  7. #define MILS_TO_REF 10000
  8. #pragma code_seg()
  9. /*****************************************************************************
  10. * CPhaseLockClock::CPhaseLockClock()
  11. *****************************************************************************
  12. * Constructor for the CPhaseLockClock object.
  13. */
  14. CPhaseLockClock::CPhaseLockClock()
  15. {
  16. m_rfOffset = 0;
  17. }
  18. /*****************************************************************************
  19. * CPhaseLockClock::Start()
  20. *****************************************************************************
  21. * Start this clock. When the clock starts, it needs to mark down the
  22. * difference between the time it is given and its concept of time.
  23. */
  24. void CPhaseLockClock::Start(REFERENCE_TIME rfMasterTime, REFERENCE_TIME rfSlaveTime)
  25. {
  26. m_rfOffset = rfMasterTime - rfSlaveTime;
  27. }
  28. /*****************************************************************************
  29. * CPhaseLockClock::GetSlaveTime()
  30. *****************************************************************************
  31. * Convert the passed time to use the same base as the master clock.
  32. */
  33. void CPhaseLockClock::GetSlaveTime(REFERENCE_TIME rfSlaveTime, REFERENCE_TIME *prfTime)
  34. {
  35. rfSlaveTime += m_rfOffset;
  36. *prfTime = rfSlaveTime;
  37. }
  38. /*****************************************************************************
  39. * CPhaseLockClock::SetSlaveTime()
  40. *****************************************************************************
  41. * Reset the relationship between the two clocks.
  42. */
  43. void CPhaseLockClock::SetSlaveTime(REFERENCE_TIME rfSlaveTime, REFERENCE_TIME *prfTime)
  44. {
  45. rfSlaveTime -= m_rfOffset;
  46. *prfTime = rfSlaveTime;
  47. }
  48. /*****************************************************************************
  49. * CPhaseLockClock::SyncToMaster()
  50. *****************************************************************************
  51. * SyncToTime provides the needed magic to keep the clock
  52. * in sync. Since the clock uses its own clock (rfSlaveTime)
  53. * to increment, it can drift. This call provides a reference
  54. * time which the clock compares with its internal
  55. * concept of time. The difference between the two is
  56. * considered the drift. Since the sync time may increment in
  57. * a lurching way, the correction has to be subtle.
  58. * So, the difference between the two is divided by
  59. * 100 and added to the offset.
  60. */
  61. void CPhaseLockClock::SyncToMaster(REFERENCE_TIME rfSlaveTime, REFERENCE_TIME rfMasterTime)
  62. {
  63. rfSlaveTime += m_rfOffset;
  64. rfSlaveTime -= rfMasterTime; // Find difference between calculated and expected time.
  65. rfSlaveTime /= 100; // Reduce in magnitude.
  66. m_rfOffset -= rfSlaveTime; // Subtract that from the original offset.
  67. }
  68. /*****************************************************************************
  69. * CSampleClock::CSampleClock()
  70. *****************************************************************************
  71. * Constructor for CSampleClock object.
  72. */
  73. CSampleClock::CSampleClock()
  74. {
  75. m_llStart = 0;
  76. m_dwSampleRate = 22050;
  77. }
  78. /*****************************************************************************
  79. * CSampleClock::Start()
  80. *****************************************************************************
  81. * Start the sample clock. Start any corresponding phase lock clock.
  82. */
  83. void CSampleClock::Start(IReferenceClock *pIClock, DWORD dwSampleRate, LONGLONG llSampleTime)
  84. {
  85. REFERENCE_TIME rfStart;
  86. m_llStart = llSampleTime;
  87. m_dwSampleRate = dwSampleRate;
  88. if (pIClock)
  89. {
  90. pIClock->GetTime(&rfStart);
  91. m_PLClock.Start(rfStart,0);
  92. }
  93. llSampleTime *= (MILS_TO_REF * 1000);
  94. llSampleTime /= m_dwSampleRate;
  95. m_rfStart = llSampleTime;
  96. }
  97. /*****************************************************************************
  98. * CSampleClock::SampleToRefTime()
  99. *****************************************************************************
  100. * Convert between sample time and reference time (100ns units).
  101. */
  102. void CSampleClock::SampleToRefTime(LONGLONG llSampleTime,REFERENCE_TIME *prfTime)
  103. {
  104. llSampleTime -= m_llStart;
  105. llSampleTime *= (MILS_TO_REF * 1000);
  106. llSampleTime /= m_dwSampleRate;
  107. m_PLClock.GetSlaveTime(llSampleTime, prfTime);
  108. }
  109. /*****************************************************************************
  110. * CSampleClock::RefTimeToSample()
  111. *****************************************************************************
  112. * Convert between sample time and reference time (100ns units).
  113. */
  114. LONGLONG CSampleClock::RefTimeToSample(REFERENCE_TIME rfTime)
  115. {
  116. m_PLClock.SetSlaveTime(rfTime, &rfTime);
  117. rfTime *= m_dwSampleRate;
  118. rfTime /= (MILS_TO_REF * 1000);
  119. return rfTime + m_llStart;
  120. }
  121. /*****************************************************************************
  122. * CSampleClock::SyncToMaster()
  123. *****************************************************************************
  124. * Sync this clock to the given sample time and the given reference clock.
  125. */
  126. void CSampleClock::SyncToMaster(LONGLONG llSampleTime, IReferenceClock *pIClock)
  127. {
  128. llSampleTime -= m_llStart;
  129. llSampleTime *= (MILS_TO_REF * 1000);
  130. llSampleTime /= m_dwSampleRate;
  131. if (pIClock)
  132. {
  133. REFERENCE_TIME rfMasterTime;
  134. pIClock->GetTime(&rfMasterTime);
  135. m_PLClock.SyncToMaster(llSampleTime, rfMasterTime);
  136. }
  137. }
  138. /*****************************************************************************
  139. * CSampleClock::SyncToMaster()
  140. *****************************************************************************
  141. * Sync the two given reference times, using our phase lock clock.
  142. */
  143. void CSampleClock::SyncToMaster(REFERENCE_TIME rfSlaveTime, REFERENCE_TIME rfMasterTime)
  144. {
  145. rfSlaveTime -= m_rfStart;
  146. m_PLClock.SyncToMaster(rfSlaveTime, rfMasterTime);
  147. }