|
|
1.1 ! root 1: /* ! 2: * circbuf.c - Routines to manage the circular MIDI input buffer. ! 3: * This buffer is filled by the low-level callback function and ! 4: * emptied by the application. Since this buffer is accessed ! 5: * by a low-level callback, memory for it must be allocated ! 6: * exactly as shown in AllocCircularBuffer(). ! 7: */ ! 8: ! 9: #include <windows.h> ! 10: #include "midimon.h" ! 11: #include "circbuf.h" ! 12: ! 13: /* ! 14: * AllocCircularBuffer - Allocates memory for a CIRCULARBUFFER structure ! 15: * and a buffer of the specified size. Each memory block is allocated ! 16: * with GlobalAlloc() using GMEM_SHARE and GMEM_MOVEABLE flags, locked ! 17: * with GlobalLock(), and page-locked with GlobalPageLock(). ! 18: * ! 19: * Params: dwSize - The size of the buffer, in events. ! 20: * ! 21: * Return: A pointer to a CIRCULARBUFFER structure identifying the ! 22: * allocated display buffer. NULL if the buffer could not be allocated. ! 23: */ ! 24: LPCIRCULARBUFFER AllocCircularBuffer(DWORD dwSize) ! 25: { ! 26: HANDLE hMem; ! 27: LPCIRCULARBUFFER lpBuf; ! 28: LPEVENT lpMem; ! 29: ! 30: /* Allocate and lock a CIRCULARBUFFER structure. ! 31: */ ! 32: hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, ! 33: (DWORD)sizeof(CIRCULARBUFFER)); ! 34: if(hMem == NULL) ! 35: return NULL; ! 36: ! 37: lpBuf = (LPCIRCULARBUFFER)GlobalLock(hMem); ! 38: if(lpBuf == NULL) ! 39: { ! 40: GlobalFree(hMem); ! 41: return NULL; ! 42: } ! 43: ! 44: /* Page lock the memory. Global memory blocks accessed by ! 45: * low-level callback functions must be page locked. ! 46: */ ! 47: //GlobalPageLock((HGLOBAL)HIWORD(lpBuf)); ! 48: ! 49: /* Save the memory handle. ! 50: */ ! 51: lpBuf->hSelf = hMem; ! 52: ! 53: /* Allocate and lock memory for the actual buffer. ! 54: */ ! 55: hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, dwSize * sizeof(EVENT)); ! 56: if(hMem == NULL) ! 57: { ! 58: //GlobalPageUnlock((HGLOBAL)HIWORD(lpBuf)); ! 59: GlobalUnlock(lpBuf->hSelf); ! 60: GlobalFree(lpBuf->hSelf); ! 61: return NULL; ! 62: } ! 63: ! 64: lpMem = (LPEVENT)GlobalLock(hMem); ! 65: if(lpMem == NULL) ! 66: { ! 67: GlobalFree(hMem); ! 68: //GlobalPageUnlock((HGLOBAL)HIWORD(lpBuf)); ! 69: GlobalUnlock(lpBuf->hSelf); ! 70: GlobalFree(lpBuf->hSelf); ! 71: return NULL; ! 72: } ! 73: ! 74: /* Page lock the memory. Global memory blocks accessed by ! 75: * low-level callback functions must be page locked. ! 76: */ ! 77: //GlobalPageLock((HGLOBAL)HIWORD(lpMem)); ! 78: ! 79: /* Set up the CIRCULARBUFFER structure. ! 80: */ ! 81: lpBuf->hBuffer = hMem; ! 82: lpBuf->wError = 0; ! 83: lpBuf->dwSize = dwSize; ! 84: lpBuf->dwCount = 0L; ! 85: lpBuf->lpStart = lpMem; ! 86: lpBuf->lpEnd = lpMem + dwSize; ! 87: lpBuf->lpTail = lpMem; ! 88: lpBuf->lpHead = lpMem; ! 89: ! 90: return lpBuf; ! 91: } ! 92: ! 93: /* FreeCircularBuffer - Frees the memory for the given CIRCULARBUFFER ! 94: * structure and the memory for the buffer it references. ! 95: * ! 96: * Params: lpBuf - Points to the CIRCULARBUFFER to be freed. ! 97: * ! 98: * Return: void ! 99: */ ! 100: void FreeCircularBuffer(LPCIRCULARBUFFER lpBuf) ! 101: { ! 102: HANDLE hMem; ! 103: ! 104: /* Free the buffer itself. ! 105: */ ! 106: //GlobalPageUnlock((HGLOBAL)HIWORD(lpBuf->lpStart)); ! 107: GlobalUnlock(lpBuf->hBuffer); ! 108: GlobalFree(lpBuf->hBuffer); ! 109: ! 110: /* Free the CIRCULARBUFFER structure. ! 111: */ ! 112: hMem = lpBuf->hSelf; ! 113: //GlobalPageUnlock((HGLOBAL)HIWORD(lpBuf)); ! 114: GlobalUnlock(hMem); ! 115: GlobalFree(hMem); ! 116: } ! 117: ! 118: /* GetEvent - Gets a MIDI event from the circular input buffer. Events ! 119: * are removed from the buffer. The corresponding PutEvent() function ! 120: * is called by the low-level callback function, so it must reside in ! 121: * the callback DLL. PutEvent() is defined in the CALLBACK.C module. ! 122: * ! 123: * Params: lpBuf - Points to the circular buffer. ! 124: * lpEvent - Points to an EVENT structure that is filled with the ! 125: * retrieved event. ! 126: * ! 127: * Return: Returns non-zero if successful, zero if there are no ! 128: * events to get. ! 129: */ ! 130: WORD FAR PASCAL GetEvent(LPCIRCULARBUFFER lpBuf, LPEVENT lpEvent) ! 131: { ! 132: /* If no event available, return. ! 133: */ ! 134: if(lpBuf->dwCount <= 0) ! 135: return 0; ! 136: ! 137: /* Get the event. ! 138: */ ! 139: *lpEvent = *lpBuf->lpTail; ! 140: ! 141: /* Decrement the byte count, bump the tail pointer. ! 142: */ ! 143: --lpBuf->dwCount; ! 144: ++lpBuf->lpTail; ! 145: ! 146: /* Wrap the tail pointer, if necessary. ! 147: */ ! 148: if(lpBuf->lpTail >= lpBuf->lpEnd) ! 149: lpBuf->lpTail = lpBuf->lpStart; ! 150: ! 151: return 1; ! 152: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.