CDDAReader.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:13k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include <initguid.h>
  23. #include "cddareader.h"
  24. #include "......DSUtilDSUtil.h"
  25. #define RAW_SECTOR_SIZE 2352
  26. #define MSF2UINT(hgs) ((hgs[1]*4500)+(hgs[2]*75)+(hgs[3]))
  27. #ifdef REGISTER_FILTER
  28. const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
  29. {
  30. {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
  31. };
  32. const AMOVIESETUP_PIN sudOpPin[] =
  33. {
  34. {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut},
  35. };
  36. const AMOVIESETUP_FILTER sudFilter[] =
  37. {
  38. {&__uuidof(CCDDAReader), L"CDDA Reader", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin}
  39. };
  40. CFactoryTemplate g_Templates[] =
  41. {
  42. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CCDDAReader>, NULL, &sudFilter[0]}
  43. };
  44. int g_cTemplates = countof(g_Templates);
  45. STDAPI DllRegisterServer()
  46. {
  47. if(GetVersion()&0x80000000)
  48. {
  49. ::MessageBox(NULL, _T("Sorry, this will only run on Windows NT based operating system."), _T("CDDA Reader"), MB_OK);
  50. return E_NOTIMPL;
  51. }
  52. SetRegKeyValue(
  53. _T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{54A35221-2C8D-4a31-A5DF-6D809847E393}"), 
  54. _T("0"), _T("0,4,,52494646,8,4,,43444441")); // "RIFFxxxxCDDA"
  55. SetRegKeyValue(
  56. _T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{54A35221-2C8D-4a31-A5DF-6D809847E393}"), 
  57. _T("Source Filter"), _T("{54A35221-2C8D-4a31-A5DF-6D809847E393}"));
  58. SetRegKeyValue(
  59. _T("Media Type\Extensions"), _T(".cda"), 
  60. _T("Source Filter"), _T("{54A35221-2C8D-4a31-A5DF-6D809847E393}"));
  61. return AMovieDllRegisterServer2(TRUE);
  62. }
  63. STDAPI DllUnregisterServer()
  64. {
  65. DeleteRegKey(_T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{54A35221-2C8D-4a31-A5DF-6D809847E393}"));
  66. DeleteRegKey(_T("Media Type\Extensions"), _T(".cda"));
  67. return AMovieDllRegisterServer2(FALSE);
  68. }
  69. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  70. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  71. {
  72.     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  73. }
  74. #endif
  75. //
  76. // CCDDAReader
  77. //
  78. CCDDAReader::CCDDAReader(IUnknown* pUnk, HRESULT* phr)
  79. : CAsyncReader(NAME("CCDDAReader"), pUnk, &m_stream, phr, __uuidof(this))
  80. {
  81. if(phr) *phr = S_OK;
  82. if(GetVersion()&0x80000000)
  83. {
  84. if(phr) *phr = E_NOTIMPL;
  85. return;
  86. }
  87. }
  88. CCDDAReader::~CCDDAReader()
  89. {
  90. }
  91. STDMETHODIMP CCDDAReader::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  92. {
  93.     CheckPointer(ppv, E_POINTER);
  94. return 
  95. QI(IFileSourceFilter)
  96. QI2(IAMMediaContent)
  97. __super::NonDelegatingQueryInterface(riid, ppv);
  98. }
  99. // IFileSourceFilter
  100. STDMETHODIMP CCDDAReader::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt) 
  101. {
  102. if(!m_stream.Load(pszFileName))
  103. return E_FAIL;
  104. m_fn = pszFileName;
  105. CMediaType mt;
  106. mt.majortype = MEDIATYPE_Stream;
  107. mt.subtype = MEDIASUBTYPE_WAVE;
  108. m_mt = mt;
  109. return S_OK;
  110. }
  111. STDMETHODIMP CCDDAReader::GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt)
  112. {
  113. CheckPointer(ppszFileName, E_POINTER);
  114. if(!(*ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength()+1)*sizeof(WCHAR))))
  115. return E_OUTOFMEMORY;
  116. wcscpy(*ppszFileName, m_fn);
  117. return S_OK;
  118. }
  119. // IAMMediaContent
  120. STDMETHODIMP CCDDAReader::GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
  121. STDMETHODIMP CCDDAReader::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
  122. STDMETHODIMP CCDDAReader::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
  123. STDMETHODIMP CCDDAReader::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
  124. STDMETHODIMP CCDDAReader::get_AuthorName(BSTR* pbstrAuthorName)
  125. {
  126. CheckPointer(pbstrAuthorName, E_POINTER);
  127. CString str = m_stream.m_trackArtist;
  128. if(str.IsEmpty()) str = m_stream.m_discArtist;
  129. *pbstrAuthorName = str.AllocSysString();
  130. return S_OK;
  131. }
  132. STDMETHODIMP CCDDAReader::get_Title(BSTR* pbstrTitle)
  133. {
  134. CheckPointer(pbstrTitle, E_POINTER);
  135. CString str = m_stream.m_trackTitle;
  136. if(str.IsEmpty()) str = m_stream.m_discTitle;
  137. *pbstrTitle = str.AllocSysString();
  138. return S_OK;
  139. }
  140. STDMETHODIMP CCDDAReader::get_Rating(BSTR* pbstrRating) {return E_NOTIMPL;}
  141. STDMETHODIMP CCDDAReader::get_Description(BSTR* pbstrDescription) {return E_NOTIMPL;}
  142. STDMETHODIMP CCDDAReader::get_Copyright(BSTR* pbstrCopyright) {return E_NOTIMPL;}
  143. STDMETHODIMP CCDDAReader::get_BaseURL(BSTR* pbstrBaseURL) {return E_NOTIMPL;}
  144. STDMETHODIMP CCDDAReader::get_LogoURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
  145. STDMETHODIMP CCDDAReader::get_LogoIconURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
  146. STDMETHODIMP CCDDAReader::get_WatermarkURL(BSTR* pbstrWatermarkURL) {return E_NOTIMPL;}
  147. STDMETHODIMP CCDDAReader::get_MoreInfoURL(BSTR* pbstrMoreInfoURL) {return E_NOTIMPL;}
  148. STDMETHODIMP CCDDAReader::get_MoreInfoBannerImage(BSTR* pbstrMoreInfoBannerImage) {return E_NOTIMPL;}
  149. STDMETHODIMP CCDDAReader::get_MoreInfoBannerURL(BSTR* pbstrMoreInfoBannerURL) {return E_NOTIMPL;}
  150. STDMETHODIMP CCDDAReader::get_MoreInfoText(BSTR* pbstrMoreInfoText) {return E_NOTIMPL;}
  151. // CCDDAStream
  152. CCDDAStream::CCDDAStream()
  153. {
  154. m_hDrive = INVALID_HANDLE_VALUE;
  155. m_llPosition = m_llLength = 0;
  156. memset(&m_TOC, 0, sizeof(m_TOC));
  157. m_nStartSector = m_nStopSector = 0;
  158. memset(&m_header, 0, sizeof(m_header));
  159. m_header.riff.hdr.chunkID = RIFFID;
  160. m_header.riff.WAVE = WAVEID;
  161. m_header.frm.hdr.chunkID = FormatID;
  162. m_header.frm.hdr.chunkSize = sizeof(m_header.frm.pcm);
  163. m_header.frm.pcm.wf.wFormatTag = WAVE_FORMAT_PCM;
  164. m_header.frm.pcm.wf.nSamplesPerSec = 44100;
  165. m_header.frm.pcm.wf.nChannels = 2;
  166. m_header.frm.pcm.wBitsPerSample = 16;
  167. m_header.frm.pcm.wf.nBlockAlign = m_header.frm.pcm.wf.nChannels * m_header.frm.pcm.wBitsPerSample / 8;
  168. m_header.frm.pcm.wf.nAvgBytesPerSec = m_header.frm.pcm.wf.nSamplesPerSec * m_header.frm.pcm.wf.nBlockAlign;
  169. m_header.data.hdr.chunkID = DataID;
  170. }
  171. CCDDAStream::~CCDDAStream()
  172. {
  173. if(m_hDrive != INVALID_HANDLE_VALUE)
  174. {
  175. CloseHandle(m_hDrive);
  176. m_hDrive = INVALID_HANDLE_VALUE;
  177. }
  178. }
  179. bool CCDDAStream::Load(const WCHAR* fnw)
  180. {
  181. CString path(fnw);
  182. int iDriveLetter = path.Find(_T(":\"))-1;
  183. int iTrackIndex = CString(path).MakeLower().Find(_T(".cda"))-1;
  184. if(iDriveLetter < 0 || iTrackIndex <= iDriveLetter)
  185. return(false);
  186. CString drive = CString(_T("\\.\")) + path[iDriveLetter] + _T(":");
  187. while(iTrackIndex > 0 && _istdigit(path[iTrackIndex-1])) iTrackIndex--;
  188. if(1 != _stscanf(path.Mid(iTrackIndex), _T("%d"), &iTrackIndex))
  189. return(false);
  190. if(m_hDrive != INVALID_HANDLE_VALUE)
  191. {
  192. CloseHandle(m_hDrive);
  193. m_hDrive = INVALID_HANDLE_VALUE;
  194. }
  195. m_hDrive = CreateFile(drive, GENERIC_READ, FILE_SHARE_READ, NULL, 
  196. OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, (HANDLE)NULL);
  197. if(m_hDrive == INVALID_HANDLE_VALUE)
  198. {
  199. return(false);
  200. }
  201. DWORD BytesReturned;
  202. if(!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC, NULL, 0, &m_TOC, sizeof(m_TOC), &BytesReturned, 0)
  203. || !(m_TOC.FirstTrack <= iTrackIndex && iTrackIndex <= m_TOC.LastTrack))
  204. {
  205. CloseHandle(m_hDrive);
  206. m_hDrive = INVALID_HANDLE_VALUE;
  207. return(false);
  208. }
  209. // MMC-3 Draft Revision 10g: Table 222