Annotation of mstools/samples/midimon/circbuf.c, revision 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.