Annotation of mstools/samples/midimon/circbuf.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.