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.

840 lines
25 KiB

  1. /*
  2. ** Copyright (c) 1985-1998 Microsoft Corporation
  3. **
  4. ** Title: mciwave.h - Multimedia Systems Media Control Interface
  5. ** streaming digital audio driver internal header file.
  6. */
  7. /*
  8. ** Change log:
  9. **
  10. ** DATE REV DESCRIPTION
  11. ** ----------- ----- ------------------------------------------
  12. ** 18-APR-1990 ROBWI Original
  13. ** 10-Jan-1992 MikeTri Ported to NT
  14. ** Aug 1994 Lauriegr Tried to add some explanation
  15. */
  16. /********************* The OVERALL SCHEME OF THINGS ************************\
  17. There are normally one or two files on the go. One is the original wave file,
  18. the other is a temporary file. The data in these files is described by a
  19. WAVEDESC which contains a pointer to an array of WAVEDATANODEs.
  20. Each WAVEDATANODE identifies some part of one of the files.
  21. The high order bit of the length field identifies which file (totally naff,
  22. if you ask me, but I didn't invent it). Concatenate all the sections that
  23. the WAVEDATANODEs identify and that's the wave data.
  24. The WAVEDATANODEs actually form a linked list (linked by array indices not
  25. pointers) and it is the concatenation of that list which defines the file.
  26. There may also be some WAVEDATANODEs that define free space.
  27. I'm confused about what exactly the dDataStart in the NODEs means. Is it the
  28. position in the logical file or in one or other of the physical files? Either
  29. way it probably gets messed up if you try deleting anything (KNOWN BUG).
  30. LaurieGr
  31. \***************************************************************************/
  32. #ifndef MCIWAVE_H
  33. #define MCIWAVE_H
  34. #include <stdio.h>
  35. #include <mmsystem.h>
  36. #define WAIT_FOREVER ((DWORD)(-1))
  37. #if DBG
  38. #define PUBLIC extern /* Public label. SO DEBUGGER CAN */
  39. #define PRIVATE extern /* Private label. SEE THE SYMBOLS */
  40. #else
  41. #define PUBLIC extern /* Public label. */
  42. #define PRIVATE extern /* Private label. */
  43. #endif
  44. #define REALLYPRIVATE static
  45. #define EXPORT /* Export function. */
  46. #ifndef RC_INVOKED /* These are defined to RC */
  47. #define STATICDT
  48. #define STATICFN
  49. #define STATIC
  50. #endif /* RC_INVOKED */
  51. /*
  52. ** This constant defines the maximum length of strings containing
  53. ** file paths. This number is the same as the string in OFSTRUCT.
  54. */
  55. #define _MAX_PATH MAX_PATH
  56. /*
  57. ** These two constants define extended commands that are use within the
  58. ** wave handler. The first can be sent to the MCI entry point, and the
  59. ** second is used entirely internally.
  60. */
  61. #define MCI_MCIWAVE_PLAY_HOLD 0x01000000L
  62. #define MCI_MCIWAVE_CUE 0x02000000L
  63. /*
  64. ** The first two constants represent the maximum and minimum number of
  65. ** seconds of buffering that can be specified either on the SYSTEM.INI
  66. ** device driver entry, or in the MCI_OPEN command.
  67. ** The third constant defines the default number of seconds to use when
  68. ** calculating the number of seconds of buffering to allocate.
  69. */
  70. #define MaxAudioSeconds 9
  71. #define MinAudioSeconds 2
  72. #define AudioSecondsDefault 4
  73. /*
  74. ** This constant is used for recording when no record stopping point
  75. ** is specified.
  76. */
  77. #define INFINITEFILESIZE 0X7FFFFFFFL
  78. /*
  79. ** These constants represent the various RIFF components of the file.
  80. */
  81. #define mmioWAVE mmioFOURCC('W','A','V','E')
  82. #define mmioFMT mmioFOURCC('f','m','t',' ')
  83. #define mmioDATA mmioFOURCC('d','a','t','a')
  84. /*
  85. ** The following represent identifiers for string resources.
  86. */
  87. #define IDS_PRODUCTNAME 0
  88. #define IDS_MAPPER 1
  89. #define IDS_COMMANDS 2
  90. /*
  91. ** The following constant is used to specify the sample size when
  92. ** determing the input level during a Cued record. This number must
  93. ** be divisible by 4.
  94. */
  95. #define NUM_LEVEL_SAMPLES 64L
  96. /*
  97. ** The following constants represent specific task modes and task
  98. ** commands.
  99. */
  100. #define MODE_PLAYING 0x0001
  101. #define MODE_INSERT 0x0002
  102. #define MODE_OVERWRITE 0x0004
  103. #define MODE_PAUSED 0x0008
  104. #define MODE_CUED 0x0010
  105. #define MODE_HOLDING 0x0020
  106. #define MODE_CLEANUP 0x0040
  107. #define MODE_WAIT 0x0080
  108. #define COMMAND_NEW 0x0100
  109. #define COMMAND_PLAY 0x0200
  110. #define COMMAND_INSERT 0x0400
  111. #define COMMAND_OVERWRITE 0x0800
  112. #define COMMAND_STOP 0x1000
  113. #define COMMAND_CUE 0x2000
  114. #define COMMAND_HOLD 0x4000
  115. /*
  116. ** The following macros allow modes and commands to be added, removed,
  117. ** queried, set, and get.
  118. */
  119. #define ADDMODE(pwd, m) ((pwd)->wMode |= (m))
  120. #define REMOVEMODE(pwd, m) ((pwd)->wMode &= ~(m))
  121. #define ISMODE(pwd, m) ((pwd)->wMode & (m))
  122. #define SETMODE(pwd, m) ((pwd)->wMode = (m))
  123. #define GETMODE(pwd) ((pwd)->wMode)
  124. /*
  125. ** The following macros allow testing and setting of the current task
  126. ** state.
  127. */
  128. #define ISTASKSTATE(pwd, s) ((pwd)->wTaskState == (s))
  129. #define SETTASKSTATE(pwd, s) ((pwd)->wTaskState = (s))
  130. #define TASKSTATE(pwd) ((pwd)->wTaskState)
  131. /*
  132. ** Define message for state changes for device tasks
  133. */
  134. #define WTM_STATECHANGE (WM_USER + 1)
  135. /*
  136. @doc INTERNAL MCIWAVE
  137. @types DIRECTION |
  138. The Direction enumeration is used internally in the MCI wave handler
  139. to indicate the current direction of data flow. This is either input
  140. (record), or output (play).
  141. @flag input |
  142. Indicates the direction is record.
  143. @flag output |
  144. Indicates the direction is playback.
  145. @tagname tagDirection
  146. */
  147. typedef enum tagDirection {
  148. input,
  149. output
  150. } DIRECTION;
  151. /*
  152. ** The following constants represent specific task states.
  153. */
  154. #define TASKNONE 0
  155. #define TASKINIT 1
  156. #define TASKIDLE 2
  157. #define TASKBUSY 3
  158. #define TASKCLOSE 4
  159. #define TASKSAVE 5
  160. #define TASKDELETE 6
  161. #define TASKCUT 7
  162. /*
  163. ** The following constants and macros are used in dealing with data nodes,
  164. ** which are pointers to blocks of data. The first constant is used
  165. ** within these macros as a mask for block pointers which refer to data
  166. ** located in the temporary file, and not in the original read-only file.
  167. */
  168. #define TEMPDATAMASK (0x80000000)
  169. #define ENDOFNODES (-1)
  170. #define ISTEMPDATA(lpwdn) (((lpwdn)->dDataStart & TEMPDATAMASK) != 0)
  171. #define MASKDATASTART(d) ((d) | TEMPDATAMASK)
  172. #define UNMASKDATASTART(lpwdn) ((lpwdn)->dDataStart & ~TEMPDATAMASK)
  173. #define LPWDN(pwd, d) ((pwd)->lpWaveDataNode + (d))
  174. #define RELEASEBLOCKNODE(lpwdn) ((lpwdn)->dDataLength = (DWORD)-1)
  175. #define ISFREEBLOCKNODE(lpwdn) ((lpwdn)->dDataLength == (DWORD)-1)
  176. /*
  177. ** The following constant is used to determine the allocation increments
  178. ** for data pointers
  179. */
  180. #define DATANODEALLOCSIZE 32
  181. /*
  182. ** The following macro is used to round a data offset to the next nearest
  183. ** buffer size increment.
  184. */
  185. #define ROUNDDATA(pwd, d) ((((DWORD)(d) + (pwd)->dAudioBufferLen - 1) / (pwd)->dAudioBufferLen) * (pwd)->dAudioBufferLen)
  186. #define BLOCKALIGN(pwd, d) ((((DWORD)(d) + (pwd)->pwavefmt->nBlockAlign - 1) / (pwd)->pwavefmt->nBlockAlign) * (pwd)->pwavefmt->nBlockAlign)
  187. /************************************************************************/
  188. /*
  189. @doc INTERNAL MCIWAVE
  190. @types WAVEDATANODE |
  191. The Wave Data Node structure is used internally in the MCI wave
  192. handler to store information about a block of wave data, located either
  193. in the original file, or in the temporary data file. These structures
  194. are used to form a linked list of wave data nodes that describe the
  195. data in the entire file as it currently exists.
  196. The headers themselves are allocated as an expandable array of global
  197. memory, using <e>WAVEDATANODE.dDataLength<d> as an in-use flag when
  198. searching the list for free entries to use. Note that a free entry
  199. can also have free temporary data attached to it, as in the case of
  200. performing a delete in which all the data for a specific node is
  201. removed.
  202. @field DWORD | dDataStart |
  203. Indicates the absolute position at which the data for this node begins.
  204. This element is also used in determining if the data pointed to by this
  205. node is original data, or newly created temporary data. This is done
  206. by masking the length with <f>TEMPDATAMASK<d>. The length can be
  207. accessed by using <f>UNMASKDATASTART<d>.
  208. @field DWORD | dDataLength |
  209. Indicates the length of active data pointed to by the node. This
  210. could be zero if say, a write failed. This contains -1 if the node
  211. is not part of the linked list of active nodes.
  212. @field DWORD | dTotalLength |
  213. Indicates the actual total length of data available to this node. For
  214. original data, this will always be the same as the
  215. <e>WAVEDATANODE.dDataLength<d> element, but for temporary data, this
  216. may be longer, as it is a block aligned number, the block lengths being
  217. based on the size of wave data buffers. If the node is not in use, it
  218. still may have data associated with it. If there is no data associated
  219. with a free node, the total length is set to zero.
  220. @field DWORD | dNextWaveDataNode |
  221. This element is used for active nodes, and contains an index into the
  222. array of nodes indicating the location of the next active node, or
  223. <f>ENDOFNODES<d> to indicate the end of the list of active nodes.
  224. @othertype WAVEDATANODE NEAR * | LPWAVEDATANODE |
  225. A far pointer to the structure.
  226. @tagname tagWaveDataNode
  227. */
  228. typedef struct tagWaveDataNode {
  229. DWORD dDataStart;
  230. DWORD dDataLength;
  231. DWORD dTotalLength;
  232. DWORD dNextWaveDataNode;
  233. } WAVEDATANODE,
  234. FAR * LPWAVEDATANODE;
  235. /*
  236. @doc INTERNAL MCIWAVE
  237. @types WAVEDESC |
  238. The Wave Description structure is used internally in the MCI wave
  239. handler to store details for each device, along with any state information.
  240. @field MCIDEVICEID | wDeviceID |
  241. MCI device identifier passed to the driver during driver open.
  242. @field UINT | wMode |
  243. Contains the current mode of the background task, if there is a task.
  244. @flag MODE_PLAYING |
  245. This mode is set when the task is actually doing playback. It is reset
  246. before Cleanup mode is entered.
  247. @flag MODE_INSERT |
  248. This mode is set when the task is actually doing insert recording. It
  249. is reset before Cleanup mode is entered.
  250. @flag MODE_OVERWRITE |
  251. This mode is set when the task is actually doing overwrite recording.
  252. It is reset before Cleanup mode is entered.
  253. @flag MODE_PAUSED |
  254. This mode is set if playback or recording has been paused by an
  255. MCI_PAUSE command.
  256. @flag MODE_CUED |
  257. This mode is entered when playback or recording has actually been cued.
  258. @flag MODE_HOLDING |
  259. This mode is entered when playback is about to block itself and hold
  260. after doing playback.
  261. @flag MODE_CLEANUP |
  262. This mode is entered after playback or recording has finished, but
  263. before the task has entered idle state, and new commands are being
  264. ignored.
  265. @flag MODE_WAIT |
  266. This mode flag is used by both the calling task and the background
  267. task. If the calling task received a Record or Play command with the
  268. Wait flag, then this mode is set, so that if an error occurs during
  269. playback or recording, the background task does not perform
  270. notification, but just clears the notification callback handle. Just
  271. before it performs notification, the background task clears this
  272. flag so that the calling task will know that it should not return an
  273. error condition. If the calling task is broken out of the wait loop,
  274. it checks this flag to determine if it should report an error
  275. condition.
  276. @flag COMMAND_NEW |
  277. This command specifies that a new command has been set.
  278. @flag COMMAND_PLAY |
  279. This command indicates that playback should be performed on the preset
  280. parameters.
  281. @flag COMMAND_INSERT |
  282. This command indicates that insert recording should be performed on
  283. the preset parameters.
  284. @flag COMMAND_OVERWRITE |
  285. This command indicates that overwrite recording should be performed on
  286. the preset parameters.
  287. @flag COMMAND_STOP |
  288. This command indicates that playback or recording should stop.
  289. @flag COMMAND_CUE |
  290. This command indicates that playback should initially pause itself
  291. before writing then enter Cue mode when all buffers have been written.
  292. For recording, it should enter a level checking loop and wait for
  293. further commands.
  294. @flag COMMAND_HOLD |
  295. This command specifies that playback should enter a hold state after
  296. completing playback.
  297. @field DWORD | dTimeFormat |
  298. Indicates the current format of position values used in messages.
  299. @flag MCI_FORMAT_MILLISECONDS |
  300. Milliseconds.
  301. @flag MCI_FORMAT_SAMPLES |
  302. Samples.
  303. @flag MCI_FORMAT_BYTES |
  304. Bytes.
  305. @field UINT | wSeconds |
  306. Contains the desired amount of buffering in terms of seconds. This
  307. is then converted to actual buffers, and limited by the predefined
  308. min and max values.
  309. @field HWND | hwndCallback |
  310. If a message has specified notification, this contains the window
  311. handle to where notification is to be sent. The handle is stored
  312. here for delayed notification, and can be checked when the function
  313. has finished or was interrupted.
  314. @field HTASK | hTask |
  315. If the MCI wave device instance was opened with an element attached,
  316. this element contains the handle to the background task used for
  317. playback and recording.
  318. @field <t>DIRECTION<d> | Direction |
  319. Indicates the current direction of data flow.
  320. @flag input |
  321. Indicates the direction is inwards, i.e. recording.
  322. @flag output |
  323. Indicates the direction is outwards, i.e. playback.
  324. @field UINT | wTaskState |
  325. MCIWAVE has a separate background task for every open instance of
  326. mciwave. The task handle and task state are stored in the
  327. per-instance data structure. The task can be in one of four states.
  328. @flag TASKNONE |
  329. This state is only set if the requested file cannot be opened during
  330. task initialization. It is used so that the task create loop is able
  331. to abort on an initialization failure.
  332. @flag TASKINIT |
  333. This is the initial task state set when the instance data structure is
  334. initialized in <f>mwOpenDevice<d> before the actual task is created by
  335. <f>mmTaskCreate<d>. After the task is created, <f>mwOpenDevice<d>
  336. waits until the task state changes to TASKIDLE before returning success
  337. so that the background task is definitely initialized after an open
  338. call.
  339. @flag TASKIDLE |
  340. The task sets the state to TASKIDLE and blocks whenever there is
  341. nothing to do. When the task wakes, the state is either TASKCLOSE if
  342. the instance is being closed or else TASKBUSY if the task is to begin
  343. recording or playback of the file.
  344. @flag TASKCLOSE |
  345. <f>mwCloseDevice<d> stops playback or recording which forces the task
  346. state to TASKIDLE and then sets the state to TASKCLOSE and wakes the
  347. task so that the task will destroy itself.
  348. @flag TASKBUSY |
  349. The task is in this state during playback and recording.
  350. @flag TASKCLOSE |
  351. The task is closing and about to terminate.
  352. @flag TASKSAVE |
  353. The task saving the current data to the specified file.
  354. @flag TASKDELETE |
  355. The task deleting the specified data.
  356. @flag TASKCUT |
  357. The task cutting the specified data (Not implemented).
  358. @field UINT | idOut |
  359. Wave device id of output device to use, or WAVE_MAPPER for any.
  360. @field UINT | idIn |
  361. Wave device id of input device to use, or WAVE_MAPPER for any.
  362. @field HWAVEOUT | hWaveOut |
  363. Output wave device handle when in use.
  364. @field HWAVEIN | hWaveIn |
  365. Input wave device handle when in use.
  366. @field <t>LPWAVEHDR<d> | rglpWaveHdr |
  367. Pointer to array of audio buffers for wave buffering.
  368. @field DWORD | dCur |
  369. Current position in file in bytes.
  370. @field DWORD | dFrom |
  371. Position in bytes at which playback or recording should begin.
  372. @field DWORD | dTo |
  373. Position in bytes at which playback or recording should terminate,
  374. or <f>INFINITEFILESIZE<d> if recording should continue until stopped.
  375. @field DWORD | dSize |
  376. Actual wave data size in bytes.
  377. @field char | aszFile |
  378. Contains the name of the element attached to the MCI wave device
  379. instance, if any. This might be a zero length string if the file is
  380. new and has not been named yet.
  381. @field char | aszTempFile |
  382. Contains the name of the temporary data file, if any.
  383. @field <t>HMMIO<d> | hmmio |
  384. MMIO identifier of the element attached to the MCI wave device
  385. instance, if any.
  386. @field HFILE | hfTempBuffers |
  387. Contains the temporary data DOS file handle, if any, else HFILE_ERROR.
  388. @field <t>LPMMIOPROC<d> | pIOProc |
  389. Contains a pointer to the alternate MMIO IO procedure, if any, else
  390. NULL.
  391. @field <t>LPWAVEDATANODE<d> | lpWaveDataNode |
  392. Points to the array of wave data nodes. This is allocated when the
  393. file opens, so it is always valid. The array is expanded as needed.
  394. @field DWORD | dRiffData |
  395. This contains an offset into the original file, if any, indicating
  396. the actual starting point of the wave data, which in a RIFF file will
  397. not be zero.
  398. @field DWORD | dWaveDataStartNode |
  399. This contains an index to the first active data pointer in the linked
  400. list of data pointer nodes.
  401. @field DWORD | dWaveDataCurrentNode |
  402. This contains an index to the current active data pointer in the
  403. linked list of data pointer nodes.
  404. @field DWORD | dVirtualWaveDataStart |
  405. This contains a virtual starting point representing logically where in
  406. the file the data for the current node begins.
  407. @field DWORD | dWaveDataNodes |
  408. This indicates the total number of data pointer nodes available.
  409. @field DWORD | dWaveTempDataLength |
  410. This contains the current length of the temporary data file, if any.
  411. @field DWORD | dLevel |
  412. Current input level if it is being scanned.
  413. @field UINT | wTaskError |
  414. Task error return.
  415. @field UINT | wAudioBuffers |
  416. Number of audio buffers actually allocated during playback or recording.
  417. @field DWORD | wAudioBufferLen |
  418. Length of each audio buffer.
  419. @field PSTR | szSaveFile |
  420. During a save command, this optionally contains the name of the file
  421. to save to, unless data is being saved to the original file.
  422. @field UINT | wFormatSize |
  423. This contains the size of the wave header, which is used when saving
  424. data to a new file.
  425. @field <t>WAVEFORMAT<d> | pwavefmt |
  426. Pointer to the wave format header.
  427. @field HANDLE | hTaskHandle |
  428. Handle to the thread that started this request
  429. @field CRITCAL_SECTION | CritSec |
  430. Serialisation object for threads accessing this <t>WAVEDESC<d> structure
  431. @othertype WAVEDESC NEAR * | PWAVEDESC |
  432. A near pointer to the structure.
  433. @tagname tagWaveDesc
  434. */
  435. #ifndef MMNOMMIO
  436. #ifndef MMNOWAVE
  437. typedef struct tagWaveDesc {
  438. MCIDEVICEID wDeviceID;
  439. UINT wMode;
  440. DWORD dTimeFormat;
  441. UINT wSeconds;
  442. HWND hwndCallback;
  443. DWORD hTask;
  444. //HANDLE hTask;
  445. DIRECTION Direction;
  446. UINT wTaskState;
  447. UINT idOut;
  448. UINT idIn;
  449. HWAVEOUT hWaveOut;
  450. HWAVEIN hWaveIn;
  451. DWORD dCur;
  452. DWORD dFrom;
  453. DWORD dTo;
  454. DWORD dSize;
  455. HMMIO hmmio;
  456. HANDLE hTempBuffers;
  457. LPMMIOPROC pIOProc;
  458. LPWAVEDATANODE lpWaveDataNode;
  459. DWORD dRiffData;
  460. DWORD dWaveDataStartNode;
  461. DWORD dWaveDataCurrentNode;
  462. DWORD dVirtualWaveDataStart;
  463. DWORD dWaveDataNodes;
  464. DWORD dWaveTempDataLength;
  465. DWORD dLevel;
  466. UINT wTaskError;
  467. UINT wAudioBuffers;
  468. DWORD dAudioBufferLen;
  469. LPWSTR szSaveFile;
  470. UINT wFormatSize;
  471. WAVEFORMAT NEAR * pwavefmt;
  472. HANDLE hTaskHandle; // Handle of the thread running this job
  473. LPWAVEHDR rglpWaveHdr[MaxAudioSeconds];
  474. WCHAR aszFile[_MAX_PATH];
  475. WCHAR aszTempFile[_MAX_PATH];
  476. } WAVEDESC;
  477. typedef WAVEDESC * PWAVEDESC;
  478. /************************************************************************/
  479. //PRIVATE DWORD PASCAL FAR time2bytes(
  480. // PWAVEDESC pwd,
  481. // DWORD dTime,
  482. // DWORD dFormat);
  483. //
  484. //PRIVATE DWORD PASCAL FAR bytes2time(
  485. // PWAVEDESC pwd,
  486. // DWORD dBytes,
  487. // DWORD dFormat);
  488. PUBLIC VOID PASCAL FAR mwDelayedNotify(
  489. PWAVEDESC pwd,
  490. UINT uStatus);
  491. PUBLIC LPWAVEHDR * PASCAL FAR NextWaveHdr(
  492. PWAVEDESC pwd,
  493. LPWAVEHDR * lplpWaveHdr);
  494. PUBLIC UINT PASCAL FAR PlayFile(
  495. register PWAVEDESC pwd);
  496. PUBLIC UINT PASCAL FAR RecordFile(
  497. register PWAVEDESC pwd);
  498. PUBLIC DWORD PASCAL FAR mwInfo(
  499. PWAVEDESC pwd,
  500. DWORD dFlags,
  501. LPMCI_INFO_PARMS lpInfo);
  502. PUBLIC DWORD PASCAL FAR mwGetDevCaps(
  503. PWAVEDESC pwd,
  504. DWORD dFlags,
  505. LPMCI_GETDEVCAPS_PARMS lpCaps);
  506. PUBLIC DWORD PASCAL FAR mwAllocMoreBlockNodes(
  507. PWAVEDESC pwd);
  508. PUBLIC DWORD PASCAL FAR mwFindAnyFreeDataNode(
  509. PWAVEDESC pwd,
  510. DWORD dMinDataLength);
  511. PUBLIC VOID PASCAL FAR mwDeleteData(
  512. PWAVEDESC pwd);
  513. PUBLIC VOID PASCAL FAR mwSaveData(
  514. PWAVEDESC pwd);
  515. PUBLIC VOID PASCAL FAR InitMMIOOpen(
  516. PWAVEDESC pwd,
  517. LPMMIOINFO lpmmioInfo);
  518. #endif // MMNOWAVE
  519. #endif // MMNOMMIO
  520. PUBLIC LRESULT PASCAL FAR mciDriverEntry(
  521. MCIDEVICEID wDeviceID,
  522. UINT uMessage,
  523. DWORD dFlags,
  524. LPMCI_GENERIC_PARMS lpParms);
  525. PUBLIC INT_PTR PASCAL FAR Config(
  526. HWND hWnd,
  527. LPDRVCONFIGINFO lpdci,
  528. HINSTANCE hInstance);
  529. PUBLIC UINT PASCAL FAR GetAudioSeconds(
  530. LPCWSTR pch);
  531. __inline BOOL MySeekFile(HANDLE hFile, LONG Position)
  532. {
  533. return 0xFFFFFFFF != SetFilePointer(hFile, Position, NULL, FILE_BEGIN);
  534. }
  535. __inline BOOL MyReadFile(HANDLE hFile, LPVOID pBuffer, ULONG cBytesToRead, PULONG pcBytesRead)
  536. {
  537. BOOL fReturn;
  538. ULONG cBytesRead;
  539. if (!pcBytesRead) pcBytesRead = &cBytesRead;
  540. fReturn = ReadFile(hFile, pBuffer, cBytesToRead, pcBytesRead, NULL);
  541. if (fReturn && (*pcBytesRead == cBytesToRead))
  542. {
  543. return TRUE;
  544. }
  545. *pcBytesRead = -1;
  546. return FALSE;
  547. }
  548. __inline BOOL MyWriteFile(HANDLE hFile, LPCVOID pBuffer, ULONG cBytesToWrite, PULONG pcBytesWritten)
  549. {
  550. BOOL fReturn;
  551. ULONG cBytesWritten;
  552. if (!pcBytesWritten) pcBytesWritten = &cBytesWritten;
  553. fReturn = WriteFile(hFile, pBuffer, cBytesToWrite, pcBytesWritten, NULL);
  554. if (fReturn && (*pcBytesWritten == cBytesToWrite))
  555. {
  556. return TRUE;
  557. }
  558. *pcBytesWritten = -1;
  559. return FALSE;
  560. }
  561. /************************************************************************/
  562. /*
  563. ** This defines a stack and code based pointer types.
  564. */
  565. //#define STACK _based(_segname("_STACK"))
  566. //#define SZCODE char _based(_segname("_CODE"))
  567. //typedef char STACK * SSZ;
  568. #define SZCODE WCHAR // Should be sufficient,
  569. typedef WCHAR *SSZ; // as segments no longer matter in Win32
  570. /************************************************************************/
  571. PUBLIC HINSTANCE hModuleInstance;
  572. PUBLIC UINT cWaveOutMax;
  573. PUBLIC UINT cWaveInMax;
  574. PUBLIC UINT wAudioSeconds;
  575. /***************************************************************************
  576. Synchronisation support
  577. ***************************************************************************/
  578. VOID InitCrit(VOID);
  579. VOID DeleteCrit(VOID);
  580. #if DBG
  581. extern VOID DbgEnterCrit(UINT ln, LPCSTR lpszFile);
  582. #define EnterCrit() DbgEnterCrit(__LINE__, __FILE__)
  583. #else
  584. VOID EnterCrit(VOID);
  585. #endif
  586. VOID LeaveCrit(VOID);
  587. VOID TaskWaitComplete(HANDLE h);
  588. UINT TaskBlock(VOID);
  589. BOOL TaskSignal(DWORD h, UINT Msg);
  590. #ifndef MMNOMMIO
  591. #ifndef MMNOWAVE
  592. #if DBG
  593. extern DWORD dwCritSecOwner;
  594. #define mmYield(pwd) mmDbgYield(pwd, __LINE__, __FILE__)
  595. extern VOID mmDbgYield(PWAVEDESC pwd, UINT ln, LPCSTR lpszFile);
  596. #define CheckIn() WinAssert((GetCurrentThreadId() == dwCritSecOwner))
  597. #define CheckOut() WinAssert((GetCurrentThreadId() != dwCritSecOwner))
  598. #else
  599. #define CheckIn()
  600. #define CheckOut()
  601. #define mmYield(pwd) \
  602. { \
  603. LeaveCrit(); \
  604. Sleep(10); \
  605. EnterCrit(); \
  606. }
  607. #endif
  608. #endif
  609. #endif
  610. /***************************************************************************
  611. DEBUGGING SUPPORT
  612. ***************************************************************************/
  613. #if DBG
  614. extern void mciwaveDbgOut(LPSTR lpszFormat, ...);
  615. extern void mciwaveInitDebugLevel(void);
  616. extern void dDbgAssert(LPSTR exp, LPSTR file, int line);
  617. #define WinAssert(exp) \
  618. ((exp) ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__))
  619. #define WinEval(exp) \
  620. ((__dwEval=(DWORD)(exp)), \
  621. __dwEval ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__), __dwEval)
  622. int mciwaveDebugLevel;
  623. #define dprintf( _x_ ) mciwaveDbgOut _x_
  624. #define dprintf1( _x_ ) if (mciwaveDebugLevel >= 1) mciwaveDbgOut _x_
  625. #define dprintf2( _x_ ) if (mciwaveDebugLevel >= 2) mciwaveDbgOut _x_
  626. #define dprintf3( _x_ ) if (mciwaveDebugLevel >= 3) mciwaveDbgOut _x_
  627. #define dprintf4( _x_ ) if (mciwaveDebugLevel >= 4) mciwaveDbgOut _x_
  628. #else // DBG
  629. #define mciwaveInitDebugLevel() 0
  630. #define WinAssert(exp) 0
  631. #define WinEval(exp) (exp)
  632. #define dprintf(x)
  633. #define dprintf1(x)
  634. #define dprintf2(x)
  635. #define dprintf3(x)
  636. #define dprintf4(x)
  637. #endif
  638. #endif // MCIWAVE_H