Advertisement
Guest User

BonTuner.cpp

a guest
Sep 3rd, 2013
599
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.66 KB | None | 0 0
  1. // BonTuner.cpp: CBonTuner クラスのインプリメンテーション
  2. //   (DT300用)
  3. //////////////////////////////////////////////////////////////////////
  4.  
  5. #include "stdafx.h"
  6. #include <SetupApi.h>
  7. #include <Malloc.h>
  8. #include <InitGuid.h>
  9. #include <Math.h>
  10. #include <cstdio>
  11. #include <io.h>
  12. #include "Resource.h"
  13. #include "BonTuner.h"
  14.  
  15.  
  16. #pragma comment(lib, "SetupApi.lib")
  17.  
  18.  
  19. using namespace std ;
  20.  
  21. //////////////////////////////////////////////////////////////////////
  22. // 定数定義
  23. //////////////////////////////////////////////////////////////////////
  24.  
  25. // 受信サイズ(FX側の設定)
  26. DWORD TSDATASIZE        =   65536UL ;       // TSデータのサイズ
  27. DWORD TSQUEUENUM        =   16UL    ;       // TSデータの環状ストック数
  28. BOOL  BCASENABLED       =   TRUE    ;       // BCASデータ受信スレッドの有効化
  29. DWORD BCASDATASIZE      =   4096UL  ;       // BCASデータのサイズ
  30. DWORD BCASQUEUENUM      =   1UL     ;       // BCASデータの環状ストック数
  31.  
  32. // FIFOバッファ設定
  33. DWORD ASYNCTSQUEUENUM   =   512UL   ;       // 非同期TSデータの環状ストック数
  34.  
  35. // 電源設定
  36. BOOL AUTOPOWERON   = TRUE ;
  37. BOOL AUTOPOWEROFF  = TRUE ;
  38. DWORD U3BSFIXTUNE  = 0 ;
  39. DWORD U3BSFIXWAIT  = 15500 ;
  40. DWORD U3BSFIXCH    = 0 ;
  41. BOOL AUTOTUNEBACKTONHK = FALSE ;
  42.  
  43. // エンドポイントインデックス
  44. #define EPINDEX_IN          0UL
  45. #define EPINDEX_OUT         1UL
  46.  
  47. // コマンド
  48. #define CMD_EP6IN_START     0x50U   //
  49. #define CMD_EP6IN_STOP      0x51U   //
  50. #define CMD_EP2OUT_START    0x52U   //
  51. #define CMD_EP2OUT_STOP     0x53U   //
  52. #define CMD_PORT_CFG        0x54U   //addr_mask, out_pins
  53. #define CMD_REG_READ        0x55U   //addr  (return 1byte)
  54. #define CMD_REG_WRITE       0x56U   //addr, value
  55. #define CMD_PORT_READ       0x57U   //(return 1byte)
  56. #define CMD_PORT_WRITE      0x58U   //value
  57. #define CMD_IFCONFIG        0x59U   //value
  58. #define CMD_MODE_IDLE       0x5AU
  59. #define CMD_EP4IN_START     0x5BU   // B-CAS
  60. #define CMD_EP4IN_STOP      0x5CU   // B-CAS
  61. #define CMD_IR_CODE         0x5DU   //val_l, val_h (0x0000:RBUF capture 0xffff:BWUF output)
  62. #define CMD_IR_WBUF         0x5EU   //ofs(0 or 64 or 128 or 192), len(max 64), data, ....
  63. #define CMD_IR_RBUF         0x5FU   //ofs(0 or 64 or 128 or 192) (return 64byte)
  64. #define CMD_TSBCAS_INIT     0x70U   // TS - BCAS シンクロスタート
  65. #define CMD_TSBCAS_START    0x71U   // TS - BCAS シンクロスタート
  66. #define CMD_TSBCAS_END      0x72U   // TS - BCAS 終了
  67.  
  68. #define PIO_START           0x20
  69. #define PIO_IR_OUT          0x10
  70. #define PIO_IR_IN           0x08
  71. #define PIO_TS_BACK         0x04
  72.  
  73. // チューナーのリモコン番号
  74. DWORD IRNUMBER = 1UL ; // 1, 2 or 3
  75.  
  76. // ウェイト
  77.   // 追加: ButtonPressTimes,ButtonReleaseTimes,ButtonInterimWait @ 2013/06/03
  78.   //       (最新ファームでも発生するBSチャンネルスキャニングバグ対策用)
  79. DWORD COMMANDSENDTIMES   = 1 ; //2 ;
  80. DWORD COMMANDSENDWAIT    = 100 ;
  81. DWORD CHANNELCHANGEWAIT  = 500 ;
  82. DWORD BUTTONPRESSTIMES   = 2 ;
  83. DWORD BUTTONPRESSWAIT    = 300 ;
  84. DWORD BUTTONINTERIMWAIT  = 100 ;
  85. DWORD BUTTONRELEASETIMES = 2  ;
  86. DWORD BUTTONRELEASEWAIT  = 300 ;
  87. DWORD BUTTONSPACEWAIT    = 500 ;
  88. DWORD BUTTONPOWERWAIT    = 4000 ;
  89. BOOL REDUCESPACECHANGE   = TRUE ;
  90.  
  91. //リモコンのコマンド下二桁.0x04NN
  92. #define REMOCON_POWERON     0x8BU
  93. #define REMOCON_POWEROFF    0x8CU
  94.  
  95. #define REMOCON_CHIDEJI     0xD6U
  96. #define REMOCON_BS          0xE2U
  97. #define REMOCON_CS          0xE3U
  98.  
  99. #define REMOCON_3DIGITS     0xD8U
  100.  
  101. #define REMOCON_NUMBER_0    0x80U   //10と一緒
  102. #define REMOCON_NUMBER_1    0x81U
  103. #define REMOCON_NUMBER_2    0x82U
  104. #define REMOCON_NUMBER_3    0x83U
  105. #define REMOCON_NUMBER_4    0x84U
  106. #define REMOCON_NUMBER_5    0x85U
  107. #define REMOCON_NUMBER_6    0x86U
  108. #define REMOCON_NUMBER_7    0x87U
  109. #define REMOCON_NUMBER_8    0x88U
  110. #define REMOCON_NUMBER_9    0x89U
  111. #define REMOCON_NUMBER_10   0x80U
  112. #define REMOCON_NUMBER_11   0xD1U
  113. #define REMOCON_NUMBER_12   0xD2U
  114.  
  115. #define REMOCON_MENU        0x8FU
  116. #define REMOCON_UP          0x91U
  117. #define REMOCON_DOWN        0x92U
  118. #define REMOCON_LEFT        0x93U
  119. #define REMOCON_RIGHT       0x94U
  120. #define REMOCON_ENTER       0x95U
  121. #define REMOCON_BACK        0x96U
  122.  
  123.  
  124. // FX2ファームウェア
  125. static const BYTE abyFirmWare[] =
  126. #include "Fw.inc"
  127.  
  128. // FX2ファームウェア(sea)
  129. static const BYTE abyFirmWare_sea[] =
  130. #include "Fw_sea.inc"
  131.  
  132.  
  133. //////////////////////////////////////////////////////////////////////
  134. // チャンネル定義テーブル
  135. //////////////////////////////////////////////////////////////////////
  136.  
  137. const struct {
  138.     LPCTSTR pszSpace ;
  139.     LPCTSTR pszChName ;
  140.     const char* pszRCode ;
  141. } asChTbl[] = {
  142.     { TEXT("地デジ"), TEXT("リモコン 1"),              "X1" },
  143.     { TEXT("地デジ"), TEXT("リモコン 2"),              "X2" },
  144.     { TEXT("地デジ"), TEXT("リモコン 3"),              "X3" },
  145.     { TEXT("地デジ"), TEXT("リモコン 4"),              "X4" },
  146.     { TEXT("地デジ"), TEXT("リモコン 5"),              "X5" },
  147.     { TEXT("地デジ"), TEXT("リモコン 6"),              "X6" },
  148.     { TEXT("地デジ"), TEXT("リモコン 7"),              "X7" },
  149.     { TEXT("地デジ"), TEXT("リモコン 8"),              "X8" },
  150.     { TEXT("地デジ"), TEXT("リモコン 9"),              "X9" },
  151.     { TEXT("地デジ"), TEXT("リモコン 10"),             "XA" },
  152.     { TEXT("地デジ"), TEXT("リモコン 11"),             "XB" },
  153.     { TEXT("地デジ"), TEXT("リモコン 12"),             "XC" },
  154.     { TEXT("BS"),     TEXT("BS1/TS0 BS朝日"),          "YD151" },
  155.     { TEXT("BS"),     TEXT("BS1/TS1 BS-i"),            "YD161" },
  156.     { TEXT("BS"),     TEXT("BS3/TS0 WOWOW"),           "YD191" },
  157.     { TEXT("BS"),     TEXT("BS3/TS1 BSジャパン"),      "YD171" },
  158.     { TEXT("BS"),     TEXT("BS9/TS0 BS11"),            "YD211" },
  159.     { TEXT("BS"),     TEXT("BS9/TS1 Star Channel HV"), "YD200" },
  160.     { TEXT("BS"),     TEXT("BS9/TS2 TwellV"),          "YD222" },
  161.     { TEXT("BS"),     TEXT("BS13/TS0 BS日テレ"),       "YD141" },
  162.     { TEXT("BS"),     TEXT("BS13/TS1 BSフジ"),         "YD181" },
  163.     { TEXT("BS"),     TEXT("BS15/TS1 NHK BS1/2"),      "YD101" },
  164.     { TEXT("BS"),     TEXT("BS15/TS2 NHK BS-hi"),      "YD103" },
  165.     { TEXT("110CS"),  TEXT("ND2 110CS #1"),            "ZD239" },
  166.     { TEXT("110CS"),  TEXT("ND4 110CS #2"),            "ZD194" },
  167.     { TEXT("110CS"),  TEXT("ND6 110CS #3"),            "ZD310" },
  168.     { TEXT("110CS"),  TEXT("ND8 110CS #4"),            "ZD055" },
  169.     { TEXT("110CS"),  TEXT("ND10 110CS #5"),           "ZD228" },
  170.     { TEXT("110CS"),  TEXT("ND12 110CS #6"),           "ZD323" },
  171.     { TEXT("110CS"),  TEXT("ND14 110CS #7"),           "ZD251" },
  172.     { TEXT("110CS"),  TEXT("ND16 110CS #8"),           "ZD342" },
  173.     { TEXT("110CS"),  TEXT("ND18 110CS #9"),           "ZD314" },
  174.     { TEXT("110CS"),  TEXT("ND20 110CS #10"),          "ZD340" },
  175.     { TEXT("110CS"),  TEXT("ND22 110CS #11"),          "ZD330" },
  176.     { TEXT("110CS"),  TEXT("ND24 110CS #12"),          "ZD321" },
  177. } ;
  178.  
  179. //////////////////////////////////////////////////////////////////////
  180. // ユーティリティ
  181. //////////////////////////////////////////////////////////////////////
  182.  
  183. static string trim(string str)
  184. {
  185.   string str2 = "" ;
  186.   for(string::size_type i=0;i<str.size();i++) {
  187.     if(BYTE(str[i])>0x20) {
  188.       str2 = str.substr(i,str.size()-i) ;
  189.       break ;
  190.     }
  191.   }
  192.   if(str2=="") return "" ;
  193.   for(string::size_type i=str2.size();i>0;i--) {
  194.     if(BYTE(str2[i-1])>0x20) {
  195.       return str2.substr(0,i) ;
  196.     }
  197.   }
  198.   return "" ;
  199. }
  200.  
  201. static wstring mbcs2wcs(string src)
  202. {
  203.     wchar_t *wcs = new wchar_t[src.length()*2 + 1];
  204.     size_t wLen = 0;
  205.     setlocale(LC_ALL,"japanese");
  206.     mbstowcs_s(&wLen, wcs, src.length()*2 , src.c_str(), _TRUNCATE);
  207.     wstring result = wcs;
  208.     delete [] wcs;
  209.     return result ;
  210. }
  211.  
  212. //////////////////////////////////////////////////////////////////////
  213. // インスタンス生成メソッド
  214. //////////////////////////////////////////////////////////////////////
  215.  
  216. #pragma warning( disable : 4273 )
  217.  
  218. extern "C" __declspec(dllexport) IBonDriver * CreateBonDriver()
  219. {
  220.     // スタンス生成(既存の場合はインスタンスのポインタを返す)
  221.     return (CBonTuner::m_pThis)? CBonTuner::m_pThis : ((IBonDriver *) new CBonTuner);
  222. }
  223.  
  224. #pragma warning( default : 4273 )
  225.  
  226.  
  227. //////////////////////////////////////////////////////////////////////
  228. // 構築/消滅
  229. //////////////////////////////////////////////////////////////////////
  230.  
  231. // 静的メンバ初期化
  232. CBonTuner * CBonTuner::m_pThis = NULL;
  233. HINSTANCE CBonTuner::m_hModule = NULL;
  234.  
  235. CBonTuner::CBonTuner()
  236.     : m_pUsbFx2Driver(NULL)
  237.     , m_hOnStreamEvent(NULL)
  238.     , m_dwCurSpace(0)
  239.     , m_cLastSpace(0xFF)
  240.     , m_dwCurChannel(50)
  241.     , m_pEcm(NULL)
  242.     , m_bU3BSFixDone(FALSE)
  243. {
  244.     m_pEcm = new CEcmDat() ;
  245.     m_pEcm->SetDiag(FALSE);
  246.     m_pThis = this;
  247.     m_bytesProceeded = 0 ;
  248.     m_tickProceeding = GetTickCount() ;
  249.     InitTunerProperty() ;
  250. }
  251.  
  252. CBonTuner::~CBonTuner()
  253. {
  254.     // 開かれてる場合は閉じる
  255.     CloseTuner();
  256.  
  257.     if (m_pEcm) {
  258.         m_pEcm->exit();
  259.         delete m_pEcm;
  260.         m_pEcm = NULL ;
  261.     }
  262.  
  263.     m_pThis = NULL;
  264. }
  265.  
  266. const BOOL CBonTuner::OpenTuner()
  267. {
  268.     // 一旦クローズ
  269.     CloseTuner();
  270.  
  271.     is_channel_valid = FALSE;
  272.  
  273.     m_cLastSpace = 0xFF ;
  274.  
  275.     m_bU3BSFixDone = FALSE ;
  276.  
  277.     // カメレオンUSB FX2のドライバインスタンス生成
  278.     m_pUsbFx2Driver = new CUsbFx2Driver(this);
  279.     if(!m_pUsbFx2Driver)return false;
  280.  
  281.     // FX2の初期化シーケンス
  282.     try{
  283.         // FIFOバッファ確保
  284.         AllocFifoBuff();
  285.  
  286.         // イベント作成
  287.         if(!(m_hOnStreamEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL)))throw 0UL;
  288.  
  289.         // ドライバオープン
  290.         if(BCASENABLED) {
  291.           if(!m_pUsbFx2Driver->OpenDriver( m_yFx2Id, abyFirmWare_sea, sizeof(abyFirmWare_sea), "FX2_FIFO_SEA"))throw 0UL;
  292.         }else {
  293.           if(!m_pUsbFx2Driver->OpenDriver( m_yFx2Id, abyFirmWare, sizeof(abyFirmWare),"FX2_FIFO"))throw 0UL;
  294.         }
  295.  
  296.         // エンドポイント追加
  297.         if(!m_pUsbFx2Driver->AddEndPoint(0x81U))throw 1UL;  // EPINDEX_IN
  298.         if(!m_pUsbFx2Driver->AddEndPoint(0x01U))throw 2UL;  // EPINDEX_OUT
  299.  
  300.         // FX2 I/Oポート設定 & MAX2初期パラメータ設定 & MAX2リセット
  301.         if(!m_pUsbFx2Driver->TransmitFormatedData(EPINDEX_OUT, 6UL, CMD_PORT_CFG, 0x00U, PIO_START | PIO_IR_OUT | PIO_TS_BACK, CMD_MODE_IDLE, CMD_IFCONFIG, 0xE3U))throw 3UL;
  302.  
  303.         // スレッド起動
  304.         if(!m_pUsbFx2Driver->CreateFifoThread(0x86U, &m_dwFifoThreadIndex, TSDATASIZE, TSQUEUENUM ))throw 4UL;
  305.         if(BCASENABLED) {
  306.           if(!m_pUsbFx2Driver->CreateFifoThread(0x84U, &m_dwFifoBcasThreadIndex, BCASDATASIZE, BCASQUEUENUM ))throw 4UL;
  307.           // 開始コマンド送信
  308.           if(!m_pUsbFx2Driver->TransmitFormatedData(EPINDEX_OUT, 4UL, CMD_TSBCAS_INIT, CMD_TSBCAS_START, CMD_PORT_WRITE, PIO_START | PIO_IR_OUT | PIO_TS_BACK))throw 3UL;
  309.         }else {
  310.           m_dwFifoBcasThreadIndex = 0xFFFFFFFF ;
  311.           // 開始コマンド送信
  312.           if(!m_pUsbFx2Driver->TransmitFormatedData(EPINDEX_OUT, 3UL, CMD_EP6IN_START, CMD_PORT_WRITE, PIO_START | PIO_IR_OUT | PIO_TS_BACK))throw 3UL;
  313.         }
  314.  
  315.         // リモコンベースコード決定
  316.         m_wIRBase = WORD(max(min(IRNUMBER,3UL),1UL)-1UL) * 0x80U ;
  317.  
  318.         // 成功
  319.         if(AUTOPOWERON)
  320.           IRCodeTX(REMOCON_POWERON);    //電源を入れる
  321.  
  322.         // DT-300 古いファームウェアの BS チューニングバグ対策 Method #1
  323.         if(U3BSFIXTUNE) {
  324.           if(U3BSFIXTUNE==1)
  325.             m_bU3BSFixDone = U3BSFixTune() ;
  326.           IRCodeTX(REMOCON_CHIDEJI) ;
  327.         }
  328.  
  329.         return TRUE;
  330.         }
  331.     catch(DWORD dwErrorStep){
  332.         // エラー発生
  333.         dwErrorStep += 0 ; // to avoid warnning4101
  334.         CloseTuner();
  335.  
  336.         return FALSE;
  337.         }
  338.  
  339. }
  340.  
  341. void CBonTuner::CloseTuner()
  342. {
  343.     // ドライバを閉じる
  344.     if(m_pUsbFx2Driver){
  345.  
  346.         // 次回起動時BS復元処理用にBSのチャンネルを戻しておく設定
  347.         // (起動直後はBSチャンネルを認識しないのでこのタイミングで設定しておく)
  348.         if(U3BSFIXTUNE) {
  349.           if(m_bU3BSFixDone&&U3BSFIXCH) {
  350.             U3BSFixResetChannel() ;
  351.           }
  352.         }
  353.  
  354.         // 終了時にNHKにチャンネルを戻すかどうか
  355.         if(AUTOTUNEBACKTONHK) {
  356.           Sleep(COMMANDSENDWAIT) ;
  357.           IRCodeTX(REMOCON_CHIDEJI) ;
  358.           IRCodeTX(REMOCON_NUMBER_1) ;
  359.         }
  360.  
  361.         if(BCASENABLED) {
  362.           m_pUsbFx2Driver->TransmitFormatedData(EPINDEX_OUT, 3UL,
  363.             CMD_PORT_WRITE, PIO_IR_OUT|PIO_TS_BACK,
  364.             CMD_TSBCAS_END ) ;
  365.         }
  366.  
  367.         if(AUTOPOWEROFF) {
  368.           Sleep(COMMANDSENDWAIT) ;
  369.           IRCodeTX(REMOCON_POWEROFF);   //電源を切る
  370.         }
  371.  
  372.         m_pUsbFx2Driver->CloseDriver();
  373.         delete m_pUsbFx2Driver;
  374.         m_pUsbFx2Driver = NULL;
  375.         }
  376.  
  377.     // ハンドルを閉じる
  378.     if(m_hOnStreamEvent){
  379.         ::CloseHandle(m_hOnStreamEvent);
  380.         m_hOnStreamEvent = NULL;
  381.         }
  382.  
  383.     // バッファ開放
  384.     FreeFifoBuff();
  385.     // その他初期化
  386.     m_dwCurSpace = 0 ;
  387.     m_dwCurChannel = 50 ;
  388. }
  389.  
  390. BOOL CBonTuner::U3BSFixTune()
  391. {
  392.   Sleep(COMMANDSENDWAIT) ;
  393.   if(
  394.     !IRCodeTX(REMOCON_BS)    ||
  395.     !IRCodeTX(REMOCON_MENU)  ||
  396.     !IRCodeTX(REMOCON_DOWN)  ||
  397.     !IRCodeTX(REMOCON_ENTER) ||
  398.     !IRCodeTX(REMOCON_ENTER)    )  return FALSE ;
  399.   Sleep(U3BSFIXWAIT) ;  // BS-Digital 検出まで約14-5秒くらいかかる
  400.   if(!IRCodeTX(REMOCON_MENU)) return FALSE ;
  401.   Sleep(BUTTONSPACEWAIT) ;
  402.   return TRUE ;
  403. }
  404.  
  405. BOOL CBonTuner::U3BSFixResetChannel()
  406. {
  407.   Sleep(COMMANDSENDWAIT) ;
  408.   if(
  409.     !IRCodeTX(REMOCON_BS) ||
  410.     !IRCodeTX(REMOCON_3DIGITS) ||
  411.     !IRCodeTX(REMOCON_NUMBER_0+(U3BSFIXCH/100U)%10U) ||
  412.     !IRCodeTX(REMOCON_NUMBER_0+(U3BSFIXCH/10U)%10U) ||
  413.     !IRCodeTX(REMOCON_NUMBER_0+U3BSFIXCH%10U) ) return FALSE ;
  414.   return TRUE ;
  415. }
  416.  
  417. const BOOL CBonTuner::SetChannel(const BYTE bCh)
  418. {
  419.  
  420.     //とりあえずストリームをとめる
  421.     is_channel_valid = FALSE;
  422.  
  423.  
  424.     // TSデータパージ
  425.     PurgeTsStream();
  426.  
  427.     if(bCh < 0 || bCh >= m_Channels.size()){
  428.         return FALSE;
  429.     }
  430.  
  431.     //念のため2回送る
  432.     for(size_t j = 0; j < COMMANDSENDTIMES; j++){
  433.         //1個ずつ送る
  434.         Sleep(COMMANDSENDWAIT) ;
  435.         #if 0 // 元ソース
  436.         for(i = 0; i < REMOCON_CMD_LEN; i++){
  437.             if('\0' == m_Channels[bCh].rcode[i]){
  438.                 break;
  439.             }
  440.             if(!IRButtonTX(m_Channels[bCh].rcode[i])){
  441.                return FALSE ;
  442.             }
  443.         }
  444.         #else // mod5 rev 修正版
  445.         for(size_t i = 0; i < min<size_t>(m_Channels[bCh].rcode.size(),REMOCON_CMD_LEN); i++){
  446.             if(!IRButtonTX(m_Channels[bCh].rcode[i])){
  447.                return FALSE ;
  448.             }
  449.         }
  450.         #endif
  451.     }
  452.  
  453.     Sleep(CHANNELCHANGEWAIT) ;
  454.  
  455.     //ストリーム送る
  456.     is_channel_valid = TRUE;
  457.     return TRUE;
  458. }
  459.  
  460.  
  461. const float CBonTuner::GetSignalLevel(void)
  462. {
  463.     #if 0
  464.     // FIFOバッファのFullnessを返す
  465.     return ((float)m_FifoBuffer.size() / (float)ASYNCTSQUEUENUM * 100.0f);
  466.     #else
  467.     // 実際に処理したストリームの転送量 Mbps を返す
  468.     DWORD tick = GetTickCount() ;
  469.     float duration ;
  470.     if(tick>=m_tickProceeding) {
  471.       duration = float( tick -  m_tickProceeding + 1 ) ;
  472.     }else {
  473.       duration = float( 0xFFFFFFFF - m_tickProceeding + tick + 1 ) ;
  474.     }
  475.     duration /= 1000.f ;
  476.     float result = (float)m_bytesProceeded*8.f / duration / 1024.f / 1024.f ;
  477.     m_tickProceeding = tick ;
  478.     m_bytesProceeded = 0 ;
  479.     if(result>100.f) result = 0.f ;
  480.     return result ;
  481.     #endif
  482. }
  483.  
  484. const DWORD CBonTuner::WaitTsStream(const DWORD dwTimeOut)
  485. {
  486.  
  487.  
  488.     // 終了チェック
  489.     if(!m_pUsbFx2Driver)return WAIT_ABANDONED;
  490.  
  491.     // イベントがシグナル状態になるのを待つ
  492.     const DWORD dwRet = ::WaitForSingleObject(m_hOnStreamEvent, (dwTimeOut)? dwTimeOut : INFINITE);
  493.  
  494.     switch(dwRet){
  495.         case WAIT_ABANDONED :
  496.             // チューナが閉じられた
  497.             return WAIT_ABANDONED;
  498.  
  499.         case WAIT_OBJECT_0 :
  500.         case WAIT_TIMEOUT :
  501.             // ストリーム取得可能 or チューナが閉じられた
  502.             return (m_pUsbFx2Driver)? dwRet : WAIT_ABANDONED;
  503.  
  504.         case WAIT_FAILED :
  505.         default:
  506.             // 例外
  507.             return WAIT_FAILED;
  508.         }
  509. }
  510.  
  511. const DWORD CBonTuner::GetReadyCount()
  512. {
  513.     // 取り出し可能TSデータ数を取得する
  514.     return m_FifoBuffer.size();
  515. }
  516.  
  517. const BOOL CBonTuner::GetTsStream(BYTE *pDst, DWORD *pdwSize, DWORD *pdwRemain)
  518. {
  519.     // TSデータをバッファから取り出す
  520.     BYTE *pSrc = NULL;
  521.  
  522.     if(GetTsStream(&pSrc, pdwSize, pdwRemain)){
  523.         if(*pdwSize){
  524.             CopyMemory(pDst, pSrc, *pdwSize);
  525.             }
  526.  
  527.         return TRUE;
  528.         }
  529.  
  530.     return FALSE;
  531. }
  532.  
  533. const BOOL CBonTuner::GetTsStream(BYTE **ppDst, DWORD *pdwSize, DWORD *pdwRemain)
  534. {
  535.     CBlockLock Lock(&m_CriticalLock);
  536.  
  537.     if(!m_pUsbFx2Driver)return FALSE;
  538.  
  539.     // TSデータをバッファから取り出す
  540.     if(m_FifoBuffer.size()){
  541.         // データコピー
  542.         *pdwSize = m_FifoBuffer.front().second; // TSDATASIZE;
  543.         *ppDst = m_FifoBuffer.front().first;
  544.         m_FifoBuffer.pop();
  545.         *pdwRemain = m_FifoBuffer.size() ;
  546.  
  547.         return TRUE;
  548.         }
  549.     else{
  550.         // 取り出し可能なデータがない
  551.         *pdwSize = 0;
  552.         *pdwRemain = 0;
  553.  
  554.         return TRUE;
  555.         }
  556. }
  557.  
  558. void CBonTuner::PurgeTsStream()
  559. {
  560.     // バッファから取り出し可能データをパージする
  561.     CBlockLock Lock(&m_CriticalLock);
  562.  
  563.     // 未処理のデータをパージする
  564.     while(!m_FifoBuffer.empty()){
  565.         m_FifoBuffer.pop();
  566.         }
  567. }
  568.  
  569. void CBonTuner::Release()
  570. {
  571.     // インスタンス開放
  572.     delete this;
  573. }
  574.  
  575. const bool CBonTuner::OnRecvFifoData(const DWORD dwThreadIndex, const BYTE *pData, const DWORD dwLen, CUsbFx2Driver *pDriver)
  576. {
  577.     if (dwThreadIndex == m_dwFifoThreadIndex) {
  578.         CBlockLock Lock(&m_CriticalLock);
  579.         //有効なチャンネルが選択されている時に限って
  580.         if(is_channel_valid){
  581.             // FIFOバッファにプッシュ
  582.             PushFifoBuff(pData,dwLen);
  583.             m_bytesProceeded+=dwLen ;
  584.         }
  585.         // イベントセット
  586.         ::SetEvent(m_hOnStreamEvent);
  587.     }
  588.     else if (dwThreadIndex == m_dwFifoBcasThreadIndex) {
  589.         if(m_pEcm) m_pEcm->set(pData, dwLen);
  590.         m_bytesProceeded+=dwLen ;
  591.     }
  592.  
  593.     return true;
  594. }
  595.  
  596. void CBonTuner::AllocFifoBuff(void)
  597. {
  598.     // FIFOバッファをパージする
  599.     PurgeTsStream();
  600.  
  601.     // バッファプールを確保する
  602.     m_BufferPool.resize(ASYNCTSQUEUENUM);
  603.  
  604.     for(DWORD dwPos = 0UL ; dwPos < ASYNCTSQUEUENUM ; dwPos++){
  605.         m_BufferPool[dwPos].resize(TSDATASIZE);
  606.         }
  607.  
  608.     m_dwEmptyFifoPos = 0UL;
  609. }
  610.  
  611. void CBonTuner::FreeFifoBuff(void)
  612. {
  613.     // FIFOバッファをパージする
  614.     PurgeTsStream();
  615.  
  616.     // バッファプールを開放する
  617.     m_BufferPool.clear();
  618. }
  619.  
  620. void CBonTuner::PushFifoBuff(const BYTE *pData, DWORD dwLen)
  621. {
  622.     // バッファプールの最大数を超える場合は最後尾を切り捨てる
  623.     while(m_FifoBuffer.size() >= ASYNCTSQUEUENUM){
  624.         m_FifoBuffer.pop();
  625.         }
  626.  
  627.     // バッファプールにデータコピー
  628.     m_BufferPool[m_dwEmptyFifoPos].resize(dwLen) ;
  629.     BYTE *pWritePointer = static_cast<BYTE*>(m_BufferPool[m_dwEmptyFifoPos].top()) ;
  630.     CopyMemory(pWritePointer, pData, dwLen );
  631.  
  632.     // FIFOバッファにプッシュ
  633.     m_FifoBuffer.push(make_pair(pWritePointer,dwLen));
  634.  
  635.     // バッファプール位置更新
  636.     if(++m_dwEmptyFifoPos >= ASYNCTSQUEUENUM)m_dwEmptyFifoPos = 0UL;
  637. }
  638.  
  639. // 0x04NNを送信
  640. BOOL CBonTuner::IRCodeTX(BYTE code)
  641. {
  642.     BYTE cmd[3];
  643.     DWORD len = 0;
  644.  
  645.     switch(code) {
  646.       //チューナースペース切り替えが省略可能な場合は何もしない
  647.       case REMOCON_CHIDEJI:
  648.       case REMOCON_BS:
  649.       case REMOCON_CS:
  650.         if(REDUCESPACECHANGE && code==m_cLastSpace) {
  651.           return TRUE ;
  652.         }
  653.         break ;
  654.     }
  655.  
  656.     for(int i=0;i<BUTTONPRESSTIMES;i++) {
  657.       cmd[len++] = CMD_IR_CODE;
  658.       cmd[len++] = code;
  659.       cmd[len++] = 0x04U;
  660.       *LPWORD(&cmd[1]) += m_wIRBase ;
  661.       if(!m_pUsbFx2Driver->TransmitData(EPINDEX_OUT,cmd,len)){
  662.           return FALSE;
  663.       }
  664.       len = 0;
  665.       Sleep(BUTTONPRESSWAIT);
  666.     }
  667.  
  668.     Sleep(BUTTONINTERIMWAIT);
  669.  
  670.     //cap_stsからそのままパクる.詳細不明.
  671.     for(int i=0;i<BUTTONRELEASETIMES;i++) {
  672.       cmd[len++] = CMD_IR_CODE;
  673.       cmd[len++] = 0;
  674.       cmd[len++] = 0;
  675.       if(!m_pUsbFx2Driver->TransmitData(EPINDEX_OUT,cmd,len)){
  676.           return FALSE;
  677.       }
  678.       len = 0;
  679.       Sleep(BUTTONRELEASEWAIT);
  680.     }
  681.  
  682.     switch(code) {
  683.       //チューナースペース切り替え直後は反応が悪いので待つ
  684.       case REMOCON_CHIDEJI:
  685.       case REMOCON_BS:
  686.       case REMOCON_CS:
  687.         if(m_cLastSpace!=code) {
  688.           m_cLastSpace = code ;
  689.           Sleep(BUTTONSPACEWAIT) ;
  690.         }
  691.         break ;
  692.       //電源をON/OFF直後はリモコン反応しないので.反応するようになるまで4秒待つ.
  693.       case REMOCON_POWERON:
  694.       case REMOCON_POWEROFF:
  695.         Sleep(BUTTONPOWERWAIT);
  696.         break ;
  697.     }
  698.     return TRUE;
  699. }
  700.  
  701. // 自分の名前からチューナータイプとIDを決定
  702. BOOL CBonTuner::InitTunerProperty(void)
  703. {
  704.     //自分の名前を取得
  705.     char szMyPath[_MAX_PATH] ;
  706.     GetModuleFileNameA( m_hModule, szMyPath, _MAX_PATH ) ;
  707.     char szMyDrive[_MAX_FNAME] ;
  708.     char szMyDir[_MAX_FNAME] ;
  709.     char szMyName[_MAX_FNAME] ;
  710.     _splitpath_s( szMyPath, szMyDrive, _MAX_FNAME,szMyDir, _MAX_FNAME, szMyName, _MAX_FNAME, NULL, 0 ) ;
  711.     _strupr_s( szMyName, sizeof(szMyName) ) ;
  712.     //バンド数とFX2IDを取得
  713.     int nNumBands = 3, nFx2Id = 0 ;
  714.     sscanf_s( szMyName, "BONDRIVER_U%1dID%1d", &nNumBands, &nFx2Id ) ;
  715.     LPCTSTR pszTunerName ;
  716.     m_Channels.clear() ;
  717.     int numChannels = (sizeof(asChTbl)/sizeof(asChTbl[0])) ;
  718.     string strUnitedPrefix ;
  719.     if ( nNumBands == 3 ) {
  720.       pszTunerName = TEXT("ユニデン3波") ;
  721.       strUnitedPrefix = "BonDriver_U3" ;
  722.     }
  723.     else {
  724.       pszTunerName = TEXT("ユニデン地デジ") ;
  725.       numChannels = 12 ;
  726.       strUnitedPrefix = "BonDriver_U1" ;
  727.     }
  728.     m_yFx2Id = BYTE(nFx2Id) ;
  729.     //チューナー名を決定
  730.     _stprintf_s( m_szTunerName, 100, TEXT("%s(ID=%d)"), pszTunerName, nFx2Id ) ;
  731.     for(int i=0;i<numChannels;i++) {
  732.       m_Channels.push_back(CHANNEL(asChTbl[i].pszSpace,asChTbl[i].pszChName,asChTbl[i].pszRCode)) ;
  733.     }
  734.     //Iniファイルのロード
  735.     #if 0
  736.     if(!LoadIniFile(string(szMyDrive)+string(szMyDir)+string(szMyName)+".ini"))
  737.       LoadIniFile(string(szMyDrive)+string(szMyDir)+strUnitedPrefix+".ini") ;
  738.     #else
  739.     LoadIniFile(string(szMyDrive)+string(szMyDir)+strUnitedPrefix+".ini") ;
  740.     LoadIniFile(string(szMyDrive)+string(szMyDir)+string(szMyName)+".ini") ;
  741.     #endif
  742.     //チャンネルファイルのロード
  743.     DBGOUT("Channel File Try Loading...\r\n") ;
  744.     if(!LoadChannelFile(string(szMyDrive)+string(szMyDir)+string(szMyName)+".ch.txt"))
  745.       LoadChannelFile(string(szMyDrive)+string(szMyDir)+strUnitedPrefix+".ch.txt") ;
  746.     return TRUE ;
  747. }
  748.  
  749. bool CBonTuner::LoadIniFile(string strIniFileName)
  750. {
  751.   if(_access(strIniFileName.c_str(), 0)) return false ;
  752.   DBGOUT("Loading Ini \"%s\"...\n",strIniFileName.c_str()) ;
  753.   #define LOADINT(key) do { \
  754.       key = GetPrivateProfileIntA("BonTuner",#key, \
  755.         key,strIniFileName.c_str()) ; \
  756.       DBGOUT("%s = %d\n",#key,key) ; \
  757.     }while(0)
  758.   LOADINT(TSDATASIZE) ;
  759.   LOADINT(TSQUEUENUM) ;
  760.   LOADINT(BCASENABLED) ;
  761.   LOADINT(BCASDATASIZE) ;
  762.   LOADINT(BCASQUEUENUM) ;
  763.   LOADINT(ASYNCTSQUEUENUM) ;
  764.   LOADINT(AUTOPOWERON) ;
  765.   LOADINT(AUTOPOWEROFF) ;
  766.   LOADINT(U3BSFIXTUNE) ;
  767.   LOADINT(U3BSFIXWAIT) ;
  768.   LOADINT(U3BSFIXCH) ;
  769.   LOADINT(AUTOTUNEBACKTONHK) ;
  770.   LOADINT(IRNUMBER) ;
  771.   LOADINT(COMMANDSENDTIMES) ;
  772.   LOADINT(COMMANDSENDWAIT) ;
  773.   LOADINT(CHANNELCHANGEWAIT) ;
  774.   LOADINT(BUTTONPRESSTIMES) ;
  775.   LOADINT(BUTTONPRESSWAIT) ;
  776.   LOADINT(BUTTONINTERIMWAIT) ;
  777.   LOADINT(BUTTONRELEASETIMES) ;
  778.   LOADINT(BUTTONRELEASEWAIT) ;
  779.   LOADINT(BUTTONSPACEWAIT) ;
  780.   LOADINT(BUTTONPOWERWAIT) ;
  781.   LOADINT(REDUCESPACECHANGE) ;
  782.   #undef LOADINT
  783.   if(m_pEcm) m_pEcm->LoadIniFile(strIniFileName) ;
  784.   return true ;
  785. }
  786.  
  787. bool CBonTuner::LoadChannelFile(string strChannelFileName)
  788. {
  789.   FILE *st=NULL ;
  790.   fopen_s(&st,strChannelFileName.c_str(),"rt") ;
  791.   if(!st) return false;
  792.   char s[512] ;
  793.   m_Channels.clear() ;
  794.   while(!feof(st)) {
  795.     s[0]='\0' ;
  796.     fgets(s,512,st) ;
  797.     int t=0 ;
  798.     string params[3] ;
  799.     params[0] = params[1] = params[2] = "" ;
  800.     for(int i=0;s[i];i++) {
  801.       if(s[i]==';') break ;
  802.       else if(s[i]==',') {
  803.         t++ ; if(t==3) break ;
  804.       }else params[t] += s[i] ;
  805.     }
  806.     if(t>=2) {
  807.       DBGOUT("Channel(%d)= %s, %s, %s\r\n",m_Channels.size(),trim(params[0]).c_str(),trim(params[1]).c_str(),trim(params[2]).c_str()) ;
  808.       m_Channels.push_back(
  809.         CHANNEL(mbcs2wcs(trim(params[0])),mbcs2wcs(trim(params[1])),trim(params[2])) ) ;
  810.     }
  811.   }
  812.   DBGOUT("Channel File Loaded. (Total %d Channels)\r\n",m_Channels.size()) ;
  813.   fclose(st) ;
  814.   return true ;
  815. }
  816.  
  817.  
  818. BYTE CBonTuner::ConvButtonToCode(BYTE button)
  819. {
  820.     switch(button){
  821.         case 'X':
  822.             return REMOCON_CHIDEJI;
  823.         case 'Y':
  824.             return REMOCON_BS;
  825.         case 'Z':
  826.             return REMOCON_CS;
  827.         case 'D' :
  828.             return REMOCON_3DIGITS;
  829.  
  830.         case '0':
  831.             return REMOCON_NUMBER_0;    //Aと一緒なわけですが
  832.         case '1':
  833.             return REMOCON_NUMBER_1;
  834.         case '2':
  835.             return REMOCON_NUMBER_2;
  836.         case '3':
  837.             return REMOCON_NUMBER_3;
  838.         case '4':
  839.             return REMOCON_NUMBER_4;
  840.         case '5':
  841.             return REMOCON_NUMBER_5;
  842.         case '6':
  843.             return REMOCON_NUMBER_6;
  844.         case '7':
  845.             return REMOCON_NUMBER_7;
  846.         case '8':
  847.             return REMOCON_NUMBER_8;
  848.         case '9':
  849.             return REMOCON_NUMBER_9;
  850.         case 'A':
  851.             return REMOCON_NUMBER_10;
  852.         case 'B':
  853.             return REMOCON_NUMBER_11;
  854.         case 'C':
  855.             return REMOCON_NUMBER_12;
  856.  
  857.         case 'P':
  858.             return REMOCON_POWERON;
  859.         case 'Q':
  860.             return REMOCON_POWEROFF;
  861.  
  862.         default:
  863.             return 0;
  864.     }
  865. }
  866.  
  867. BOOL CBonTuner::IRButtonTX(BYTE button)
  868. {
  869.   BYTE code = ConvButtonToCode(button) ;
  870.  
  871.   // DT-300 古いファームウェアの BS チューニングバグ対策 Method #2
  872.   if( U3BSFIXTUNE==2 && !m_bU3BSFixDone && code==REMOCON_BS ) {
  873.     return m_bU3BSFixDone = U3BSFixTune() ;
  874.   }
  875.  
  876.   return IRCodeTX(code) ;
  877. }
  878.  
  879. LPCTSTR CBonTuner::GetTunerName(void)
  880. {
  881.     // チューナ名を返す
  882.     return m_szTunerName ;
  883. }
  884.  
  885. const BOOL CBonTuner::IsTunerOpening(void)
  886. {
  887.     // チューナの使用中の有無を返す(全プロセスを通して)
  888.     if( m_pUsbFx2Driver != NULL ){
  889.         return TRUE;
  890.     }else{
  891.         return FALSE;
  892.     }
  893. }
  894.  
  895. LPCTSTR CBonTuner::EnumTuningSpace(const DWORD dwSpace)
  896. {
  897.     // 0は最初の空間を返す
  898.     if ( dwSpace == 0 ) return m_Channels[0].c_space() ;
  899.     // 次の空間名を探す
  900.     DWORD dwSpcIdx = 0 ;
  901.     int nIdx0 = 0 ;
  902.     for ( CHANNELS::size_type nIdx = 0 ; nIdx < m_Channels.size() ; nIdx++ ) {
  903.         if ( m_Channels[nIdx0].space == m_Channels[nIdx].space ) continue ;
  904.         nIdx0 = nIdx ;
  905.         dwSpcIdx++ ;
  906.         if ( dwSpace == dwSpcIdx ) return m_Channels[nIdx].c_space() ;
  907.     }
  908.     return NULL ;
  909. }
  910.  
  911. LPCTSTR CBonTuner::EnumChannelName(const DWORD dwSpace, const DWORD dwChannel)
  912. {
  913.     // 空間名を取得する
  914.     LPCTSTR pszSpace = EnumTuningSpace( dwSpace ) ;
  915.     if ( !pszSpace ) return NULL ;
  916.     wstring space = wstring(pszSpace) ;
  917.     // 空間名の一致するチャンネルを探す
  918.     DWORD dwChIdx = 0 ;
  919.     for ( CHANNELS::size_type nIdx = 0 ; nIdx < m_Channels.size() ; nIdx++ ) {
  920.         if ( space != m_Channels[nIdx].space ) continue ;
  921.         if ( dwChIdx == dwChannel ) return m_Channels[nIdx].c_name() ;
  922.         dwChIdx++ ;
  923.     }
  924.     return NULL ;
  925. }
  926.  
  927. const BOOL CBonTuner::SetChannel(const DWORD dwSpace, const DWORD dwChannel)
  928. {
  929.     // 空間名を取得する
  930.     LPCTSTR pszSpace = EnumTuningSpace( dwSpace ) ;
  931.     if ( !pszSpace ) return FALSE ;
  932.     wstring space = wstring(pszSpace) ;
  933.     // 空間名の一致するチャンネルを探す
  934.     DWORD dwChIdx = 0 ;
  935.     for ( CHANNELS::size_type nIdx = 0 ; nIdx < m_Channels.size() ; nIdx++ ) {
  936.         if ( space != m_Channels[nIdx].space ) continue ;
  937.         if ( dwChIdx == dwChannel ) {
  938.             // チャンネルを設定する
  939.             if( SetChannel((BYTE)nIdx) == TRUE ){
  940.                 m_dwCurSpace = dwSpace;
  941.                 m_dwCurChannel = dwChannel;
  942.                 return TRUE;
  943.             }else{
  944.                 return FALSE;
  945.             }
  946.         }
  947.         dwChIdx++ ;
  948.     }
  949.     return FALSE ;
  950. }
  951.  
  952. const DWORD CBonTuner::GetCurSpace(void)
  953. {
  954.     // 現在のチューニング空間を返す
  955.     return m_dwCurSpace;
  956. }
  957.  
  958. const DWORD CBonTuner::GetCurChannel(void)
  959. {
  960.     // 現在のチャンネルを返す
  961.     return m_dwCurChannel;
  962. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement