Leaked source code of windows server 2003
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.

520 lines
18 KiB

  1. #include "precomp.h"
  2. /*************************************************************************
  3. Function: AudioFile::OpenSourceFile(MMIOSRC *pSrcFile, WAVEFORMATEX *pwf)
  4. Purpose : Opens wav file to read audio data from.
  5. Returns : HRESULT.
  6. Params : None
  7. Comments: * Registry keys:
  8. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\PlayFromFile\fPlayFromFile
  9. If set to zero, data will not be read from wav file.
  10. If set to a non null value <= INT_MAX, data will be read from wav file.
  11. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\PlayFromFile\szInputFileName
  12. Name of the wav file to read audio data from.
  13. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\PlayFromFile\fLoop
  14. If set to zero, the file will only be read once.
  15. If set to a non null value <= INT_MAX, the file will be read circularly.
  16. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\PlayFromFile\cchIOBuffer
  17. If set to zero, size of the MM IO buffer is set to its default value (8Kbytes).
  18. If set to one, size of the MM IO buffer is set to match maximum size of the wav file.
  19. If set a non null value between 2 and INT_MAX, size of the MM IO buffer is set to cchIOBuffer bytes.
  20. History : Date Reason
  21. 06/02/96 Created - PhilF
  22. *************************************************************************/
  23. HRESULT AudioFile::OpenSourceFile (MMIOSRC *pSrcFile, WAVEFORMATEX *pwf)
  24. {
  25. HRESULT hr = DPR_SUCCESS;
  26. MMIOINFO mmioInfo;
  27. long cchBuffer;
  28. WAVEFORMATEX *pwfFile;
  29. DWORD dw;
  30. FX_ENTRY ("SendAudioStream::OpenSrcFile")
  31. RegEntry reIPhoneInFile(szRegInternetPhone TEXT("\\") szRegInternetPhoneInputFile,
  32. HKEY_LOCAL_MACHINE,
  33. FALSE,
  34. KEY_READ);
  35. // For now, get the file name from the registry
  36. if (pSrcFile->fPlayFromFile = reIPhoneInFile.GetNumberIniStyle(TEXT("fPlayFromFile"), FALSE))
  37. {
  38. lstrcpyn(pSrcFile->szInputFileName,
  39. reIPhoneInFile.GetString(TEXT("szInputFileName")),
  40. CCHMAX(pSrcFile->szInputFileName));
  41. cchBuffer = reIPhoneInFile.GetNumberIniStyle(TEXT("cchIOBuffer"), 0L);
  42. pSrcFile->fLoop = reIPhoneInFile.GetNumberIniStyle(TEXT("fLoop"), TRUE);
  43. pSrcFile->fDisconnectAfterPlayback
  44. = reIPhoneInFile.GetNumberIniStyle(TEXT("fDisconnectAfterPlayback"), FALSE);
  45. cchBuffer = MMIO_DEFAULTBUFFER;
  46. ZeroMemory(&mmioInfo, sizeof(MMIOINFO));
  47. do
  48. {
  49. mmioInfo.cchBuffer = cchBuffer;
  50. pSrcFile->hmmioSrc = mmioOpen((LPSTR)&(pSrcFile->szInputFileName[0]), (LPMMIOINFO)&mmioInfo, MMIO_READ | MMIO_DENYWRITE | MMIO_EXCLUSIVE | MMIO_ALLOCBUF);
  51. cchBuffer /= 2;
  52. } while ((mmioInfo.wErrorRet == MMIOERR_OUTOFMEMORY) && (mmioInfo.cchBuffer > MMIO_DEFAULTBUFFER));
  53. if (pSrcFile->hmmioSrc)
  54. {
  55. // Locate a 'WAVE' form type in a 'RIFF' thing...
  56. pSrcFile->ckSrcRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  57. if (mmioDescend(pSrcFile->hmmioSrc, (LPMMCKINFO)&(pSrcFile->ckSrcRIFF), NULL, MMIO_FINDRIFF))
  58. goto MyMMIOErrorExit3;
  59. // We found a WAVE chunk--now go through and get all subchunks that we know how to deal with
  60. while (mmioDescend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrc), &(pSrcFile->ckSrcRIFF), 0) == 0)
  61. {
  62. // Quickly check for corrupt RIFF file--don't ascend past end!
  63. if ((pSrcFile->ckSrc.dwDataOffset + pSrcFile->ckSrc.cksize) > (pSrcFile->ckSrcRIFF.dwDataOffset + pSrcFile->ckSrcRIFF.cksize))
  64. goto MyMMIOErrorExit1;
  65. // Make sure the wave format structure of this file is compatible with the microphone
  66. if (pSrcFile->ckSrc.ckid == mmioFOURCC('f', 'm', 't', ' '))
  67. {
  68. if ((dw = pSrcFile->ckSrc.cksize) < sizeof(WAVEFORMATEX))
  69. dw = sizeof(WAVEFORMATEX);
  70. if (!(pwfFile = (WAVEFORMATEX *)GlobalAllocPtr(GHND, dw)))
  71. goto MyMMIOErrorExit1;
  72. dw = pSrcFile->ckSrc.cksize;
  73. if (mmioRead(pSrcFile->hmmioSrc, (HPSTR)pwfFile, dw) != (LONG)dw)
  74. goto MyMMIOErrorExit0;
  75. if (dw == sizeof(WAVEFORMATEX))
  76. pwfFile->cbSize = 0;
  77. if ((pwfFile->wFormatTag != pwf->wFormatTag) || (pwfFile->nChannels != pwf->nChannels)
  78. || (pwfFile->nSamplesPerSec != pwf->nSamplesPerSec) || (pwfFile->nAvgBytesPerSec != pwf->nAvgBytesPerSec)
  79. || (pwfFile->nBlockAlign != pwf->nBlockAlign) || (pwfFile->wBitsPerSample != pwf->wBitsPerSample) || (pwfFile->cbSize != pwf->cbSize))
  80. goto MyMMIOErrorExit0;
  81. pwfFile = (WAVEFORMATEX *)(UINT_PTR)GlobalFreePtr(pwfFile);
  82. }
  83. // Step up to prepare for next chunk..
  84. mmioAscend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrc), 0);
  85. }
  86. // Go back to beginning of data portion of WAVE chunk
  87. if (-1L == mmioSeek(pSrcFile->hmmioSrc, pSrcFile->ckSrcRIFF.dwDataOffset + sizeof(FOURCC), SEEK_SET))
  88. goto MyMMIOErrorExit2;
  89. pSrcFile->ckSrc.ckid = mmioFOURCC('d', 'a', 't', 'a');
  90. if (mmioDescend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrc), &(pSrcFile->ckSrcRIFF), MMIO_FINDCHUNK))
  91. goto MyMMIOErrorExit2;
  92. pSrcFile->dwMaxDataLength = pSrcFile->ckSrc.cksize;
  93. pSrcFile->dwDataLength = 0;
  94. pSrcFile->wfx = *pwf;
  95. // At this point, the src file is sitting at the very
  96. // beginning of its data chunks--so we can read from the src file...
  97. goto MyLastExit;
  98. MyMMIOErrorExit0:
  99. GlobalFreePtr(pwfFile);
  100. MyMMIOErrorExit1:
  101. mmioAscend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrc), 0);
  102. MyMMIOErrorExit2:
  103. mmioAscend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrcRIFF), 0);
  104. MyMMIOErrorExit3:
  105. mmioClose(pSrcFile->hmmioSrc, 0);
  106. pSrcFile->hmmioSrc = NULL;
  107. }
  108. }
  109. MyLastExit:
  110. return hr;
  111. }
  112. /*************************************************************************
  113. Function: AudioFile::CloseSourceFile(void)
  114. Purpose : Close wav file used to read audio data from.
  115. Returns : HRESULT.
  116. Params : None
  117. Comments:
  118. History : Date Reason
  119. 06/02/96 Created - PhilF
  120. *************************************************************************/
  121. HRESULT AudioFile::CloseSourceFile (MMIOSRC *pSrcFile)
  122. {
  123. HRESULT hr = DPR_SUCCESS;
  124. FX_ENTRY ("SendAudioStream::CloseSrcFile")
  125. if (pSrcFile->fPlayFromFile && pSrcFile->hmmioSrc)
  126. {
  127. mmioAscend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrc), 0);
  128. mmioAscend(pSrcFile->hmmioSrc, &(pSrcFile->ckSrcRIFF), 0);
  129. mmioClose(pSrcFile->hmmioSrc, 0);
  130. pSrcFile->hmmioSrc = NULL;
  131. }
  132. return hr;
  133. }
  134. HRESULT AudioFile::ReadSourceFile(MMIOSRC *pmmioSrc, BYTE *pData, DWORD dwBytesToRead)
  135. {
  136. long lNumBytesRead;
  137. bool bCloseFile = false;
  138. FX_ENTRY ("AdPckt::ReadFromFile")
  139. if (pmmioSrc->hmmioSrc == NULL)
  140. return S_FALSE;
  141. if (dwBytesToRead)
  142. {
  143. MyRead:
  144. if ((pmmioSrc->dwDataLength + dwBytesToRead) <= pmmioSrc->dwMaxDataLength)
  145. {
  146. lNumBytesRead = mmioRead(pmmioSrc->hmmioSrc, (char*)pData, dwBytesToRead);
  147. pmmioSrc->dwDataLength += lNumBytesRead;
  148. }
  149. else
  150. {
  151. lNumBytesRead = mmioRead(pmmioSrc->hmmioSrc, (char*)pData, pmmioSrc->dwMaxDataLength - pmmioSrc->dwDataLength);
  152. pmmioSrc->dwDataLength += lNumBytesRead;
  153. // silence out the remainder of the block
  154. if (pmmioSrc->wfx.wBitsPerSample != 8)
  155. {
  156. ZeroMemory(pData, dwBytesToRead - lNumBytesRead);
  157. }
  158. else
  159. {
  160. FillMemory(pData, dwBytesToRead - lNumBytesRead, 0x80);
  161. }
  162. pmmioSrc->dwDataLength = 0;
  163. lNumBytesRead = 0;
  164. }
  165. if (!lNumBytesRead)
  166. {
  167. if (pmmioSrc->fLoop && !pmmioSrc->fDisconnectAfterPlayback)
  168. {
  169. // Reset file pointer to beginning of data
  170. mmioAscend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrc), 0);
  171. if (-1L == mmioSeek(pmmioSrc->hmmioSrc, pmmioSrc->ckSrcRIFF.dwDataOffset + sizeof(FOURCC), SEEK_SET))
  172. {
  173. DEBUGMSG (1, ("MediaControl::OpenSrcFile: Couldn't seek in file, mmr=%ld\r\n", (ULONG) 0L));
  174. bCloseFile = true;
  175. }
  176. else
  177. {
  178. pmmioSrc->ckSrc.ckid = mmioFOURCC('d', 'a', 't', 'a');
  179. if (mmioDescend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrc), &(pmmioSrc->ckSrcRIFF), MMIO_FINDCHUNK))
  180. {
  181. DEBUGMSG (1, ("MediaControl::OpenSrcFile: Couldn't locate 'data' chunk, mmr=%ld\r\n", (ULONG) 0L));
  182. bCloseFile = true;
  183. }
  184. else
  185. {
  186. // At this point, the src file is sitting at the very
  187. // beginning of its data chunks--so we can read from the src file...
  188. goto MyRead;
  189. }
  190. }
  191. }
  192. else
  193. {
  194. bCloseFile = true;
  195. }
  196. if (bCloseFile)
  197. {
  198. mmioAscend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrcRIFF), 0);
  199. mmioClose(pmmioSrc->hmmioSrc, 0);
  200. pmmioSrc->hmmioSrc = NULL;
  201. return S_FALSE;
  202. }
  203. }
  204. return S_OK;
  205. }
  206. return S_FALSE;
  207. }
  208. /*************************************************************************
  209. Function: RecvAudioStream::OpenDestFile(void)
  210. Purpose : Opens wav file to record audio data into.
  211. Returns : HRESULT.
  212. Params : None
  213. Comments: * Registry keys:
  214. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\RecordToFile\fRecordToFile
  215. If set to zero, data will not be recorded into wav file.
  216. If set to a non null value <= INT_MAX, data will be recorded into wav file.
  217. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\RecordToFile\fRecordToFile
  218. If set to zero, data will overwrite existing data if wav file already exists.
  219. If set to a non null value <= INT_MAX, data will be recorded into wav file after existing data.
  220. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\RecordToFile\szOutputFileName
  221. Name of the wav file to record audio data into.
  222. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\RecordToFile\lMaxTimeLength
  223. If set to zero, there is no limit to the size of the wav file.
  224. If set to a non null value <= INT_MAX, size of the file will be clamped to lMaxTimeLength.
  225. \\HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Audio\RecordToFile\cchIOBuffer
  226. If set to zero, size of the MM IO buffer is set to its default value (8Kbytes).
  227. If set to one, size of the MM IO buffer is set to match maximum size of the wav file.
  228. If set a non null value between 2 and INT_MAX, size of the MM IO buffer is set to cchIOBuffer bytes.
  229. History : Date Reason
  230. 06/02/96 Created - PhilF
  231. *************************************************************************/
  232. HRESULT AudioFile::OpenDestFile (MMIODEST *pDestFile, WAVEFORMATEX *pwf)
  233. {
  234. HRESULT hr = DPR_SUCCESS;
  235. MMIOINFO mmioInfo;
  236. DWORD dw;
  237. long cchBuffer;
  238. long lMaxTimeLength;
  239. BOOL fAppend;
  240. MMRESULT mmr;
  241. FX_ENTRY ("RecvAudioStream::OpenDestFile")
  242. RegEntry reIPhoneOutFile(szRegInternetPhone TEXT("\\") szRegInternetPhoneOutputFile,
  243. HKEY_LOCAL_MACHINE,
  244. FALSE,
  245. KEY_READ);
  246. // For now, get the file name from the registry
  247. if (pDestFile->fRecordToFile = reIPhoneOutFile.GetNumberIniStyle(TEXT("fRecordToFile"), FALSE))
  248. {
  249. lstrcpyn(pDestFile->szOutputFileName,
  250. reIPhoneOutFile.GetString(TEXT("szOutputFileName")),
  251. CCHMAX(pDestFile->szOutputFileName));
  252. cchBuffer = reIPhoneOutFile.GetNumberIniStyle(TEXT("cchIOBuffer"), 0L);
  253. lMaxTimeLength = reIPhoneOutFile.GetNumberIniStyle(TEXT("lMaxTimeLength"), 0L);
  254. #if 0
  255. fAppend = reIPhoneOutFile.GetNumberIniStyle(TEXT("fAppend"), FALSE);
  256. #else
  257. fAppend = FALSE;
  258. #endif
  259. // Try to open the file for writing using buffered I/O
  260. // If the size of the buffer is too large, try again
  261. // with a buffer half that size.
  262. // m_RecvFilter->GetProp(FM_PROP_DST_MEDIA_FORMAT, (PDWORD)&pwf);
  263. if (!pwf)
  264. goto MyLastExit;
  265. pDestFile->dwMaxDataLength = lMaxTimeLength == 0L ? (DWORD)INT_MAX : (DWORD)(lMaxTimeLength * pwf->nSamplesPerSec * pwf->nBlockAlign / 1000L);
  266. if ((cchBuffer == 0L) || (lMaxTimeLength == 0L))
  267. cchBuffer = MMIO_DEFAULTBUFFER;
  268. else
  269. if (cchBuffer == 1L)
  270. cchBuffer = (long)pDestFile->dwMaxDataLength;
  271. ZeroMemory(&mmioInfo, sizeof(MMIOINFO));
  272. if (!mmioOpen((LPSTR)&(pDestFile->szOutputFileName[0]), NULL, MMIO_EXIST))
  273. fAppend = FALSE;
  274. do
  275. {
  276. mmioInfo.cchBuffer = cchBuffer;
  277. // pDestFile->hmmioDst = mmioOpen((LPSTR)&(pDestFile->szOutputFileName[0]), (LPMMIOINFO)&mmioInfo, MMIO_EXCLUSIVE | MMIO_ALLOCBUF | (fAppend ? MMIO_READWRITE : MMIO_WRITE | MMIO_CREATE));
  278. pDestFile->hmmioDst = mmioOpen((LPSTR)&(pDestFile->szOutputFileName[0]), (LPMMIOINFO)&mmioInfo, MMIO_EXCLUSIVE | MMIO_ALLOCBUF | (fAppend ? MMIO_WRITE : MMIO_WRITE | MMIO_CREATE));
  279. cchBuffer /= 2;
  280. } while ((mmioInfo.wErrorRet == MMIOERR_OUTOFMEMORY) && (mmioInfo.cchBuffer > MMIO_DEFAULTBUFFER));
  281. if (pDestFile->hmmioDst)
  282. {
  283. if (!fAppend)
  284. {
  285. // Create the RIFF chunk of form type 'WAVE'
  286. pDestFile->ckDstRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  287. pDestFile->ckDstRIFF.cksize = 0L;
  288. if (mmioCreateChunk(pDestFile->hmmioDst, &(pDestFile->ckDstRIFF), MMIO_CREATERIFF))
  289. goto MyMMIOErrorExit3;
  290. // Now create the destination fmt, fact, and data chunks _in that order_
  291. pDestFile->ckDst.ckid = mmioFOURCC('f', 'm', 't', ' ');
  292. pDestFile->ckDst.cksize = dw = SIZEOF_WAVEFORMATEX(pwf);
  293. if (mmioCreateChunk(pDestFile->hmmioDst, &(pDestFile->ckDst), 0))
  294. goto MyMMIOErrorExit2;
  295. if (mmioWrite(pDestFile->hmmioDst, (HPSTR)pwf, dw) != (LONG)dw)
  296. goto MyMMIOErrorExit1;
  297. if (mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0))
  298. goto MyMMIOErrorExit1;
  299. // Create the 'fact' chunk.
  300. // Since we are not writing any data to this file (yet), we set the
  301. // samples contained in the file to 0.
  302. pDestFile->ckDst.ckid = mmioFOURCC('f', 'a', 'c', 't');
  303. pDestFile->ckDst.cksize = 0L;
  304. if (mmioCreateChunk(pDestFile->hmmioDst, &(pDestFile->ckDst), 0))
  305. goto MyMMIOErrorExit2;
  306. pDestFile->dwDataLength = 0; // This will be updated when closing the file.
  307. if (mmioWrite(pDestFile->hmmioDst, (HPSTR)&(pDestFile->dwDataLength), sizeof(long)) != sizeof(long))
  308. goto MyMMIOErrorExit1;
  309. if (mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0))
  310. goto MyMMIOErrorExit1;
  311. // Create the data chunk and stay descended
  312. pDestFile->ckDst.ckid = mmioFOURCC('d', 'a', 't', 'a');
  313. pDestFile->ckDst.cksize = 0L;
  314. if (mmioCreateChunk(pDestFile->hmmioDst, &(pDestFile->ckDst), 0))
  315. goto MyMMIOErrorExit2;
  316. // At this point, the dst file is sitting at the very
  317. // beginning of its data chunks--so we can write to the dst file...
  318. goto MyLastExit;
  319. MyMMIOErrorExit1:
  320. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0);
  321. MyMMIOErrorExit2:
  322. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDstRIFF), 0);
  323. MyMMIOErrorExit3:
  324. mmioClose(pDestFile->hmmioDst, 0);
  325. mmioOpen((LPSTR)&(pDestFile->szOutputFileName[0]), (LPMMIOINFO)&mmioInfo, MMIO_DELETE);
  326. pDestFile->hmmioDst = NULL;
  327. }
  328. else
  329. {
  330. // File already exists, only need to position pointer at the end of existing data.
  331. // Locate a 'WAVE' form type in a 'RIFF' thing...
  332. pDestFile->ckDstRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  333. if (mmr = mmioDescend(pDestFile->hmmioDst, (LPMMCKINFO)&(pDestFile->ckDstRIFF), NULL, MMIO_FINDRIFF))
  334. goto MyOtherMMIOErrorExit3;
  335. // We found a WAVE chunk--now go through and get all subchunks that we know how to deal with
  336. while (mmr = mmioDescend(pDestFile->hmmioDst, &(pDestFile->ckDst), &(pDestFile->ckDstRIFF), 0) == 0)
  337. {
  338. // Quickly check for corrupt RIFF file--don't ascend past end!
  339. if ((pDestFile->ckDst.dwDataOffset + pDestFile->ckDst.cksize) > (pDestFile->ckDstRIFF.dwDataOffset + pDestFile->ckDstRIFF.cksize))
  340. goto MyOtherMMIOErrorExit1;
  341. // Step up to prepare for next chunk..
  342. mmr = mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0);
  343. }
  344. // Go back to beginning of data portion of WAVE chunk
  345. if (-1L == mmioSeek(pDestFile->hmmioDst, pDestFile->ckDstRIFF.dwDataOffset + sizeof(FOURCC), SEEK_SET))
  346. goto MyOtherMMIOErrorExit2;
  347. pDestFile->ckDst.ckid = mmioFOURCC('d', 'a', 't', 'a');
  348. if (mmr = mmioDescend(pDestFile->hmmioDst, &(pDestFile->ckDst), &(pDestFile->ckDstRIFF), MMIO_FINDCHUNK))
  349. goto MyOtherMMIOErrorExit2;
  350. pDestFile->dwDataLength = pDestFile->ckDst.cksize;
  351. if (-1L == (mmr = mmioSeek(pDestFile->hmmioDst, 0, SEEK_END)))
  352. goto MyOtherMMIOErrorExit2;
  353. // At this point, the dst file is sitting at the very
  354. // end of its data chunks--so we can write to the dst file...
  355. goto MyLastExit;
  356. MyOtherMMIOErrorExit1:
  357. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0);
  358. MyOtherMMIOErrorExit2:
  359. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDstRIFF), 0);
  360. MyOtherMMIOErrorExit3:
  361. mmioClose(pDestFile->hmmioDst, 0);
  362. pDestFile->hmmioDst = NULL;
  363. }
  364. }
  365. }
  366. MyLastExit:
  367. return hr;
  368. }
  369. /*************************************************************************
  370. Function: RecvAudioStream::CloseDestFile(void)
  371. Purpose : Close wav file used to record audio data into.
  372. Returns : HRESULT.
  373. Params : None
  374. Comments:
  375. History : Date Reason
  376. 06/02/96 Created - PhilF
  377. *************************************************************************/
  378. HRESULT AudioFile::CloseDestFile (MMIODEST *pDestFile)
  379. {
  380. HRESULT hr = DPR_SUCCESS;
  381. FX_ENTRY ("RecvAudioStream::CloseDestFile")
  382. if (pDestFile->fRecordToFile && pDestFile->hmmioDst)
  383. {
  384. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDst), 0);
  385. mmioAscend(pDestFile->hmmioDst, &(pDestFile->ckDstRIFF), 0);
  386. mmioClose(pDestFile->hmmioDst, 0);
  387. pDestFile->hmmioDst = NULL;
  388. }
  389. return hr;
  390. }
  391. HRESULT AudioFile::WriteDestFile(MMIODEST *pmmioDest, BYTE *pData, DWORD dwBytesToWrite)
  392. {
  393. MMRESULT mmr=MMSYSERR_NOERROR;
  394. FX_ENTRY ("AudioFile::WriteToFile")
  395. if ((pmmioDest->hmmioDst == NULL) || (dwBytesToWrite == 0))
  396. {
  397. return S_FALSE;
  398. }
  399. if (mmioWrite(pmmioDest->hmmioDst, (char *) pData, dwBytesToWrite) != (long)dwBytesToWrite)
  400. {
  401. mmr = MMSYSERR_ERROR;
  402. }
  403. else
  404. {
  405. pmmioDest->dwDataLength += dwBytesToWrite;
  406. }
  407. if ((pmmioDest->dwDataLength >= pmmioDest->dwMaxDataLength) ||
  408. (mmr != MMSYSERR_NOERROR))
  409. {
  410. mmr = mmioAscend(pmmioDest->hmmioDst, &(pmmioDest->ckDst), 0);
  411. mmr = mmioAscend(pmmioDest->hmmioDst, &(pmmioDest->ckDstRIFF), 0);
  412. mmr = mmioClose(pmmioDest->hmmioDst, 0);
  413. pmmioDest->hmmioDst = NULL;
  414. }
  415. return S_OK;
  416. }