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.

435 lines
17 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. /* @Doc DMusic16
  3. *
  4. * @Module DMusic16.h - Internal definitions for DMusic16.DLL |
  5. */
  6. #ifndef __DMUSIC16__
  7. #define __DMUSIC16__
  8. #undef WINAPI
  9. #define WINAPI _loadds FAR PASCAL
  10. #ifdef WIN32
  11. #define BCODE
  12. #define BSTACK
  13. #else
  14. #define BCODE __based(__segname("_CODE"))
  15. #define BSTACK __based(__segname("_STACK"))
  16. #endif
  17. /* Make symbols show up in debug builds
  18. */
  19. #ifdef DEBUG
  20. #define STATIC
  21. #else
  22. #define STATIC static
  23. #endif
  24. /* MIDI defines
  25. */
  26. #define MIDI_CHANNELS 16
  27. #define SZCODE const char BCODE
  28. /* Quadword alignment for event lengths in DMEVENT's
  29. */
  30. #define QWORD_ALIGN(x) (((x) + 7) & ~7) /* Next highest */
  31. #define QWORD_TRUNC(x) ((x) & ~7) /* Next lowest */
  32. /* Multiplier to convert between reftime and milliseconds
  33. */
  34. #define REFTIME_TO_MS (10L*1000L)
  35. /* Number of events we want in the capture pool. Based on about a second's worth of high
  36. * concentration data
  37. */
  38. #define CAP_HIGHWATERMARK 1024
  39. /* How often user-mode timer ticks happen (milliseconds)
  40. */
  41. #define MS_USERMODE 1000
  42. /* Typedefs for everyone. Woohoo!
  43. */
  44. typedef struct QUADWORD QUADWORD;
  45. typedef struct QUADWORD NEAR *NPQUADWORD;
  46. typedef struct QUADWORD FAR *LPQUADWORD;
  47. typedef struct LINKNODE LINKNODE;
  48. typedef struct LINKNODE NEAR *NPLINKNODE;
  49. typedef struct LINKNODE FAR *LPLINKNODE;
  50. typedef struct DMEVENT DMEVENT;
  51. typedef struct DMEVENT NEAR *NPDMEVENT;
  52. typedef struct DMEVENT FAR *LPDMEVENT;
  53. typedef struct EVENT EVENT;
  54. typedef struct EVENT NEAR *NPEVENT;
  55. typedef struct EVENT FAR *LPEVENT;
  56. typedef struct EVENTQUEUE EVENTQUEUE;
  57. typedef struct EVENTQUEUE NEAR *NPEVENTQUEUE;
  58. typedef struct EVENTQUEUE FAR *LPEVENTQUEUE;
  59. typedef struct OPENHANDLEINSTANCE OPENHANDLEINSTANCE;
  60. typedef struct OPENHANDLEINSTANCE NEAR *NPOPENHANDLEINSTANCE;
  61. typedef struct OPENHANDLEINSTANCE FAR *LPOPENHANDLEINSTANCE;
  62. typedef struct OPENHANDLE OPENHANDLE;
  63. typedef struct OPENHANDLE NEAR *NPOPENHANDLE;
  64. typedef struct OPENHANDLE FAR *LPOPENHANDLE;
  65. typedef struct THRUCHANNEL THRUCHANNEL;
  66. typedef struct THRUCHANNEL NEAR *NPTHRUCHANNEL;
  67. typedef struct THRUCHANNEL FAR *LPTHRUCHANNEL;
  68. /* 64-bit integer used w/ assembly helpers
  69. */
  70. struct QUADWORD
  71. {
  72. DWORD dwLow;
  73. DWORD dwHigh;
  74. };
  75. /* @struct Holds things in doubly linked lists
  76. */
  77. struct LINKNODE {
  78. NPLINKNODE pPrev; /* @field NPLINKNODE | pPrev |
  79. Pointer to the previous node in the list */
  80. NPLINKNODE pNext; /* @field NPLINKNODE | pNext |
  81. Pointer to the next node in the list */
  82. };
  83. /* @struct DirectMusic event as packed by IDirectMusic
  84. */
  85. struct DMEVENT {
  86. DWORD cbEvent; /* @field DWORD | cbEvent |
  87. Unrounded number of event bytes */
  88. DWORD dwChannelGroup; /* @field DWORD | dwChannelGroup |
  89. This field determines which channel group (set of 16 MIDI channels) receives the event. */
  90. QUADWORD rtDelta; /* @field QUADWORD | rtDelta | Offset from buffer header in 100 ns units */
  91. DWORD dwFlags; /* @field DWORD | dwFlags | DMEVENT_xxx */
  92. BYTE abEvent[0]; /* @field BYTE | abEvent[] |
  93. Actual event data, rounded up to be an even number
  94. of QWORD's (8 bytes) */
  95. };
  96. /* Total size of an event needed to hold cb bytes of data */
  97. #define DMEVENT_SIZE(cb) QWORD_ALIGN(sizeof(DMEVENT) + (cb))
  98. /* If we have cb for event + data, how much data can we fit? */
  99. #define DMEVENT_DATASIZE(cb) (QWORD_TRUNC(cb) - sizeof(DMEVENT))
  100. #define DMEVENT_STRUCTURED 0x00000001
  101. #define EVENT_F_MIDIHDR 0x0001
  102. /* @struct Event as stored in an <c EVENTQUEUE>.
  103. */
  104. struct EVENT {
  105. LPEVENT lpNext; /* @field LPEVENT | lpNext |
  106. Next event in queue */
  107. DWORD msTime; /* @field DWORD | msTime |
  108. Absolute ms time in stream time (i.e. timeSetEvent) */
  109. QUADWORD rtTime; /* @field QUADWORD | rtTime |
  110. Absolute time in 100ns units relative to reference clock. Use for sorting event queue. */
  111. WORD wFlags; /* @field WORD | wFlags |
  112. A bitwise combination of the following flags:
  113. @flag EVENT_F_MIDIHDR | The event data starts with a MIDIHDR */
  114. WORD cbEvent; /* @field WORD | cbEvent |
  115. The unrounded number of bytes in the event data */
  116. BYTE abEvent[0]; /* @field BYTE | abEvent[] |
  117. The actual event data, rounded up to be an even number of DWORD's */
  118. };
  119. /* @struct A queue of <c EVENT> structs.
  120. *
  121. * @comm
  122. * This is not the same as the generic list in list.c because we don't need
  123. * the overhead of a prev pointer here and we don't need the overhead of a far
  124. * pointer there.
  125. */
  126. struct EVENTQUEUE {
  127. LPEVENT pHead; /* @field LPEVENT | pHead | Pointer to the first event */
  128. LPEVENT pTail; /* @field LPEVENT | pTail | Pointer to the last event */
  129. UINT cEle; /* @field UINT | cEle | The number of events currently in queue */
  130. };
  131. /* @struct An instance of an open device
  132. *
  133. * @comm
  134. *
  135. * Since multiple Win32 processes can hold a single MMSYSTEM handle open,
  136. * we need to track them. There is one of these structs per Win32 client
  137. * per open handle. It simply refers to the OPENHANDLE which contains
  138. * all the actual handle data.
  139. *
  140. */
  141. struct OPENHANDLEINSTANCE {
  142. LINKNODE link; /* @field LINKNODE | link | Holds this handle in gOpenHandleInstanceList */
  143. LINKNODE linkHandleList; /* @field LINKNODE | linkHandleList |
  144. Holds this handle in the list maintained in the <c OPENHANDLE> struct for this device. */
  145. NPOPENHANDLE pHandle; /* @field NPOPENHANDLE | pHandle |
  146. Pointer to the <c OPENHANDLE> struct for this device. */
  147. DWORD dwVxDEventHandle; /* @field DWORD | dwVxDEventHandle |
  148. VxD Event handle for signalling input on this device for this client. */
  149. BOOL fActive; /* @field BOOL | fActive | Indicates if the port is active or not. This is used for per-instance
  150. focus management. If the port is flagged as inactive, then the underlying device is not opened. */
  151. WORD wTask; /* @field WORD | wTask | Task which opened the handle. This is used to clean up if the task
  152. terminates abnormally. */
  153. NPTHRUCHANNEL pThru; /* @field NPTHRUCHANNEL | pThru If an input device, an array of 16 thru
  154. entries, one per input channel. */
  155. };
  156. /* OPENHANDLE.wFlags
  157. */
  158. #define OH_F_MIDIIN 0x0001 /* This is a MIDI input device */
  159. #define OH_F_CLOSING 0x0002 /* This device is being closed */
  160. #define OH_F_SHARED 0x0004 /* This device is shareable */
  161. /* @struct An open device
  162. *
  163. * @comm
  164. *
  165. * There is a one-to-one relationship between open handles and <c OPENHANDLE> structs.
  166. *
  167. * All of the following event queues are either
  168. * Protected - means it is accessible at callback time and user time, and is
  169. * protected by wCritSect
  170. * Callback - Means it is unprotected by a critical section and is only accessible
  171. * at callback time. Callbacks, per handle, are not reentered.
  172. *
  173. * In the MIDI in callback, we *cannot* just go away if we don't get wCritSect,
  174. * as we can on output. Hence the multiple input queues below.
  175. *
  176. * When the user mode refill algorithm runs, it puts events in qFree, protected
  177. * by the critical section. (The one exception to this is preloading qFreeCB before
  178. * midiInStart is called on the handle). When the callback runs, it tried to get the
  179. * critical section. If it can, it moves the free events from qFree to qFreeCB.
  180. *
  181. * In any case, the callback can now use qFreeCB even if it didn't get the critical
  182. * section. It pulls a free event from the queue, fills it, and puts it back onto
  183. * the tail of qDoneCB. If the critical section is held, it then transfers the
  184. * entire contents of qDoneCB to qDone.
  185. *
  186. * These transfers are not time consuming; they are merely the manipulation of
  187. * a couple of pointers.
  188. */
  189. struct OPENHANDLE {
  190. LINKNODE link; /* @field LINKNODE | link |
  191. Holds this handle in gOpenHandles */
  192. NPLINKNODE pInstanceList; /* @field NPLINKLINK | pInstanceList |
  193. Points to the first element in the list of open handle instances using
  194. this device. */
  195. UINT uReferenceCount; /* @field UINT | uReferenceCount |
  196. The number of clients using this device; i.e., the number of elements in the
  197. pInstanceList. */
  198. UINT uActiveCount; /* @field UINT | uActiveCount |
  199. The number of clients that have activated this device */
  200. UINT id; /* @field UINT | id | The MMSYSTEM device ID of this device */
  201. WORD wFlags; /* @field WORD | wFlags | Some combination of the following flags:
  202. @flag OH_F_MIDIIN | This device is a MIDI input device
  203. @flag OH_F_CLOSING | This device is being closed.
  204. @flag OH_F_SHARE | This device is opened in shared mode */
  205. HMIDIOUT hmo; /* @field HMIDIOUT | hmo | MIDI output handle if an output device */
  206. HMIDIIN hmi; /* @field HMIDIIN | hmi | MIDI input handle if an input device */
  207. WORD wCritSect; /* @field WORD | wCritSect | Critical section protecting protected queues */
  208. DWORD msStartTime; /* @field DWORD | msStartTime | <f timeGetTime()> Time we started input */
  209. EVENTQUEUE qPlay; /* @field EVENTQUEUE | qPlay |
  210. Output: Queue of events to play (protected) */
  211. EVENTQUEUE qDone; /* @field EVENTQUEUE | qDone |
  212. Input/Output: Events already done (played or received) (protected) */
  213. EVENTQUEUE qFree; /* @field EVENTQUEUE | qFree |
  214. Input: Queue of free events (protected) */
  215. EVENTQUEUE qFreeCB; /* @field EVENTQUEUE | qFreeCB |
  216. Input: Queue of free events used by callback */
  217. EVENTQUEUE qDoneCB; /* @field EVENTQUEUE | qDoneCB |
  218. Input: Queue of received events used by callback */
  219. WORD wPostedSysExBuffers; /* @field WORD | cPostedSysExBuffers |
  220. Input: Buffers posted in MMSYSTEM for recording SysEx */
  221. };
  222. #define CLASS_MIDI 0 /* dwEventClass */
  223. /* Close to our page size
  224. */
  225. #define SEG_SIZE 4096
  226. #define C_PER_SEG ((SEG_SIZE - sizeof(SEGHDR)) / (sizeof(EVENT) + sizeof(DWORD)))
  227. #define SEG_F_4BYTE_EVENTS 0x0001
  228. typedef struct SEGHDR SEGHDR;
  229. typedef struct SEGHDR FAR * LPSEGHDR;
  230. /* @struct The header for one segment of allocated memory
  231. */
  232. struct SEGHDR {
  233. WORD selNext; /* @field WORD | selNext |
  234. The selector of the next block of memory in the allocated list */
  235. WORD hSeg; /* @field WORD | hSeg |
  236. The global handle of the memory block */
  237. WORD wFlags; /* @field WORD | wFlags |
  238. A bitwise combination of the following flags:
  239. @flag SEG_F_4BYTE_EVENTS | This segment contains multiple
  240. channel messages */
  241. WORD cbSeg; /* @field WORD | cbSeg |
  242. The size of the segment, less the <c SEGHDR> */
  243. };
  244. /* @struct Thru information for one channel
  245. *
  246. * @comm
  247. *
  248. * Each input device handle instance contains an array of 16 of these structures containing
  249. * the thru destination for data that arrives on that channel.
  250. *
  251. */
  252. struct THRUCHANNEL {
  253. WORD wChannel; /* @field WORD | wChannel | The destination channel */
  254. NPOPENHANDLEINSTANCE pohi; /* @field NPOPENHANDLEINSTANCE | pohi | The output handle instance
  255. to receive the thru'ed data. */
  256. };
  257. /* globals */
  258. extern HINSTANCE ghInst;
  259. extern NPLINKNODE gOpenHandleInstanceList;
  260. extern NPLINKNODE gOpenHandleList;
  261. extern UINT gcOpenInputDevices;
  262. extern UINT gcOpenOutputDevices;
  263. /* device.c */
  264. #define VA_F_INPUT 0x0001
  265. #define VA_F_OUTPUT 0x0002
  266. #define VA_F_EITHER (VA_F_INPUT | VA_F_OUTPUT)
  267. extern VOID PASCAL DeviceOnLoad(VOID);
  268. extern MMRESULT PASCAL CloseLegacyDeviceI(NPOPENHANDLEINSTANCE pohi);
  269. extern MMRESULT PASCAL ActivateLegacyDeviceI(NPOPENHANDLEINSTANCE pohi, BOOL fActivate);
  270. extern BOOL PASCAL IsValidHandle(HANDLE h, WORD wType, NPOPENHANDLEINSTANCE FAR *lppohi);
  271. extern VOID PASCAL CloseDevicesForTask(WORD wTask);
  272. /* list.c */
  273. extern VOID PASCAL ListInsert(NPLINKNODE *pHead, NPLINKNODE pNode);
  274. extern VOID PASCAL ListRemove(NPLINKNODE *pHead, NPLINKNODE pNode);
  275. /* eventq.c */
  276. extern VOID PASCAL QueueInit(NPEVENTQUEUE pQueue);
  277. extern VOID PASCAL QueueAppend(NPEVENTQUEUE pQueue, LPEVENT pEvent);
  278. extern VOID PASCAL QueueCat(NPEVENTQUEUE pDest, NPEVENTQUEUE pSource);
  279. extern LPEVENT PASCAL QueueRemoveFromFront(NPEVENTQUEUE pQueue);
  280. #define QUEUE_FILTER_KEEP (0)
  281. #define QUEUE_FILTER_REMOVE (1)
  282. typedef int (PASCAL *PFNQUEUEFILTER)(LPEVENT pEvent, DWORD dwInstance);
  283. extern VOID PASCAL QueueFilter(NPEVENTQUEUE pQueue, DWORD dwInstance, PFNQUEUEFILTER pfnFilter);
  284. extern LPEVENT PASCAL QueuePeek(NPEVENTQUEUE pQueue);
  285. #ifdef DEBUG
  286. #define AssertQueueValid(pQueue) _AssertQueueValid((pQueue), __FILE__, __LINE__)
  287. extern VOID PASCAL _AssertQueueValid(NPEVENTQUEUE pQueue, LPSTR pstrFile, UINT uLine);
  288. #else
  289. #define AssertQueueValid
  290. #endif
  291. /* locks.c */
  292. #define LOCK_F_INPUT 0x0001
  293. #define LOCK_F_OUTPUT 0x0002
  294. #define LOCK_F_COMMON 0x0004
  295. extern VOID PASCAL LockCode(WORD wFlags);
  296. extern VOID PASCAL UnlockCode(WORD wFlags);
  297. /* dmhelp.asm */
  298. extern VOID PASCAL InitializeCriticalSection(LPWORD lpwCritSect);
  299. #define CS_NONBLOCKING (0)
  300. #define CS_BLOCKING (1)
  301. extern WORD PASCAL EnterCriticalSection(LPWORD lpwCritSect, WORD fBlocking);
  302. extern VOID PASCAL LeaveCriticalSection(LPWORD lpwCritSect);
  303. extern WORD PASCAL DisableInterrupts(VOID);
  304. extern VOID PASCAL RestoreInterrupts(WORD wIntStat);
  305. extern WORD PASCAL InterlockedIncrement(LPWORD pw);
  306. extern WORD PASCAL InterlockedDecrement(LPWORD pw);
  307. extern DWORD PASCAL QuadwordDiv(QUADWORD qwDividend, DWORD dwDivisor);
  308. extern VOID PASCAL QuadwordMul(DWORD m1, DWORD m2, LPQUADWORD qwResult);
  309. extern BOOL PASCAL QuadwordLT(QUADWORD qwLValue, QUADWORD qwRValue);
  310. extern VOID PASCAL QuadwordAdd(QUADWORD qwOp1, QUADWORD qwOp2, LPQUADWORD lpqwResult);
  311. /* alloc.c */
  312. extern VOID PASCAL AllocOnLoad(VOID);
  313. extern VOID PASCAL AllocOnExit(VOID);
  314. extern LPEVENT PASCAL AllocEvent(DWORD msTime, QUADWORD rtTime, WORD cbEvent);
  315. extern VOID PASCAL FreeEvent(LPEVENT lpEvent);
  316. /* midiout.c */
  317. extern VOID PASCAL MidiOutOnLoad(VOID);
  318. extern VOID PASCAL MidiOutOnExit(VOID);
  319. extern MMRESULT PASCAL MidiOutOnOpen(NPOPENHANDLEINSTANCE pohi);
  320. extern VOID PASCAL MidiOutOnClose(NPOPENHANDLEINSTANCE pohi);
  321. extern MMRESULT PASCAL MidiOutOnActivate(NPOPENHANDLEINSTANCE pohi);
  322. extern MMRESULT PASCAL MidiOutOnDeactivate(NPOPENHANDLEINSTANCE pohi);
  323. extern VOID PASCAL SetOutputTimerRes(BOOL fOnOpen);
  324. extern VOID PASCAL FreeDoneHandleEvents(NPOPENHANDLE poh, BOOL fClosing);
  325. extern VOID PASCAL MidiOutThru(NPOPENHANDLEINSTANCE pohi, DWORD dwMessage);
  326. /* midiin.c */
  327. extern VOID PASCAL MidiInOnLoad(VOID);
  328. extern VOID PASCAL MidiInOnExit(VOID);
  329. extern MMRESULT PASCAL MidiInOnOpen(NPOPENHANDLEINSTANCE pohi);
  330. extern VOID PASCAL MidiInOnClose(NPOPENHANDLEINSTANCE pohi);
  331. extern MMRESULT PASCAL MidiInOnActivate(NPOPENHANDLEINSTANCE pohi);
  332. extern MMRESULT PASCAL MidiInOnDeactivate(NPOPENHANDLEINSTANCE pohi);
  333. extern VOID PASCAL MidiInRefillFreeLists(VOID);
  334. extern VOID PASCAL MidiInUnthruToInstance(NPOPENHANDLEINSTANCE pohi);
  335. extern VOID PASCAL FreeAllQueueEvents(NPEVENTQUEUE peq);
  336. /* mmdevldr.asm */
  337. extern MMRESULT CDECL SetWin32Event(DWORD dwVxDEvent); /* Must be CDECL! */
  338. /* timerwnd.c */
  339. extern BOOL PASCAL CreateTimerTask(VOID);
  340. extern VOID PASCAL DestroyTimerTask(VOID);
  341. #endif