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.

732 lines
17 KiB

  1. /****************************************************************************
  2. *
  3. * ACMSTRM.C
  4. *
  5. * routine for compressing audio with the ACM
  6. *
  7. * Copyright (c) 1992 Microsoft Corporation. All Rights Reserved.
  8. *
  9. * You have a royalty-free right to use, modify, reproduce and
  10. * distribute the Sample Files (and/or any modified version) in
  11. * any way you find useful, provided that you agree that
  12. * Microsoft has no warranty obligations or liability for any
  13. * Sample Application Files which are modified.
  14. *
  15. ***************************************************************************/
  16. //
  17. // What this file does:
  18. //
  19. // Given an audio Stream (that is, essentially, a function that it can call
  20. // to get audio samples), this presents the same sort of interface and allows
  21. // other people to call it to get compressed audio.
  22. //
  23. #include <windows.h>
  24. #include <windowsx.h>
  25. #include <win32.h>
  26. #include <mmsystem.h>
  27. #include <vfw.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <malloc.h>
  31. #include <ctype.h>
  32. #include <compobj.h>
  33. #include <mmreg.h>
  34. #include <msacm.h>
  35. #include "handler.h"
  36. #ifndef WIN32
  37. extern "C" LONG FAR PASCAL muldiv32(LONG,LONG,LONG);
  38. #endif
  39. #ifdef DEBUG
  40. static void CDECL dprintf(LPSTR, ...);
  41. #define DPF dprintf
  42. #else
  43. #define DPF ; / ## /
  44. #endif
  45. #define WAVEFORMATSIZE(pwf) \
  46. ((((LPWAVEFORMAT)(pwf))->wFormatTag == WAVE_FORMAT_PCM) ? \
  47. sizeof(PCMWAVEFORMAT) : \
  48. sizeof(WAVEFORMATEX) + ((LPWAVEFORMATEX)(pwf))->cbSize)
  49. HRESULT CACMCmpStream::MakeInst(
  50. IUnknown FAR* pUnknownOuter,
  51. const IID FAR& riid,
  52. void FAR* FAR* ppv)
  53. {
  54. IUnknown FAR* pUnknown;
  55. CACMCmpStream FAR* pAVIStream;
  56. HRESULT hresult;
  57. pAVIStream = new FAR CACMCmpStream(pUnknownOuter, &pUnknown);
  58. if (!pAVIStream)
  59. return ResultFromScode(E_OUTOFMEMORY);
  60. hresult = pUnknown->QueryInterface(riid, ppv);
  61. if (FAILED(GetScode(hresult)))
  62. delete pAVIStream;
  63. return hresult;
  64. }
  65. /* - - - - - - - - */
  66. CACMCmpStream::CACMCmpStream(
  67. IUnknown FAR* pUnknownOuter,
  68. IUnknown FAR* FAR* ppUnknown)
  69. {
  70. m_pavi = 0;
  71. m_hs = 0;
  72. m_lpFormat = 0;
  73. m_lpFormatC = 0;
  74. if (pUnknownOuter)
  75. m_pUnknownOuter = pUnknownOuter;
  76. else
  77. m_pUnknownOuter = this;
  78. *ppUnknown = this;
  79. m_refs = 0;
  80. }
  81. /* - - - - - - - - */
  82. STDMETHODIMP CACMCmpStream::QueryInterface(
  83. const IID FAR& iid,
  84. void FAR* FAR* ppv)
  85. {
  86. if (iid == IID_IUnknown)
  87. *ppv = (IUnknown FAR *) this;
  88. else if (iid == IID_IAVIStream)
  89. *ppv = (IAVIStream FAR *) this;
  90. else
  91. return ResultFromScode(E_NOINTERFACE);
  92. AddRef();
  93. return NULL;
  94. }
  95. /* - - - - - - - - */
  96. STDMETHODIMP_(ULONG) CACMCmpStream::AddRef()
  97. {
  98. uUseCount++;
  99. return ++m_refs;
  100. }
  101. /* - - - - - - - - */
  102. LONG CACMCmpStream::SetUpCompression()
  103. {
  104. LONG lRet = AVIERR_OK;
  105. // Get the initial format
  106. AVIStreamFormatSize(m_pavi, AVIStreamStart(m_pavi), &m_cbFormat);
  107. m_lpFormat = (LPWAVEFORMATEX) GlobalAllocPtr(GHND | GMEM_SHARE, m_cbFormat);
  108. if (!m_lpFormat) {
  109. lRet = AVIERR_MEMORY;
  110. goto exit;
  111. }
  112. AVIStreamReadFormat(m_pavi, AVIStreamStart(m_pavi), m_lpFormat, &m_cbFormat);
  113. if (m_lpFormatC != NULL) {
  114. // we already have the format, let's hope it works...
  115. // We could check if the format matches the original format....
  116. if (m_cbFormat == m_cbFormatC &&
  117. (_fmemcmp(m_lpFormat, m_lpFormatC, (int) m_cbFormat) == 0))
  118. goto sameformat;
  119. } else if (m_lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
  120. acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&m_cbFormatC);
  121. m_lpFormatC = (LPWAVEFORMATEX) GlobalAllocPtr(GHND | GMEM_SHARE, m_cbFormatC);
  122. if (!m_lpFormatC) {
  123. lRet = AVIERR_MEMORY;
  124. goto exit;
  125. }
  126. m_lpFormatC->wFormatTag = WAVE_FORMAT_PCM;
  127. if (acmFormatSuggest(NULL, m_lpFormat, m_lpFormatC, m_cbFormatC, 0L) != 0)
  128. goto sameformat;
  129. } else {
  130. sameformat:
  131. DPF("Leaving the format unchanged....\n");
  132. m_lpFormatC = m_lpFormat;
  133. m_cbFormatC = m_cbFormat;
  134. m_lpFormat = NULL;
  135. m_cbFormat = 0;
  136. m_hs = (HACMSTREAM) -1;
  137. goto exit;
  138. }
  139. ACMFORMATDETAILS afdU;
  140. ACMFORMATTAGDETAILS aftdU;
  141. ACMFORMATDETAILS afdC;
  142. ACMFORMATTAGDETAILS aftdC;
  143. afdU.cbStruct = sizeof(afdU);
  144. afdU.pwfx = m_lpFormat;
  145. afdU.cbwfx = m_cbFormat;
  146. afdU.fdwSupport = 0;
  147. afdU.dwFormatTag = m_lpFormat->wFormatTag;
  148. acmFormatDetails(NULL, &afdU, ACM_FORMATDETAILSF_FORMAT);
  149. aftdU.cbStruct = sizeof(aftdU);
  150. aftdU.dwFormatTag = m_lpFormat->wFormatTag;
  151. aftdU.fdwSupport = 0;
  152. acmFormatTagDetails(NULL,
  153. &aftdU, ACM_FORMATTAGDETAILSF_FORMATTAG);
  154. afdC.cbStruct = sizeof(afdC);
  155. afdC.pwfx = m_lpFormatC;
  156. afdC.cbwfx = m_cbFormatC;
  157. afdC.dwFormatTag = m_lpFormatC->wFormatTag;
  158. afdC.fdwSupport = 0;
  159. acmFormatDetails(NULL, &afdC, ACM_FORMATDETAILSF_FORMAT);
  160. aftdC.cbStruct = sizeof(aftdC);
  161. aftdC.dwFormatTag = m_lpFormatC->wFormatTag;
  162. aftdC.fdwSupport = 0;
  163. acmFormatTagDetails(NULL,
  164. &aftdC,
  165. ACM_FORMATTAGDETAILSF_FORMATTAG);
  166. DPF("Converting %s %s to %s %s\n", (LPSTR) &aftdU.szFormatTag, (LPSTR) &afdU.szFormat, (LPSTR) &aftdC.szFormatTag, (LPSTR) &afdC.szFormat);
  167. // Open the compressor they asked for...
  168. lRet = acmStreamOpen(&m_hs, // returned stream handle
  169. NULL, // use any converter you want
  170. m_lpFormat, // starting format
  171. m_lpFormatC, // ending format
  172. 0L, // no filter
  173. 0L, // no callback
  174. 0L, // instance data for callback
  175. ACM_STREAMOPENF_NONREALTIME);//emph. quality not speed
  176. // !!! translate error code
  177. if (!m_hs) {
  178. TCHAR ach[ACMFORMATDETAILS_FORMAT_CHARS * 5];
  179. TCHAR achTemp[128];
  180. static int iEntered = 0;
  181. LoadString(ghInst, IDS_CNVTERR, (LPTSTR)achTemp, sizeof(achTemp)/sizeof(TCHAR));
  182. wsprintf(ach, achTemp,
  183. (LPTSTR) &aftdU.szFormatTag,
  184. (LPTSTR) &afdU.szFormat,
  185. (LPTSTR) &aftdC.szFormatTag,
  186. (LPTSTR) &afdC.szFormat);
  187. LoadString(ghInst, IDS_ACMERR, (LPTSTR)achTemp, sizeof(achTemp)/sizeof(TCHAR));
  188. if (iEntered++ == 0)
  189. MessageBox(NULL, ach, achTemp, MB_OK);
  190. iEntered--;
  191. lRet = AVIERR_ERROR;
  192. goto exit;
  193. }
  194. // Fix avistream header
  195. m_avistream.dwSampleSize = m_lpFormatC->nBlockAlign;
  196. m_avistream.dwScale = m_lpFormatC->nBlockAlign;
  197. m_avistream.dwRate = m_lpFormatC->nAvgBytesPerSec;
  198. acmStreamSize(m_hs,
  199. AVIStreamLength(m_pavi) * m_lpFormat->nBlockAlign,
  200. (LPDWORD) &m_avistream.dwLength,
  201. ACM_STREAMSIZEF_SOURCE);
  202. // !!! acmStreamSize rounds up here, do we need to compensate?
  203. // !!! should we round off/up here?
  204. m_avistream.dwLength /= m_lpFormatC->nBlockAlign;
  205. m_avistream.dwQuality = 0; // !!!
  206. exit:
  207. if (lRet != AVIERR_OK) {
  208. // !!! Don't release here!
  209. }
  210. return lRet;
  211. }
  212. /* - - - - - - - - */
  213. //
  214. // ACM stream:
  215. //
  216. // lParam1 should be a PAVISTREAM (an audio one!)
  217. //
  218. // lParam2 should be an LPWAVEFORMAT for the format you want converted
  219. // to.
  220. //
  221. STDMETHODIMP CACMCmpStream::Create(LONG lParam1, LONG lParam2)
  222. {
  223. PAVISTREAM pavi = (PAVISTREAM) lParam1;
  224. LPAVICOMPRESSOPTIONS lpOpts = (LPAVICOMPRESSOPTIONS) lParam2;
  225. LPWAVEFORMAT lpwfNew = NULL;
  226. LONG lRet = AVIERR_OK;
  227. DPF("Creating ACM compression stream....\n");
  228. // Get the stream header for future reference....
  229. AVIStreamInfo(pavi, &m_avistream, sizeof(m_avistream));
  230. m_avistream.fccHandler = 0;
  231. if (m_avistream.fccType != streamtypeAUDIO) {
  232. DPF("Stream isn't audio!\n");
  233. lRet = AVIERR_INTERNAL;
  234. goto exit;
  235. }
  236. if (acmGetVersion() < 0x02000000L) {
  237. DPF("Bad ACM version!\n");
  238. lRet = AVIERR_INTERNAL;
  239. goto exit;
  240. }
  241. if (lpOpts && lpOpts->lpFormat) {
  242. lpwfNew = (LPWAVEFORMAT) lpOpts->lpFormat;
  243. if (lpOpts->cbFormat < WAVEFORMATSIZE(lpwfNew)) {
  244. DPF("Bad format size!\n");
  245. lRet = AVIERR_INTERNAL;
  246. goto exit;
  247. }
  248. m_cbFormatC = WAVEFORMATSIZE(lpwfNew);
  249. m_lpFormatC = (LPWAVEFORMATEX) GlobalAllocPtr(GMEM_MOVEABLE, m_cbFormatC);
  250. if (m_lpFormatC == NULL) {
  251. DPF("Out of memory for format!\n");
  252. lRet = AVIERR_MEMORY;
  253. goto exit;
  254. }
  255. hmemcpy(m_lpFormatC, lpOpts->lpFormat, m_cbFormatC);
  256. } else {
  257. m_cbFormatC = 0;
  258. m_lpFormatC = NULL;
  259. }
  260. // Make sure the uncompressed stream doesn't go away without our
  261. // knowledge....
  262. AVIStreamAddRef(pavi);
  263. // Don't put this in the structure until we've done the AddRef....
  264. m_pavi = pavi;
  265. exit:
  266. return ResultFromScode(lRet);
  267. }
  268. STDMETHODIMP_(ULONG) CACMCmpStream::Release()
  269. {
  270. if (--m_refs)
  271. return m_refs;
  272. if (m_lpFormat) {
  273. GlobalFreePtr(m_lpFormat);
  274. if (m_hs) {
  275. acmStreamClose(m_hs, 0);
  276. }
  277. }
  278. if (m_pavi) {
  279. // Release our hold on the uncompressed stream....
  280. AVIStreamClose(m_pavi);
  281. }
  282. if (m_lpFormatC)
  283. GlobalFreePtr(m_lpFormatC);
  284. delete this;
  285. return 0;
  286. }
  287. STDMETHODIMP CACMCmpStream::Info(AVISTREAMINFO FAR * psi, LONG lSize)
  288. {
  289. if (m_hs == 0) {
  290. LONG lRet;
  291. // !!! If they ask for info before writing or setting the
  292. // format, this will become a "read" stream!
  293. lRet = SetUpCompression();
  294. if (lRet != 0)
  295. return ResultFromScode(lRet);
  296. }
  297. hmemcpy(psi, &m_avistream, min(lSize, sizeof(m_avistream)));
  298. // return sizeof(m_avistream);
  299. return 0;
  300. }
  301. STDMETHODIMP CACMCmpStream::ReadFormat(LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat)
  302. {
  303. LONG lRet;
  304. if (m_hs == 0) {
  305. lRet = SetUpCompression();
  306. if (lRet != 0)
  307. return ResultFromScode(lRet);
  308. }
  309. if (lpFormat)
  310. hmemcpy(lpFormat,
  311. m_lpFormatC,
  312. min(*lpcbFormat, (LONG) m_cbFormatC));
  313. *lpcbFormat = (LONG) m_cbFormatC;
  314. return 0;
  315. }
  316. STDMETHODIMP CACMCmpStream::Read(
  317. LONG lStart,
  318. LONG lSamples,
  319. LPVOID lpBuffer,
  320. LONG cbBuffer,
  321. LONG FAR * plBytes,
  322. LONG FAR * plSamples)
  323. {
  324. LONG lRet;
  325. LONG cbTemp;
  326. LPVOID lpTemp;
  327. LONG lByteStart, lByteLen;
  328. LONG lSampStart, lSampLen;
  329. MMRESULT err;
  330. ACMSTREAMHEADER acm;
  331. HRESULT hr;
  332. DWORD dwACMFlags;
  333. if (m_hs == 0) {
  334. lRet = SetUpCompression();
  335. if (lRet != 0)
  336. return ResultFromScode(lRet);
  337. }
  338. if (m_lpFormat == NULL) {
  339. // Just return original format....
  340. return AVIStreamRead(m_pavi, lStart, lSamples,
  341. lpBuffer, cbBuffer, plBytes, plSamples);
  342. }
  343. if (lStart < 0 || lStart > (LONG) (m_avistream.dwStart + m_avistream.dwLength))
  344. return ResultFromScode(AVIERR_BADPARAM);
  345. if (lSamples == AVISTREAMREAD_CONVENIENT) {
  346. // If they didn't specify a number of samples, fill their buffer....
  347. lSamples = (cbBuffer ? cbBuffer : 32768L) / m_lpFormatC->nBlockAlign;
  348. }
  349. // Don't let anybody try to read past the end....
  350. if (lSamples + lStart >
  351. (LONG) (m_avistream.dwStart + m_avistream.dwLength))
  352. lSamples = (LONG) (m_avistream.dwStart + m_avistream.dwLength) -
  353. lStart;
  354. if (lSamples <= 0)
  355. return ResultFromScode(AVIERR_BADPARAM);
  356. if (lpBuffer) {
  357. LONG lDstBytes;
  358. if (cbBuffer < lSamples * m_lpFormatC->nBlockAlign) {
  359. DPF("Returning buffer too small\n");
  360. if (plBytes)
  361. *plBytes = lSamples * m_lpFormatC->nBlockAlign;
  362. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  363. }
  364. lDstBytes = lStart * m_lpFormatC->nBlockAlign;
  365. if (lDstBytes)
  366. acmStreamSize(m_hs, lDstBytes, (LPDWORD) &lByteStart,
  367. ACM_STREAMSIZEF_DESTINATION);
  368. else
  369. lByteStart = 0;
  370. lDstBytes = (lStart + lSamples) * m_lpFormatC->nBlockAlign;
  371. acmStreamSize(m_hs, lDstBytes, (LPDWORD) &lByteLen,
  372. ACM_STREAMSIZEF_DESTINATION);
  373. lByteLen -= lByteStart;
  374. lSampStart = lByteStart / m_lpFormat->nBlockAlign;
  375. lSampLen = (lByteLen + m_lpFormat->nBlockAlign - 1) /
  376. m_lpFormat->nBlockAlign;
  377. lRet = 0;
  378. cbTemp = lSampLen * m_lpFormat->nBlockAlign;
  379. lpTemp = GlobalAllocPtr(GMEM_MOVEABLE, cbTemp);
  380. if (!lpTemp)
  381. return ResultFromScode(AVIERR_MEMORY);
  382. hr = AVIStreamRead(m_pavi,
  383. lSampStart, lSampLen,
  384. lpTemp, cbTemp, NULL, &lRet);
  385. if (lRet != lSampLen) {
  386. DPF("AVIStreamRead: Asked for %lx samples at %lx, got %lx!\n", lSampLen, lSampStart, lRet);
  387. if (lRet < lSampLen) {
  388. // Fill buffer with silence, and hope....
  389. BYTE _huge *hp;
  390. LONG cb;
  391. BYTE b;
  392. cb = (lSampLen - lRet) * m_lpFormat->nBlockAlign;
  393. hp = (BYTE _huge *) lpTemp + lRet * m_lpFormat->nBlockAlign;
  394. if ((m_lpFormat->wFormatTag == WAVE_FORMAT_PCM) &&
  395. (m_lpFormat->wBitsPerSample == 8))
  396. b = 0x80;
  397. else
  398. b = 0;
  399. while (cb-- > 0)
  400. *hp++ = b;
  401. }
  402. // !!!
  403. // lSampLen = lRet; // !!!
  404. // lByteLen = lSampLen * m_lpFormat->nBlockAlign;
  405. }
  406. if (FAILED(GetScode(hr))) {
  407. DPF("AVIStreamReadFailed! (start=%lx, len=%lx, err=%08lx)\n", lSampStart, lSampLen, hr);
  408. return hr;
  409. }
  410. // !!! This is actually broken, if we want data that doesn't start
  411. // on a block align boundary.
  412. // To fix it, we need a second temporary buffer:
  413. // Consider the case where the user wants to read one byte of PCM
  414. // data from an ADPCM stream. We read a single block of ADPCM into
  415. // lpBuffer, but we need 256 bytes (or whatever) to decompress
  416. // it into, and the user's only given us a 1-byte buffer....
  417. acm.cbStruct = sizeof(acm);
  418. acm.fdwStatus = 0;
  419. acm.dwUser = 0;
  420. acm.pbSrc = (LPBYTE) lpTemp
  421. // + (lByteStart - lSampStart * m_lpFormat->nBlockAlign)
  422. ;
  423. acm.cbSrcLength = lByteLen;
  424. acm.cbSrcLengthUsed = 0;
  425. acm.pbDst = (LPBYTE) lpBuffer;
  426. acm.cbDstLength = cbBuffer;
  427. acm.cbDstLengthUsed = 0;
  428. dwACMFlags = 0; // !!! ACM_STREAMCONVERTF_BLOCKALIGN;
  429. // !!! add in start, end flags for ACM....
  430. err = acmStreamPrepareHeader(m_hs, &acm, 0);
  431. if (err != 0) {
  432. DPF("acmStreamPrepareHeader returns %u\n", err);
  433. return ResultFromScode(AVIERR_COMPRESSOR);
  434. }
  435. err = acmStreamConvert(m_hs, &acm, dwACMFlags);
  436. GlobalFreePtr(lpTemp); // This should be a permanent buffer!
  437. acmStreamUnprepareHeader(m_hs, &acm, 0);
  438. if (err != 0) {
  439. DPF("acmStreamConvert returns %u\n", err);
  440. return ResultFromScode(AVIERR_COMPRESSOR);
  441. }
  442. DPF("Converted %lu of %lu bytes to %lu bytes (buffer size = %lu)\n", acm.cbSrcLengthUsed, acm.cbSrcLength, acm.cbDstLengthUsed, acm.cbDstLength);
  443. // Lie: say that the ACM returned a full block....
  444. acm.cbDstLengthUsed += m_lpFormatC->nBlockAlign - 1;
  445. acm.cbDstLengthUsed -= acm.cbDstLengthUsed % m_lpFormatC->nBlockAlign;
  446. if (plBytes)
  447. *plBytes = (LONG) acm.cbDstLengthUsed;
  448. if (plSamples)
  449. *plSamples = (LONG) (acm.cbDstLengthUsed / m_lpFormatC->nBlockAlign);
  450. } else {
  451. // We always assume we could read whatever they asked for....
  452. if (plBytes)
  453. *plBytes = lSamples * m_lpFormatC->nBlockAlign;
  454. if (plSamples)
  455. *plSamples = lSamples;
  456. }
  457. return 0;
  458. }
  459. STDMETHODIMP_(LONG) CACMCmpStream::FindSample(LONG lPos, LONG lFlags)
  460. {
  461. if (lFlags & FIND_FORMAT) {
  462. if (lFlags & FIND_PREV)
  463. return 0;
  464. else {
  465. if (lPos > 0)
  466. return -1;
  467. else
  468. return 0;
  469. }
  470. }
  471. return lPos;
  472. }
  473. STDMETHODIMP CACMCmpStream::SetFormat(LONG lPos,LPVOID lpFormat,LONG cbFormat)
  474. {
  475. // !!! It should really be possible to use SetFormat & Write on this
  476. // stream.....
  477. return ResultFromScode(AVIERR_UNSUPPORTED);
  478. }
  479. STDMETHODIMP CACMCmpStream::Write(LONG lStart,
  480. LONG lSamples,
  481. LPVOID lpBuffer,
  482. LONG cbBuffer,
  483. DWORD dwFlags,
  484. LONG FAR *plSampWritten,
  485. LONG FAR *plBytesWritten)
  486. {
  487. // !!!
  488. // Maybe this is the place to decompress data and write it to the original
  489. // stream?
  490. return ResultFromScode(AVIERR_UNSUPPORTED);
  491. }
  492. STDMETHODIMP CACMCmpStream::Delete(LONG lStart,LONG lSamples)
  493. {
  494. return ResultFromScode(AVIERR_UNSUPPORTED);
  495. }
  496. STDMETHODIMP CACMCmpStream::ReadData(DWORD fcc, LPVOID lp, LONG FAR *lpcb)
  497. {
  498. return AVIStreamReadData(m_pavi, fcc, lp, lpcb);
  499. }
  500. STDMETHODIMP CACMCmpStream::WriteData(DWORD fcc, LPVOID lp, LONG cb)
  501. {
  502. return ResultFromScode(AVIERR_UNSUPPORTED);
  503. }
  504. #if 0
  505. STDMETHODIMP CACMCmpStream::Clone(PAVISTREAM FAR * ppaviNew)
  506. {
  507. return ResultFromScode(AVIERR_UNSUPPORTED);
  508. }
  509. #endif
  510. STDMETHODIMP CACMCmpStream::Reserved1(void)
  511. {
  512. return ResultFromScode(AVIERR_UNSUPPORTED);
  513. }
  514. STDMETHODIMP CACMCmpStream::Reserved2(void)
  515. {
  516. return ResultFromScode(AVIERR_UNSUPPORTED);
  517. }
  518. STDMETHODIMP CACMCmpStream::Reserved3(void)
  519. {
  520. return ResultFromScode(AVIERR_UNSUPPORTED);
  521. }
  522. STDMETHODIMP CACMCmpStream::Reserved4(void)
  523. {
  524. return ResultFromScode(AVIERR_UNSUPPORTED);
  525. }
  526. STDMETHODIMP CACMCmpStream::Reserved5(void)
  527. {
  528. return ResultFromScode(AVIERR_UNSUPPORTED);
  529. }
  530. /*****************************************************************************
  531. *
  532. * dprintf() is called by the DPF macro if DEBUG is defined at compile time.
  533. *
  534. * The messages will be send to COM1: like any debug message. To
  535. * enable debug output, add the following to WIN.INI :
  536. *
  537. * [debug]
  538. * ICSAMPLE=1
  539. *
  540. ****************************************************************************/
  541. #ifdef DEBUG
  542. #define MODNAME "ACMCMPRS"
  543. static BOOL fDebug = -1;
  544. static void cdecl dprintf(LPSTR szFormat, ...)
  545. {
  546. char ach[128];
  547. #ifdef WIN32
  548. va_list va;
  549. if (fDebug == -1)
  550. fDebug = GetProfileIntA("Debug",MODNAME, FALSE);
  551. if (!fDebug)
  552. return;
  553. va_start(va, szFormat);
  554. if (szFormat[0] == '!')
  555. ach[0]=0, szFormat++;
  556. else
  557. lstrcpyA(ach, MODNAME ": ");
  558. wvsprintfA(ach+lstrlenA(ach),szFormat,(LPSTR)va);
  559. va_end(va);
  560. // lstrcatA(ach, "\r\r\n");
  561. OutputDebugStringA(ach);
  562. #else
  563. if (fDebug == -1)
  564. fDebug = GetProfileInt("Debug",MODNAME, FALSE);
  565. if (!fDebug)
  566. return;
  567. if (szFormat[0] == '!')
  568. ach[0]=0, szFormat++;
  569. else
  570. lstrcpy(ach, MODNAME ": ");
  571. wvsprintf(ach+lstrlen(ach),szFormat,(LPSTR)(&szFormat+1));
  572. // lstrcat(ach, "\r\r\n");
  573. OutputDebugString(ach);
  574. #endif
  575. }
  576. #endif