多媒體高精度定時器介紹

一:背景 

     在Windows系統下播放多媒體時,需要去精確控制播放過程,如果用Windows產生的WM_TIMER常規定時器來實現,多媒體畫面會出現斷斷續續的現象,原因在於WM_TIMER只能提供大於等於55ms的精確定時。解決辦法就是利用Windows系統本身提供的一個可以精確到1ms的多媒體定時器,它完全可以保證多媒體播放的實時性要求。

     在Windows系統下播放多媒體時,需要去精確控制播放過程,如果用Windows產生的WM_TIMER常規定時器來實現,多媒體畫面會出現斷斷續續的現象,原因在於WM_TIMER只能提供大於等於55ms的精確定時。解決辦法就是利用Windows系統本身提供的一個可以精確到1ms的多媒體定時器,它完全可以保證多媒體播放的實時性要求

二:使用函數與變量

     1:LARGE_INTEGER

         類型是union,用於表示64位有符號整數值.其他定義如下:    

         typeef union _ LARGE_INTEGER
         {
          struct
          {
              DWORD LowPart;
              LONG HighPart;
          };
          LONGLONG QuadPart;
          } LARGE_INTEGER;
   

          特     點:如果你有編譯器直接支持64位整數可以直接使用QuadPart(64位),否則分別對LowPart(32位)和HighPart(32位)存取,

                       HighPart的最高位爲符號位。 

          表示範圍:--3689348814741910324到+4611686018427387903 
          內存佈局:LARGE_INTEGER的值等4000000000,在內存中的佈局: 
                       00   28   6B   EE       00   00   00   00        

                      (低字節   )             (高字節   )   

      2:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

          類   型:Win32API

          作   用:返回硬件支持的高精度計數器的頻率。

          返回值:非零,硬件支持高精度計數器;零,硬件不支持,讀取失敗。

          描   述:技術特點供WIN9X使用的高精度定時器,要求計算機從硬件上支持高精度定時器。

       2:BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount); 

           類   型:Win32API

           作   用:返回硬件支持的高精度計數器的頻率技術值。

           返回值:非零,硬件支持高精度計數器;零,硬件不支持,讀取失敗。
           描   述:

三:實現過程 

     在定時前應該先調用QueryPerformanceFrequency()函數獲得機器內部計時器的時鐘頻率;

     接着在需要嚴格計時的事件發生前和發生之後分別調用QueryPerformanceCounter();

     最後利用兩次獲得的計數之差和時鐘頻率,就可以計算出事件經歷的精確時間。

四:示例1 測試函數SLEEP(100)的精確持續時間方法:
    LARGE_INTEGER freq;     //CUP頻率
    LARGE_INTEGER count1;   //第一次CPU計數值
    LARGE_INTEGER count2;   //第二次CPU計數值
    double ld_freq   = 0.0;
    double ld_count1 = 0.0;
    double ld_count2 = 0.0;

    //獲得時鐘頻率
  QueryPerformanceFrequency(&freq);
  ld_freq=(double)freq.QuadPart;
    //獲得第一次CPU計數值
    QueryPerformanceCounter(&count1);
    ld_count1=count1.QuadPart;
    Sleep(100);
    //獲得第二次CPU計數值
  QueryPerformanceCounter(&count2);
  ld_count2=count2.QuadPart;
  dfm=(double)(ld_count2-ld_count1);
  dft=dfm/dff;//獲得對應的時間值
備註:需要注意的是DFT計算的結果單位是秒。
   示例2 毫秒級延遲
   void Delay_MS(double delay_ms)
   {
    LARGE_INTEGER CPU_freq      ;//CUP頻率
    LARGE_INTEGER CPU_count_base;//開始計數值
    LARGE_INTEGER CPU_count_curr;//當前技術值
    double passed_time          ;//從0開始,過來多長時間
    //獲得時鐘頻率
    QueryPerformanceFrequency(&CPU_freq);
    //獲取開始寄存器計數值
    QueryPerformanceCounter(&CPU_count_base);
    //計時等待
    do
    {
        QueryPerformanceCounter(&CPU_count_curr);
        passed_time = ((CPU_count_curr.QuadPart - CPU_count_base.QuadPart) * 1000) / CPU_freq.QuadPart;
    }while (passed_time < delay_ms);
   }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章