# HG changeset patch # User Matti Hamalainen # Date 1375719425 -10800 # Node ID 4df6d97143149562585f1cb969640462b03ead82 # Parent ad838591513aefc4871a448b4d485b481a9f69b0 Automatic reindent/cleanup pass on the midi code. diff -r ad838591513a -r 4df6d9714314 src/midifile.c --- a/src/midifile.c Mon Aug 05 18:23:20 2013 +0300 +++ b/src/midifile.c Mon Aug 05 19:17:05 2013 +0300 @@ -32,53 +32,56 @@ /* ** Internal Data Structures */ -typedef struct { - BYTE note, chn; - BYTE valid, p2; - DWORD end_pos; - } MIDI_LAST_NOTE; +typedef struct +{ + BYTE note, chn; + BYTE valid, p2; + DWORD end_pos; +} MIDI_LAST_NOTE; + +typedef struct +{ + BYTE *ptr; + BYTE *pBase; + BYTE *pEnd; + + DWORD pos; + DWORD dt; + /* For Reading MIDI Files */ + DWORD sz; /* size of whole iTrack */ + /* For Writing MIDI Files */ + DWORD iBlockSize; /* max size of track */ + BYTE iDefaultChannel; /* use for write only */ + BYTE last_status; /* used for running status */ -typedef struct { - BYTE *ptr; - BYTE *pBase; - BYTE *pEnd; - - DWORD pos; - DWORD dt; - /* For Reading MIDI Files */ - DWORD sz; /* size of whole iTrack */ - /* For Writing MIDI Files */ - DWORD iBlockSize; /* max size of track */ - BYTE iDefaultChannel; /* use for write only */ - BYTE last_status; /* used for running status */ - - MIDI_LAST_NOTE LastNote[MAX_TRACK_POLYPHONY]; - } MIDI_FILE_TRACK; + MIDI_LAST_NOTE LastNote[MAX_TRACK_POLYPHONY]; +} MIDI_FILE_TRACK; + +typedef struct +{ + DWORD iHeaderSize; + /**/ WORD iVersion; /* 0, 1 or 2 */ + WORD iNumTracks; /* number of tracks... (will be 1 for MIDI type 0) */ + WORD PPQN; /* pulses per quarter note */ +} MIDI_HEADER; -typedef struct { - DWORD iHeaderSize; - /**/ - WORD iVersion; /* 0, 1 or 2 */ - WORD iNumTracks; /* number of tracks... (will be 1 for MIDI type 0) */ - WORD PPQN; /* pulses per quarter note */ - } MIDI_HEADER; +typedef struct +{ + FILE *pFile; + BOOL bOpenForWriting; -typedef struct { - FILE *pFile; - BOOL bOpenForWriting; - - MIDI_HEADER Header; - BYTE *ptr; /* to whole data block */ - DWORD file_sz; - - MIDI_FILE_TRACK Track[MAX_MIDI_TRACKS]; - } _MIDI_FILE; + MIDI_HEADER Header; + BYTE *ptr; /* to whole data block */ + DWORD file_sz; + + MIDI_FILE_TRACK Track[MAX_MIDI_TRACKS]; +} _MIDI_FILE; /* ** Internal Functions */ -#define DT_DEF 32 /* assume maximum delta-time + msg is no more than 32 bytes */ +#define DT_DEF 32 /* assume maximum delta-time + msg is no more than 32 bytes */ #define SWAP_WORD(w) (WORD)(((w)>>8)|((w)<<8)) #define SWAP_DWORD(d) (DWORD)((d)>>24)|(((d)>>8)&0xff00)|(((d)<<8)&0xff0000)|(((d)<<24)) @@ -92,1087 +95,1187 @@ static BOOL _midiValidateTrack(const _MIDI_FILE *pMF, int iTrack) { - if (!IsFilePtrValid(pMF)) return FALSE; - - if (pMF->bOpenForWriting) - { - if (iTrack < 0 || iTrack >= MAX_MIDI_TRACKS) - return FALSE; - } - else /* open for reading */ - { - if (!pMF->ptr) - return FALSE; - - if (iTrack < 0 || iTrack>=pMF->Header.iNumTracks) - return FALSE; - } - - return TRUE; + if (!IsFilePtrValid(pMF)) + return FALSE; + + if (pMF->bOpenForWriting) + { + if (iTrack < 0 || iTrack >= MAX_MIDI_TRACKS) + return FALSE; + } + else /* open for reading */ + { + if (!pMF->ptr) + return FALSE; + + if (iTrack < 0 || iTrack >= pMF->Header.iNumTracks) + return FALSE; + } + + return TRUE; } -static BYTE *_midiWriteVarLen(BYTE *ptr, int n) +static BYTE *_midiWriteVarLen(BYTE * ptr, int n) { -register long buffer; -register long value=n; + register long buffer; + register long value = n; - buffer = value & 0x7f; - while ((value >>= 7) > 0) - { - buffer <<= 8; - buffer |= 0x80; - buffer += (value & 0x7f); - } + buffer = value & 0x7f; + while ((value >>= 7) > 0) + { + buffer <<= 8; + buffer |= 0x80; + buffer += (value & 0x7f); + } - while (TRUE) - { - *ptr++ = (BYTE)buffer; - if (buffer & 0x80) - buffer >>= 8; - else - break; - } - - return(ptr); + while (TRUE) + { + *ptr++ = (BYTE) buffer; + if (buffer & 0x80) + buffer >>= 8; + else + break; + } + + return (ptr); } /* Return a ptr to valid block of memory to store a message -** of up to sz_reqd bytes +** of up to sz_reqd bytes */ static BYTE *_midiGetPtr(_MIDI_FILE *pMF, int iTrack, int sz_reqd) { -const DWORD mem_sz_inc = 8092; /* arbitary */ -BYTE *ptr; -int curr_offset; -MIDI_FILE_TRACK *pTrack = &pMF->Track[iTrack]; + const DWORD mem_sz_inc = 8092; /* arbitary */ + BYTE *ptr; + int curr_offset; + MIDI_FILE_TRACK *pTrack = &pMF->Track[iTrack]; - ptr = pTrack->ptr; - if (ptr == NULL || ptr+sz_reqd > pTrack->pEnd) /* need more RAM! */ - { - curr_offset = ptr-pTrack->pBase; - if ((ptr = (BYTE *)realloc(pTrack->pBase, mem_sz_inc+pTrack->iBlockSize))) - { - pTrack->pBase = ptr; - pTrack->iBlockSize += mem_sz_inc; - pTrack->pEnd = ptr+pTrack->iBlockSize; - /* Move new ptr to continue data entry: */ - pTrack->ptr = ptr+curr_offset; - ptr += curr_offset; - } - else - { - /* NO MEMORY LEFT */ - return NULL; - } - } + ptr = pTrack->ptr; + if (ptr == NULL || ptr + sz_reqd > pTrack->pEnd) /* need more RAM! */ + { + curr_offset = ptr - pTrack->pBase; + if ((ptr = + (BYTE *) realloc(pTrack->pBase, + mem_sz_inc + pTrack->iBlockSize))) + { + pTrack->pBase = ptr; + pTrack->iBlockSize += mem_sz_inc; + pTrack->pEnd = ptr + pTrack->iBlockSize; + /* Move new ptr to continue data entry: */ + pTrack->ptr = ptr + curr_offset; + ptr += curr_offset; + } + else + { + /* NO MEMORY LEFT */ + return NULL; + } + } - return ptr; + return ptr; } static int _midiGetLength(int ppqn, int iNoteLen, BOOL bOverride) { -int length = ppqn; - - if (bOverride) - { - length = iNoteLen; - } - else - { - switch(iNoteLen) - { - case MIDI_NOTE_DOTTED_MINIM: - length *= 3; - break; + int length = ppqn; + + if (bOverride) + { + length = iNoteLen; + } + else + { + switch (iNoteLen) + { + case MIDI_NOTE_DOTTED_MINIM: + length *= 3; + break; - case MIDI_NOTE_DOTTED_CROCHET: - length *= 3; - length /= 2; - break; + case MIDI_NOTE_DOTTED_CROCHET: + length *= 3; + length /= 2; + break; - case MIDI_NOTE_DOTTED_QUAVER: - length *= 3; - length /= 4; - break; + case MIDI_NOTE_DOTTED_QUAVER: + length *= 3; + length /= 4; + break; - case MIDI_NOTE_DOTTED_SEMIQUAVER: - length *= 3; - length /= 8; - break; + case MIDI_NOTE_DOTTED_SEMIQUAVER: + length *= 3; + length /= 8; + break; - case MIDI_NOTE_DOTTED_SEMIDEMIQUAVER: - length *= 3; - length /= 16; - break; + case MIDI_NOTE_DOTTED_SEMIDEMIQUAVER: + length *= 3; + length /= 16; + break; - case MIDI_NOTE_BREVE: - length *= 4; - break; + case MIDI_NOTE_BREVE: + length *= 4; + break; - case MIDI_NOTE_MINIM: - length *= 2; - break; + case MIDI_NOTE_MINIM: + length *= 2; + break; - case MIDI_NOTE_QUAVER: - length /= 2; - break; + case MIDI_NOTE_QUAVER: + length /= 2; + break; - case MIDI_NOTE_SEMIQUAVER: - length /= 4; - break; + case MIDI_NOTE_SEMIQUAVER: + length /= 4; + break; + + case MIDI_NOTE_SEMIDEMIQUAVER: + length /= 8; + break; - case MIDI_NOTE_SEMIDEMIQUAVER: - length /= 8; - break; - - case MIDI_NOTE_TRIPLE_CROCHET: - length *= 2; - length /= 3; - break; - } - } - - return length; + case MIDI_NOTE_TRIPLE_CROCHET: + length *= 2; + length /= 3; + break; + } + } + + return length; } /* ** midiFile* Functions */ -MIDI_FILE *midiFileCreate(const char *pFilename, BOOL bOverwriteIfExists) +MIDI_FILE *midiFileCreate(const char *pFilename, BOOL bOverwriteIfExists) { -_MIDI_FILE *pMF = (_MIDI_FILE *)malloc(sizeof(_MIDI_FILE)); -int i; + _MIDI_FILE *pMF = (_MIDI_FILE *) malloc(sizeof(_MIDI_FILE)); + int i; + + if (!pMF) + return NULL; + + if (!bOverwriteIfExists) + { + if ((pMF->pFile = fopen(pFilename, "r"))) + { + fclose(pMF->pFile); + free(pMF); + return NULL; + } + } - if (!pMF) return NULL; - - if (!bOverwriteIfExists) - { - if ((pMF->pFile = fopen(pFilename, "r"))) - { - fclose(pMF->pFile); - free(pMF); - return NULL; - } - } - - if ((pMF->pFile = fopen(pFilename, "wb+"))) - {/*empty*/} - else - { - free((void *)pMF); - return NULL; - } - - pMF->bOpenForWriting = TRUE; - pMF->Header.PPQN = MIDI_PPQN_DEFAULT; - pMF->Header.iVersion = MIDI_VERSION_DEFAULT; - - for(i=0;iTrack[i].pos = 0; - pMF->Track[i].ptr = NULL; - pMF->Track[i].pBase = NULL; - pMF->Track[i].pEnd = NULL; - pMF->Track[i].iBlockSize = 0; - pMF->Track[i].dt = 0; - pMF->Track[i].iDefaultChannel = (BYTE)(i & 0xf); - - memset(pMF->Track[i].LastNote, '\0', sizeof(pMF->Track[i].LastNote)); - } - - return (MIDI_FILE *)pMF; + if ((pMF->pFile = fopen(pFilename, "wb+"))) + { /*empty */ + } + else + { + free((void *) pMF); + return NULL; + } + + pMF->bOpenForWriting = TRUE; + pMF->Header.PPQN = MIDI_PPQN_DEFAULT; + pMF->Header.iVersion = MIDI_VERSION_DEFAULT; + + for (i = 0; i < MAX_MIDI_TRACKS; ++i) + { + pMF->Track[i].pos = 0; + pMF->Track[i].ptr = NULL; + pMF->Track[i].pBase = NULL; + pMF->Track[i].pEnd = NULL; + pMF->Track[i].iBlockSize = 0; + pMF->Track[i].dt = 0; + pMF->Track[i].iDefaultChannel = (BYTE) (i & 0xf); + + memset(pMF->Track[i].LastNote, '\0', sizeof(pMF->Track[i].LastNote)); + } + + return (MIDI_FILE *) pMF; } -int midiFileSetTracksDefaultChannel(MIDI_FILE *_pMF, int iTrack, int iChannel) +int midiFileSetTracksDefaultChannel(MIDI_FILE *_pMF, int iTrack, + int iChannel) { -int prev; + int prev; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return 0; - if (!IsTrackValid(iTrack)) return 0; - if (!IsChannelValid(iChannel)) return 0; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return 0; + if (!IsTrackValid(iTrack)) + return 0; + if (!IsChannelValid(iChannel)) + return 0; - /* For programmer each, iChannel is between 1 & 16 - but MIDI uses - ** 0-15. Thus, the fudge factor of 1 :) - */ - prev = pMF->Track[iTrack].iDefaultChannel+1; - pMF->Track[iTrack].iDefaultChannel = (BYTE)(iChannel-1); - return prev; + /* For programmer each, iChannel is between 1 & 16 - but MIDI uses + ** 0-15. Thus, the fudge factor of 1 :) + */ + prev = pMF->Track[iTrack].iDefaultChannel + 1; + pMF->Track[iTrack].iDefaultChannel = (BYTE) (iChannel - 1); + return prev; } -int midiFileGetTracksDefaultChannel(const MIDI_FILE *_pMF, int iTrack) +int midiFileGetTracksDefaultChannel(const MIDI_FILE *_pMF, int iTrack) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return 0; - if (!IsTrackValid(iTrack)) return 0; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return 0; + if (!IsTrackValid(iTrack)) + return 0; - return pMF->Track[iTrack].iDefaultChannel+1; + return pMF->Track[iTrack].iDefaultChannel + 1; } -int midiFileSetPPQN(MIDI_FILE *_pMF, int PPQN) +int midiFileSetPPQN(MIDI_FILE *_pMF, int PPQN) { -int prev; + int prev; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return MIDI_PPQN_DEFAULT; - prev = pMF->Header.PPQN; - pMF->Header.PPQN = (WORD)PPQN; - return prev; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return MIDI_PPQN_DEFAULT; + prev = pMF->Header.PPQN; + pMF->Header.PPQN = (WORD) PPQN; + return prev; } -int midiFileGetPPQN(const MIDI_FILE *_pMF) +int midiFileGetPPQN(const MIDI_FILE *_pMF) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return MIDI_PPQN_DEFAULT; - return (int)pMF->Header.PPQN; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return MIDI_PPQN_DEFAULT; + return (int) pMF->Header.PPQN; } -int midiFileSetVersion(MIDI_FILE *_pMF, int iVersion) +int midiFileSetVersion(MIDI_FILE *_pMF, int iVersion) { -int prev; + int prev; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return MIDI_VERSION_DEFAULT; - if (iVersion<0 || iVersion>2) return MIDI_VERSION_DEFAULT; - prev = pMF->Header.iVersion; - pMF->Header.iVersion = (WORD)iVersion; - return prev; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return MIDI_VERSION_DEFAULT; + if (iVersion < 0 || iVersion > 2) + return MIDI_VERSION_DEFAULT; + prev = pMF->Header.iVersion; + pMF->Header.iVersion = (WORD) iVersion; + return prev; } -int midiFileGetVersion(const MIDI_FILE *_pMF) +int midiFileGetVersion(const MIDI_FILE *_pMF) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return MIDI_VERSION_DEFAULT; - return pMF->Header.iVersion; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return MIDI_VERSION_DEFAULT; + return pMF->Header.iVersion; } -MIDI_FILE *midiFileOpen(const char *pFilename) +MIDI_FILE *midiFileOpen(const char *pFilename) { -FILE *fp = fopen(pFilename, "rb"); -_MIDI_FILE *pMF = NULL; -BYTE *ptr; -BOOL bValidFile=FALSE; -long size; + FILE *fp = fopen(pFilename, "rb"); + _MIDI_FILE *pMF = NULL; + BYTE *ptr; + BOOL bValidFile = FALSE; + long size; - if (fp) - { - if ((pMF = (_MIDI_FILE *)malloc(sizeof(_MIDI_FILE)))) - { - fseek(fp, 0L, SEEK_END); - size = ftell(fp); - if ((pMF->ptr = (BYTE *)malloc(size))) - { - fseek(fp, 0L, SEEK_SET); - fread(pMF->ptr, sizeof(BYTE), size, fp); - /* Is this a valid MIDI file ? */ - ptr = pMF->ptr; - if (*(ptr+0) == 'M' && *(ptr+1) == 'T' && - *(ptr+2) == 'h' && *(ptr+3) == 'd') - { - DWORD dwData; - WORD wData; - int i; + if (fp) + { + if ((pMF = (_MIDI_FILE *) malloc(sizeof(_MIDI_FILE)))) + { + fseek(fp, 0L, SEEK_END); + size = ftell(fp); + if ((pMF->ptr = (BYTE *) malloc(size))) + { + fseek(fp, 0L, SEEK_SET); + fread(pMF->ptr, sizeof(BYTE), size, fp); + /* Is this a valid MIDI file ? */ + ptr = pMF->ptr; + if (*(ptr + 0) == 'M' && *(ptr + 1) == 'T' && + *(ptr + 2) == 'h' && *(ptr + 3) == 'd') + { + DWORD dwData; + WORD wData; + int i; + + dwData = *((DWORD *) (ptr + 4)); + pMF->Header.iHeaderSize = SWAP_DWORD(dwData); + + wData = *((WORD *) (ptr + 8)); + pMF->Header.iVersion = (WORD) SWAP_WORD(wData); + + wData = *((WORD *) (ptr + 10)); + pMF->Header.iNumTracks = (WORD) SWAP_WORD(wData); + + wData = *((WORD *) (ptr + 12)); + pMF->Header.PPQN = (WORD) SWAP_WORD(wData); - dwData = *((DWORD *)(ptr+4)); - pMF->Header.iHeaderSize = SWAP_DWORD(dwData); - - wData = *((WORD *)(ptr+8)); - pMF->Header.iVersion = (WORD)SWAP_WORD(wData); - - wData = *((WORD *)(ptr+10)); - pMF->Header.iNumTracks = (WORD)SWAP_WORD(wData); - - wData = *((WORD *)(ptr+12)); - pMF->Header.PPQN = (WORD)SWAP_WORD(wData); - - ptr += pMF->Header.iHeaderSize+8; - /* - ** Get all tracks - */ - for(i=0;iTrack[i].pos = 0; - pMF->Track[i].last_status = 0; - } - - for(i=0;iHeader.iNumTracks;++i) - { - pMF->Track[i].pBase = ptr; - pMF->Track[i].ptr = ptr+8; - dwData = *((DWORD *)(ptr+4)); - pMF->Track[i].sz = SWAP_DWORD(dwData); - pMF->Track[i].pEnd = ptr+pMF->Track[i].sz+8; - ptr += pMF->Track[i].sz+8; - } - - pMF->bOpenForWriting = FALSE; - pMF->pFile = NULL; - bValidFile = TRUE; - } - } - } + ptr += pMF->Header.iHeaderSize + 8; + /* + ** Get all tracks + */ + for (i = 0; i < MAX_MIDI_TRACKS; ++i) + { + pMF->Track[i].pos = 0; + pMF->Track[i].last_status = 0; + } - fclose(fp); - } - - if (!bValidFile) - { - if (pMF) free((void *)pMF); - return NULL; - } - - return (MIDI_FILE *)pMF; + for (i = 0; i < pMF->Header.iNumTracks; ++i) + { + pMF->Track[i].pBase = ptr; + pMF->Track[i].ptr = ptr + 8; + dwData = *((DWORD *) (ptr + 4)); + pMF->Track[i].sz = SWAP_DWORD(dwData); + pMF->Track[i].pEnd = ptr + pMF->Track[i].sz + 8; + ptr += pMF->Track[i].sz + 8; + } + + pMF->bOpenForWriting = FALSE; + pMF->pFile = NULL; + bValidFile = TRUE; + } + } + } + + fclose(fp); + } + + if (!bValidFile) + { + if (pMF) + free((void *) pMF); + return NULL; + } + + return (MIDI_FILE *) pMF; } -typedef struct { - int iIdx; - int iEndPos; - } MIDI_END_POINT; +typedef struct +{ + int iIdx; + int iEndPos; +} MIDI_END_POINT; static int qs_cmp_pEndPoints(const void *e1, const void *e2) { -MIDI_END_POINT *p1 = (MIDI_END_POINT *)e1; -MIDI_END_POINT *p2 = (MIDI_END_POINT *)e2; + MIDI_END_POINT *p1 = (MIDI_END_POINT *) e1; + MIDI_END_POINT *p2 = (MIDI_END_POINT *) e2; - return p1->iEndPos-p2->iEndPos; + return p1->iEndPos - p2->iEndPos; } -BOOL midiFileFlushTrack(MIDI_FILE *_pMF, int iTrack, BOOL bFlushToEnd, DWORD dwEndTimePos) +BOOL midiFileFlushTrack(MIDI_FILE *_pMF, int iTrack, BOOL bFlushToEnd, + DWORD dwEndTimePos) { -int sz; -BYTE *ptr; -MIDI_END_POINT *pEndPoints; -int num, i, mx_pts; -BOOL bNoChanges = TRUE; + int sz; + BYTE *ptr; + MIDI_END_POINT *pEndPoints; + int num, i, mx_pts; + BOOL bNoChanges = TRUE; + + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!_midiValidateTrack(pMF, iTrack)) + return FALSE; + sz = sizeof(pMF->Track[0].LastNote) / sizeof(pMF->Track[0].LastNote[0]); - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!_midiValidateTrack(pMF, iTrack)) return FALSE; - sz = sizeof(pMF->Track[0].LastNote)/sizeof(pMF->Track[0].LastNote[0]); + /* + ** Flush all + */ + pEndPoints = (MIDI_END_POINT *) malloc(sz * sizeof(MIDI_END_POINT)); + mx_pts = 0; + for (i = 0; i < sz; ++i) + if (pMF->Track[iTrack].LastNote[i].valid) + { + pEndPoints[mx_pts].iIdx = i; + pEndPoints[mx_pts].iEndPos = + pMF->Track[iTrack].LastNote[i].end_pos; + mx_pts++; + } + + if (bFlushToEnd) + { + if (mx_pts) + dwEndTimePos = pEndPoints[mx_pts - 1].iEndPos; + else + dwEndTimePos = pMF->Track[iTrack].pos; + } - /* - ** Flush all - */ - pEndPoints = (MIDI_END_POINT *)malloc(sz * sizeof(MIDI_END_POINT)); - mx_pts = 0; - for(i=0;iTrack[iTrack].LastNote[i].valid) - { - pEndPoints[mx_pts].iIdx = i; - pEndPoints[mx_pts].iEndPos = pMF->Track[iTrack].LastNote[i].end_pos; - mx_pts++; - } - - if (bFlushToEnd) - { - if (mx_pts) - dwEndTimePos = pEndPoints[mx_pts-1].iEndPos; - else - dwEndTimePos = pMF->Track[iTrack].pos; - } - - if (mx_pts) - { - /* Sort, smallest first, and add the note off msgs */ - qsort(pEndPoints, mx_pts, sizeof(MIDI_END_POINT), qs_cmp_pEndPoints); - - i = 0; - while ((dwEndTimePos >= (DWORD)pEndPoints[i].iEndPos || bFlushToEnd) && iTrack[iTrack].LastNote[num].end_pos - pMF->Track[iTrack].pos); - /* msgNoteOn msgNoteOff */ - *ptr++ = (BYTE)(msgNoteOff | pMF->Track[iTrack].LastNote[num].chn); - *ptr++ = pMF->Track[iTrack].LastNote[num].note; - *ptr++ = 0; - - pMF->Track[iTrack].LastNote[num].valid = FALSE; - pMF->Track[iTrack].pos = pMF->Track[iTrack].LastNote[num].end_pos; - - pMF->Track[iTrack].ptr = ptr; - - ++i; - bNoChanges = FALSE; - } - } - - free((void *)pEndPoints); - /* - ** Re-calc current position - */ - pMF->Track[iTrack].dt = dwEndTimePos - pMF->Track[iTrack].pos; - - return TRUE; + if (mx_pts) + { + /* Sort, smallest first, and add the note off msgs */ + qsort(pEndPoints, mx_pts, sizeof(MIDI_END_POINT), qs_cmp_pEndPoints); + + i = 0; + while ((dwEndTimePos >= (DWORD) pEndPoints[i].iEndPos || bFlushToEnd) + && i < mx_pts) + { + ptr = _midiGetPtr(pMF, iTrack, DT_DEF); + if (!ptr) + return FALSE; + + num = pEndPoints[i].iIdx; /* get 'LastNote' index */ + + ptr = + _midiWriteVarLen(ptr, + pMF->Track[iTrack].LastNote[num].end_pos - + pMF->Track[iTrack].pos); + /* msgNoteOn msgNoteOff */ + *ptr++ = + (BYTE) (msgNoteOff | pMF->Track[iTrack].LastNote[num].chn); + *ptr++ = pMF->Track[iTrack].LastNote[num].note; + *ptr++ = 0; + + pMF->Track[iTrack].LastNote[num].valid = FALSE; + pMF->Track[iTrack].pos = pMF->Track[iTrack].LastNote[num].end_pos; + + pMF->Track[iTrack].ptr = ptr; + + ++i; + bNoChanges = FALSE; + } + } + + free((void *) pEndPoints); + /* + ** Re-calc current position + */ + pMF->Track[iTrack].dt = dwEndTimePos - pMF->Track[iTrack].pos; + + return TRUE; } -BOOL midiFileSyncTracks(MIDI_FILE *_pMF, int iTrack1, int iTrack2) +BOOL midiFileSyncTracks(MIDI_FILE *_pMF, int iTrack1, int iTrack2) { -int p1, p2; + int p1, p2; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack1)) return FALSE; - if (!IsTrackValid(iTrack2)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack1)) + return FALSE; + if (!IsTrackValid(iTrack2)) + return FALSE; - p1 = pMF->Track[iTrack1].pos + pMF->Track[iTrack1].dt; - p2 = pMF->Track[iTrack2].pos + pMF->Track[iTrack2].dt; - - if (p1 < p2) midiTrackIncTime(pMF, iTrack1, p2-p1, TRUE); - else if (p2 < p1) midiTrackIncTime(pMF, iTrack2, p1-p2, TRUE); - - return TRUE; + p1 = pMF->Track[iTrack1].pos + pMF->Track[iTrack1].dt; + p2 = pMF->Track[iTrack2].pos + pMF->Track[iTrack2].dt; + + if (p1 < p2) + midiTrackIncTime(pMF, iTrack1, p2 - p1, TRUE); + else if (p2 < p1) + midiTrackIncTime(pMF, iTrack2, p1 - p2, TRUE); + + return TRUE; } -BOOL midiFileClose(MIDI_FILE *_pMF) +BOOL midiFileClose(MIDI_FILE *_pMF) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - - if (pMF->bOpenForWriting) - { - WORD iNumTracks = 0; - WORD wTest = 256; - BOOL bSwap = FALSE; - int i; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; - /* Intel processor style-endians need byte swap :( */ - if (*((BYTE *)&wTest) == 0) - bSwap = TRUE; + if (pMF->bOpenForWriting) + { + WORD iNumTracks = 0; + WORD wTest = 256; + BOOL bSwap = FALSE; + int i; + + /* Intel processor style-endians need byte swap :( */ + if (*((BYTE *) & wTest) == 0) + bSwap = TRUE; - /* Flush our buffers */ - for(i=0;iTrack[i].ptr) - { - midiSongAddEndSequence(pMF, i); - midiFileFlushTrack(pMF, i, TRUE, 0); - iNumTracks++; - } - } - /* - ** Header - */ - { - const BYTE mthd[4] = {'M', 'T', 'h', 'd'}; - DWORD dwData; - WORD wData; - WORD version, PPQN; + /* Flush our buffers */ + for (i = 0; i < MAX_MIDI_TRACKS; ++i) + { + if (pMF->Track[i].ptr) + { + midiSongAddEndSequence(pMF, i); + midiFileFlushTrack(pMF, i, TRUE, 0); + iNumTracks++; + } + } + /* + ** Header + */ + { + const BYTE mthd[4] = { 'M', 'T', 'h', 'd' }; + DWORD dwData; + WORD wData; + WORD version, PPQN; - fwrite(mthd, sizeof(BYTE), 4, pMF->pFile); - dwData = 6; - if (bSwap) dwData = SWAP_DWORD(dwData); - fwrite(&dwData, sizeof(DWORD), 1, pMF->pFile); + fwrite(mthd, sizeof(BYTE), 4, pMF->pFile); + dwData = 6; + if (bSwap) + dwData = SWAP_DWORD(dwData); + fwrite(&dwData, sizeof(DWORD), 1, pMF->pFile); - wData = (WORD)(iNumTracks==1?pMF->Header.iVersion:1); - if (bSwap) version = SWAP_WORD(wData); else version = (WORD)wData; - if (bSwap) iNumTracks = SWAP_WORD(iNumTracks); - wData = pMF->Header.PPQN; - if (bSwap) PPQN = SWAP_WORD(wData); else PPQN = wData; - fwrite(&version, sizeof(WORD), 1, pMF->pFile); - fwrite(&iNumTracks, sizeof(WORD), 1, pMF->pFile); - fwrite(&PPQN, sizeof(WORD), 1, pMF->pFile); - } - /* - ** Track data - */ - for(i=0;iTrack[i].ptr) - { - const BYTE mtrk[4] = {'M', 'T', 'r', 'k'}; - DWORD sz, dwData; + wData = (WORD) (iNumTracks == 1 ? pMF->Header.iVersion : 1); + if (bSwap) + version = SWAP_WORD(wData); + else + version = (WORD) wData; + if (bSwap) + iNumTracks = SWAP_WORD(iNumTracks); + wData = pMF->Header.PPQN; + if (bSwap) + PPQN = SWAP_WORD(wData); + else + PPQN = wData; + fwrite(&version, sizeof(WORD), 1, pMF->pFile); + fwrite(&iNumTracks, sizeof(WORD), 1, pMF->pFile); + fwrite(&PPQN, sizeof(WORD), 1, pMF->pFile); + } + /* + ** Track data + */ + for (i = 0; i < MAX_MIDI_TRACKS; ++i) + if (pMF->Track[i].ptr) + { + const BYTE mtrk[4] = { 'M', 'T', 'r', 'k' }; + DWORD sz, dwData; - /* Write track header */ - fwrite(&mtrk, sizeof(BYTE), 4, pMF->pFile); + /* Write track header */ + fwrite(&mtrk, sizeof(BYTE), 4, pMF->pFile); - /* Write data size */ - sz = dwData = (int)(pMF->Track[i].ptr - pMF->Track[i].pBase); - if (bSwap) sz = SWAP_DWORD(sz); - fwrite(&sz, sizeof(DWORD), 1, pMF->pFile); + /* Write data size */ + sz = dwData = (int) (pMF->Track[i].ptr - pMF->Track[i].pBase); + if (bSwap) + sz = SWAP_DWORD(sz); + fwrite(&sz, sizeof(DWORD), 1, pMF->pFile); - /* Write data */ - fwrite(pMF->Track[i].pBase, sizeof(BYTE), dwData, pMF->pFile); - - /* Free memory */ - free((void *)pMF->Track[i].pBase); - } + /* Write data */ + fwrite(pMF->Track[i].pBase, sizeof(BYTE), dwData, pMF->pFile); + + /* Free memory */ + free((void *) pMF->Track[i].pBase); + } - } + } - if (pMF->pFile) - return fclose(pMF->pFile)?FALSE:TRUE; - free((void *)pMF); - return TRUE; + if (pMF->pFile) + return fclose(pMF->pFile) ? FALSE : TRUE; + free((void *) pMF); + return TRUE; } /* ** midiSong* Functions */ -BOOL midiSongAddSMPTEOffset(MIDI_FILE *_pMF, int iTrack, int iHours, int iMins, int iSecs, int iFrames, int iFFrames) +BOOL midiSongAddSMPTEOffset(MIDI_FILE *_pMF, int iTrack, int iHours, + int iMins, int iSecs, int iFrames, int iFFrames) { -static BYTE tmp[] = {msgMetaEvent, metaSMPTEOffset, 0x05, 0,0,0,0,0}; + static BYTE tmp[] = + { msgMetaEvent, metaSMPTEOffset, 0x05, 0, 0, 0, 0, 0 }; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - if (iMins<0 || iMins>59) iMins=0; - if (iSecs<0 || iSecs>59) iSecs=0; - if (iFrames<0 || iFrames>24) iFrames=0; + if (iMins < 0 || iMins > 59) + iMins = 0; + if (iSecs < 0 || iSecs > 59) + iSecs = 0; + if (iFrames < 0 || iFrames > 24) + iFrames = 0; - tmp[3] = (BYTE)iHours; - tmp[4] = (BYTE)iMins; - tmp[5] = (BYTE)iSecs; - tmp[6] = (BYTE)iFrames; - tmp[7] = (BYTE)iFFrames; - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + tmp[3] = (BYTE) iHours; + tmp[4] = (BYTE) iMins; + tmp[5] = (BYTE) iSecs; + tmp[6] = (BYTE) iFrames; + tmp[7] = (BYTE) iFFrames; + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } -BOOL midiSongAddSimpleTimeSig(MIDI_FILE *_pMF, int iTrack, int iNom, int iDenom) +BOOL midiSongAddSimpleTimeSig(MIDI_FILE *_pMF, int iTrack, int iNom, + int iDenom) { - return midiSongAddTimeSig(_pMF, iTrack, iNom, iDenom, 24, 8); + return midiSongAddTimeSig(_pMF, iTrack, iNom, iDenom, 24, 8); } -BOOL midiSongAddTimeSig(MIDI_FILE *_pMF, int iTrack, int iNom, int iDenom, int iClockInMetroTick, int iNotated32nds) +BOOL midiSongAddTimeSig(MIDI_FILE *_pMF, int iTrack, int iNom, int iDenom, + int iClockInMetroTick, int iNotated32nds) { -static BYTE tmp[] = {msgMetaEvent, metaTimeSig, 0x04, 0,0,0,0}; + static BYTE tmp[] = { msgMetaEvent, metaTimeSig, 0x04, 0, 0, 0, 0 }; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - tmp[3] = (BYTE)iNom; - tmp[4] = (BYTE)(MIDI_NOTE_MINIM/iDenom); - tmp[5] = (BYTE)iClockInMetroTick; - tmp[6] = (BYTE)iNotated32nds; - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + tmp[3] = (BYTE) iNom; + tmp[4] = (BYTE) (MIDI_NOTE_MINIM / iDenom); + tmp[5] = (BYTE) iClockInMetroTick; + tmp[6] = (BYTE) iNotated32nds; + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } -BOOL midiSongAddKeySig(MIDI_FILE *_pMF, int iTrack, tMIDI_KEYSIG iKey) +BOOL midiSongAddKeySig(MIDI_FILE *_pMF, int iTrack, tMIDI_KEYSIG iKey) { -static BYTE tmp[] = {msgMetaEvent, metaKeySig, 0x02, 0, 0}; + static BYTE tmp[] = { msgMetaEvent, metaKeySig, 0x02, 0, 0 }; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - tmp[3] = (BYTE)((iKey&keyMaskKey)*((iKey&keyMaskNeg)?-1:1)); - tmp[4] = (BYTE)((iKey&keyMaskMin)?1:0); - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + tmp[3] = (BYTE) ((iKey & keyMaskKey) * ((iKey & keyMaskNeg) ? -1 : 1)); + tmp[4] = (BYTE) ((iKey & keyMaskMin) ? 1 : 0); + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } -BOOL midiSongAddTempo(MIDI_FILE *_pMF, int iTrack, int iTempo) +BOOL midiSongAddTempo(MIDI_FILE *_pMF, int iTrack, int iTempo) { -static BYTE tmp[] = {msgMetaEvent, metaSetTempo, 0x03, 0,0,0}; -int us; /* micro-seconds per qn */ + static BYTE tmp[] = { msgMetaEvent, metaSetTempo, 0x03, 0, 0, 0 }; + int us; /* micro-seconds per qn */ - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - us = 60000000L/iTempo; - tmp[3] = (BYTE)((us>>16)&0xff); - tmp[4] = (BYTE)((us>>8)&0xff); - tmp[5] = (BYTE)((us>>0)&0xff); - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + us = 60000000L / iTempo; + tmp[3] = (BYTE) ((us >> 16) & 0xff); + tmp[4] = (BYTE) ((us >> 8) & 0xff); + tmp[5] = (BYTE) ((us >> 0) & 0xff); + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } -BOOL midiSongAddMIDIPort(MIDI_FILE *_pMF, int iTrack, int iPort) +BOOL midiSongAddMIDIPort(MIDI_FILE *_pMF, int iTrack, int iPort) { -static BYTE tmp[] = {msgMetaEvent, metaMIDIPort, 1, 0}; + static BYTE tmp[] = { msgMetaEvent, metaMIDIPort, 1, 0 }; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; - tmp[3] = (BYTE)iPort; - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; + tmp[3] = (BYTE) iPort; + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } -BOOL midiSongAddEndSequence(MIDI_FILE *_pMF, int iTrack) +BOOL midiSongAddEndSequence(MIDI_FILE *_pMF, int iTrack) { -static BYTE tmp[] = {msgMetaEvent, metaEndSequence, 0}; + static BYTE tmp[] = { msgMetaEvent, metaEndSequence, 0 }; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); + return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } /* ** midiTrack* Functions */ -BOOL midiTrackAddRaw(MIDI_FILE *_pMF, int iTrack, int data_sz, const BYTE *pData, BOOL bMovePtr, int dt) +BOOL midiTrackAddRaw(MIDI_FILE *_pMF, int iTrack, int data_sz, + const BYTE * pData, BOOL bMovePtr, int dt) { -MIDI_FILE_TRACK *pTrk; -BYTE *ptr; -int dtime; + MIDI_FILE_TRACK *pTrk; + BYTE *ptr; + int dtime; + + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; - - pTrk = &pMF->Track[iTrack]; - ptr = _midiGetPtr(pMF, iTrack, data_sz+DT_DEF); - if (!ptr) - return FALSE; - - dtime = pTrk->dt; - if (bMovePtr) - dtime += dt; - - ptr = _midiWriteVarLen(ptr, dtime); - memcpy(ptr, pData, data_sz); - - pTrk->pos += dtime; - pTrk->dt = 0; - pTrk->ptr = ptr+data_sz; - - return TRUE; + pTrk = &pMF->Track[iTrack]; + ptr = _midiGetPtr(pMF, iTrack, data_sz + DT_DEF); + if (!ptr) + return FALSE; + + dtime = pTrk->dt; + if (bMovePtr) + dtime += dt; + + ptr = _midiWriteVarLen(ptr, dtime); + memcpy(ptr, pData, data_sz); + + pTrk->pos += dtime; + pTrk->dt = 0; + pTrk->ptr = ptr + data_sz; + + return TRUE; } -BOOL midiTrackIncTime(MIDI_FILE *_pMF, int iTrack, int iDeltaTime, BOOL bOverridePPQN) +BOOL midiTrackIncTime(MIDI_FILE *_pMF, int iTrack, int iDeltaTime, + BOOL bOverridePPQN) { -DWORD will_end_at; + DWORD will_end_at; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; - - will_end_at = _midiGetLength(pMF->Header.PPQN, iDeltaTime, bOverridePPQN); - will_end_at += pMF->Track[iTrack].pos + pMF->Track[iTrack].dt; - - midiFileFlushTrack(pMF, iTrack, FALSE, will_end_at); - - return TRUE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; + + will_end_at = _midiGetLength(pMF->Header.PPQN, iDeltaTime, bOverridePPQN); + will_end_at += pMF->Track[iTrack].pos + pMF->Track[iTrack].dt; + + midiFileFlushTrack(pMF, iTrack, FALSE, will_end_at); + + return TRUE; } -BOOL midiTrackAddText(MIDI_FILE *_pMF, int iTrack, tMIDI_TEXT iType, const char *pTxt) +BOOL midiTrackAddText(MIDI_FILE *_pMF, int iTrack, tMIDI_TEXT iType, + const char *pTxt) { -BYTE *ptr; -int sz; + BYTE *ptr; + int sz; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - sz = strlen(pTxt); - if ((ptr = _midiGetPtr(pMF, iTrack, sz+DT_DEF))) - { - *ptr++ = 0; /* delta-time=0 */ - *ptr++ = msgMetaEvent; - *ptr++ = (BYTE)iType; - ptr = _midiWriteVarLen((BYTE *)ptr, sz); - strcpy((char *)ptr, pTxt); - pMF->Track[iTrack].ptr = ptr+sz; - return TRUE; - } - else - { - return FALSE; - } + sz = strlen(pTxt); + if ((ptr = _midiGetPtr(pMF, iTrack, sz + DT_DEF))) + { + *ptr++ = 0; /* delta-time=0 */ + *ptr++ = msgMetaEvent; + *ptr++ = (BYTE) iType; + ptr = _midiWriteVarLen((BYTE *) ptr, sz); + strcpy((char *) ptr, pTxt); + pMF->Track[iTrack].ptr = ptr + sz; + return TRUE; + } + else + { + return FALSE; + } } -BOOL midiTrackSetKeyPressure(MIDI_FILE *pMF, int iTrack, int iNote, int iAftertouch) +BOOL midiTrackSetKeyPressure(MIDI_FILE *pMF, int iTrack, int iNote, + int iAftertouch) { - return midiTrackAddMsg(pMF, iTrack, msgNoteKeyPressure, iNote, iAftertouch); + return midiTrackAddMsg(pMF, iTrack, msgNoteKeyPressure, iNote, + iAftertouch); } -BOOL midiTrackAddControlChange(MIDI_FILE *pMF, int iTrack, tMIDI_CC iCCType, int iParam) +BOOL midiTrackAddControlChange(MIDI_FILE *pMF, int iTrack, tMIDI_CC iCCType, + int iParam) { - return midiTrackAddMsg(pMF, iTrack, msgControlChange, iCCType, iParam); + return midiTrackAddMsg(pMF, iTrack, msgControlChange, iCCType, iParam); } -BOOL midiTrackAddProgramChange(MIDI_FILE *pMF, int iTrack, int iInstrPatch) +BOOL midiTrackAddProgramChange(MIDI_FILE *pMF, int iTrack, int iInstrPatch) { - return midiTrackAddMsg(pMF, iTrack, msgSetProgram, iInstrPatch, 0); + return midiTrackAddMsg(pMF, iTrack, msgSetProgram, iInstrPatch, 0); } -BOOL midiTrackChangeKeyPressure(MIDI_FILE *pMF, int iTrack, int iDeltaPressure) +BOOL midiTrackChangeKeyPressure(MIDI_FILE *pMF, int iTrack, + int iDeltaPressure) { - return midiTrackAddMsg(pMF, iTrack, msgChangePressure, iDeltaPressure&0x7f, 0); + return midiTrackAddMsg(pMF, iTrack, msgChangePressure, + iDeltaPressure & 0x7f, 0); } -BOOL midiTrackSetPitchWheel(MIDI_FILE *pMF, int iTrack, int iWheelPos) +BOOL midiTrackSetPitchWheel(MIDI_FILE *pMF, int iTrack, int iWheelPos) { -WORD wheel = (WORD)iWheelPos; + WORD wheel = (WORD) iWheelPos; - /* bitshift 7 instead of eight because we're dealing with 7 bit numbers */ - wheel += MIDI_WHEEL_CENTRE; - return midiTrackAddMsg(pMF, iTrack, msgSetPitchWheel, wheel&0x7f, (wheel>>7)&0x7f); + /* bitshift 7 instead of eight because we're dealing with 7 bit numbers */ + wheel += MIDI_WHEEL_CENTRE; + return midiTrackAddMsg(pMF, iTrack, msgSetPitchWheel, wheel & 0x7f, + (wheel >> 7) & 0x7f); } -BOOL midiTrackAddMsg(MIDI_FILE *_pMF, int iTrack, tMIDI_MSG iMsg, int iParam1, int iParam2) +BOOL midiTrackAddMsg(MIDI_FILE *_pMF, int iTrack, tMIDI_MSG iMsg, + int iParam1, int iParam2) { -BYTE *ptr; -BYTE data[3]; -int sz; + BYTE *ptr; + BYTE data[3]; + int sz; - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; - if (!IsMessageValid(iMsg)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; + if (!IsMessageValid(iMsg)) + return FALSE; + + ptr = _midiGetPtr(pMF, iTrack, DT_DEF); + if (!ptr) + return FALSE; - ptr = _midiGetPtr(pMF, iTrack, DT_DEF); - if (!ptr) - return FALSE; - - data[0] = (BYTE)(iMsg | pMF->Track[iTrack].iDefaultChannel); - data[1] = (BYTE)(iParam1 & 0x7f); - data[2] = (BYTE)(iParam2 & 0x7f); - /* - ** Is this msg a single, or double BYTE, prm? - */ - switch(iMsg) - { - case msgSetProgram: /* only one byte required for these msgs */ - case msgChangePressure: - sz = 2; - break; + data[0] = (BYTE) (iMsg | pMF->Track[iTrack].iDefaultChannel); + data[1] = (BYTE) (iParam1 & 0x7f); + data[2] = (BYTE) (iParam2 & 0x7f); + /* + ** Is this msg a single, or double BYTE, prm? + */ + switch (iMsg) + { + case msgSetProgram: /* only one byte required for these msgs */ + case msgChangePressure: + sz = 2; + break; - default: /* double byte messages */ - sz = 3; - break; - } - - return midiTrackAddRaw(pMF, iTrack, sz, data, FALSE, 0); + default: /* double byte messages */ + sz = 3; + break; + } + + return midiTrackAddRaw(pMF, iTrack, sz, data, FALSE, 0); } -BOOL midiTrackAddNote(MIDI_FILE *_pMF, int iTrack, int iNote, int iLength, int iVol, BOOL bAutoInc, BOOL bOverrideLength) +BOOL midiTrackAddNote(MIDI_FILE *_pMF, int iTrack, int iNote, int iLength, + int iVol, BOOL bAutoInc, BOOL bOverrideLength) { -MIDI_FILE_TRACK *pTrk; -BYTE *ptr; -BOOL bSuccess = FALSE; -int i, chn; + MIDI_FILE_TRACK *pTrk; + BYTE *ptr; + BOOL bSuccess = FALSE; + int i, chn; + + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; + if (!IsNoteValid(iNote)) + return FALSE; + + pTrk = &pMF->Track[iTrack]; + ptr = _midiGetPtr(pMF, iTrack, DT_DEF); + if (!ptr) + return FALSE; + + chn = pTrk->iDefaultChannel; + iLength = _midiGetLength(pMF->Header.PPQN, iLength, bOverrideLength); - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; - if (!IsNoteValid(iNote)) return FALSE; - - pTrk = &pMF->Track[iTrack]; - ptr = _midiGetPtr(pMF, iTrack, DT_DEF); - if (!ptr) - return FALSE; - - chn = pTrk->iDefaultChannel; - iLength = _midiGetLength(pMF->Header.PPQN, iLength, bOverrideLength); - - for(i=0;iLastNote)/sizeof(pTrk->LastNote[0]);++i) - if (pTrk->LastNote[i].valid == FALSE) - { - pTrk->LastNote[i].note = (BYTE)iNote; - pTrk->LastNote[i].chn = (BYTE)chn; - pTrk->LastNote[i].end_pos = pTrk->pos+pTrk->dt+iLength; - pTrk->LastNote[i].valid = TRUE; - bSuccess = TRUE; - - ptr = _midiWriteVarLen(ptr, pTrk->dt); /* delta-time */ - *ptr++ = (BYTE)(msgNoteOn | chn); - *ptr++ = (BYTE)iNote; - *ptr++ = (BYTE)iVol; - break; - } - - if (!bSuccess) - return FALSE; - - pTrk->ptr = ptr; - - pTrk->pos += pTrk->dt; - pTrk->dt = 0; - - if (bAutoInc) - return midiTrackIncTime(pMF, iTrack, iLength, bOverrideLength); - - return TRUE; + for (i = 0; i < sizeof(pTrk->LastNote) / sizeof(pTrk->LastNote[0]); ++i) + if (pTrk->LastNote[i].valid == FALSE) + { + pTrk->LastNote[i].note = (BYTE) iNote; + pTrk->LastNote[i].chn = (BYTE) chn; + pTrk->LastNote[i].end_pos = pTrk->pos + pTrk->dt + iLength; + pTrk->LastNote[i].valid = TRUE; + bSuccess = TRUE; + + ptr = _midiWriteVarLen(ptr, pTrk->dt); /* delta-time */ + *ptr++ = (BYTE) (msgNoteOn | chn); + *ptr++ = (BYTE) iNote; + *ptr++ = (BYTE) iVol; + break; + } + + if (!bSuccess) + return FALSE; + + pTrk->ptr = ptr; + + pTrk->pos += pTrk->dt; + pTrk->dt = 0; + + if (bAutoInc) + return midiTrackIncTime(pMF, iTrack, iLength, bOverrideLength); + + return TRUE; } -BOOL midiTrackAddRest(MIDI_FILE *_pMF, int iTrack, int iLength, BOOL bOverridePPQN) +BOOL midiTrackAddRest(MIDI_FILE *_pMF, int iTrack, int iLength, + BOOL bOverridePPQN) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - iLength = _midiGetLength(pMF->Header.PPQN, iLength, bOverridePPQN); - return midiTrackIncTime(pMF, iTrack, iLength, bOverridePPQN); + iLength = _midiGetLength(pMF->Header.PPQN, iLength, bOverridePPQN); + return midiTrackIncTime(pMF, iTrack, iLength, bOverridePPQN); } -int midiTrackGetEndPos(MIDI_FILE *_pMF, int iTrack) +int midiTrackGetEndPos(MIDI_FILE *_pMF, int iTrack) { - _VAR_CAST; - if (!IsFilePtrValid(pMF)) return FALSE; - if (!IsTrackValid(iTrack)) return FALSE; + _VAR_CAST; + if (!IsFilePtrValid(pMF)) + return FALSE; + if (!IsTrackValid(iTrack)) + return FALSE; - return pMF->Track[iTrack].pos; + return pMF->Track[iTrack].pos; } /* ** midiRead* Functions */ -static BYTE *_midiReadVarLen(BYTE *ptr, DWORD *num) +static BYTE *_midiReadVarLen(BYTE * ptr, DWORD * num) { -register DWORD value; -register BYTE c; + register DWORD value; + register BYTE c; if ((value = *ptr++) & 0x80) - { - value &= 0x7f; - do - { - value = (value << 7) + ((c = *ptr++) & 0x7f); - } while (c & 0x80); - } - *num = value; - return(ptr); + { + value &= 0x7f; + do + { + value = (value << 7) + ((c = *ptr++) & 0x7f); + } + while (c & 0x80); + } + *num = value; + return (ptr); } -static BOOL _midiReadTrackCopyData(MIDI_MSG *pMsg, BYTE *ptr, DWORD sz, BOOL bCopyPtrData) +static BOOL _midiReadTrackCopyData(MIDI_MSG * pMsg, BYTE * ptr, DWORD sz, + BOOL bCopyPtrData) { - if (sz > pMsg->data_sz) - { - pMsg->data = (BYTE *)realloc(pMsg->data, sz); - pMsg->data_sz = sz; - } - - if (!pMsg->data) - return FALSE; - - if (bCopyPtrData && ptr) - memcpy(pMsg->data, ptr, sz); - - return TRUE; + if (sz > pMsg->data_sz) + { + pMsg->data = (BYTE *) realloc(pMsg->data, sz); + pMsg->data_sz = sz; + } + + if (!pMsg->data) + return FALSE; + + if (bCopyPtrData && ptr) + memcpy(pMsg->data, ptr, sz); + + return TRUE; } int midiReadGetNumTracks(const MIDI_FILE *_pMF) { - _VAR_CAST; - return pMF->Header.iNumTracks; + _VAR_CAST; + return pMF->Header.iNumTracks; } -BOOL midiReadGetNextMessage(const MIDI_FILE *_pMF, int iTrack, MIDI_MSG *pMsg) +BOOL midiReadGetNextMessage(const MIDI_FILE *_pMF, int iTrack, + MIDI_MSG * pMsg) { -MIDI_FILE_TRACK *pTrack; -BYTE *bptr, *pMsgDataPtr; -int sz; + MIDI_FILE_TRACK *pTrack; + BYTE *bptr, *pMsgDataPtr; + int sz; - _VAR_CAST; - if (!IsTrackValid(iTrack)) return FALSE; - - pTrack = &pMF->Track[iTrack]; - /* FIXME: Check if there is data on this track first!!! */ - if (pTrack->ptr >= pTrack->pEnd) - return FALSE; - - pTrack->ptr = _midiReadVarLen(pTrack->ptr, &pMsg->dt); - pTrack->pos += pMsg->dt; + _VAR_CAST; + if (!IsTrackValid(iTrack)) + return FALSE; - pMsg->dwAbsPos = pTrack->pos; + pTrack = &pMF->Track[iTrack]; + /* FIXME: Check if there is data on this track first!!! */ + if (pTrack->ptr >= pTrack->pEnd) + return FALSE; + + pTrack->ptr = _midiReadVarLen(pTrack->ptr, &pMsg->dt); + pTrack->pos += pMsg->dt; + + pMsg->dwAbsPos = pTrack->pos; - if (*pTrack->ptr & 0x80) /* Is this is sys message */ - { - pMsg->iType = (tMIDI_MSG)((*pTrack->ptr) & 0xf0); - pMsgDataPtr = pTrack->ptr+1; + if (*pTrack->ptr & 0x80) /* Is this is sys message */ + { + pMsg->iType = (tMIDI_MSG) ((*pTrack->ptr) & 0xf0); + pMsgDataPtr = pTrack->ptr + 1; - /* SysEx & Meta events don't carry channel info, but something - ** important in their lower bits that we must keep */ - if (pMsg->iType == 0xf0) - pMsg->iType = (tMIDI_MSG)(*pTrack->ptr); - } - else /* just data - so use the last msg type */ - { - pMsg->iType = pMsg->iLastMsgType; - pMsgDataPtr = pTrack->ptr; - } - - pMsg->iLastMsgType = (tMIDI_MSG)pMsg->iType; - pMsg->iLastMsgChnl = (BYTE)((*pTrack->ptr) & 0x0f)+1; + /* SysEx & Meta events don't carry channel info, but something + ** important in their lower bits that we must keep */ + if (pMsg->iType == 0xf0) + pMsg->iType = (tMIDI_MSG) (*pTrack->ptr); + } + else /* just data - so use the last msg type */ + { + pMsg->iType = pMsg->iLastMsgType; + pMsgDataPtr = pTrack->ptr; + } - switch(pMsg->iType) - { - case msgNoteOn: - pMsg->MsgData.NoteOn.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.NoteOn.iNote = *(pMsgDataPtr); - pMsg->MsgData.NoteOn.iVolume = *(pMsgDataPtr+1); - pMsg->iMsgSize = 3; - break; + pMsg->iLastMsgType = (tMIDI_MSG) pMsg->iType; + pMsg->iLastMsgChnl = (BYTE) ((*pTrack->ptr) & 0x0f) + 1; + + switch (pMsg->iType) + { + case msgNoteOn: + pMsg->MsgData.NoteOn.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.NoteOn.iNote = *(pMsgDataPtr); + pMsg->MsgData.NoteOn.iVolume = *(pMsgDataPtr + 1); + pMsg->iMsgSize = 3; + break; - case msgNoteOff: - pMsg->MsgData.NoteOff.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.NoteOff.iNote = *(pMsgDataPtr); - pMsg->iMsgSize = 3; - break; + case msgNoteOff: + pMsg->MsgData.NoteOff.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.NoteOff.iNote = *(pMsgDataPtr); + pMsg->iMsgSize = 3; + break; - case msgNoteKeyPressure: - pMsg->MsgData.NoteKeyPressure.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.NoteKeyPressure.iNote = *(pMsgDataPtr); - pMsg->MsgData.NoteKeyPressure.iPressure = *(pMsgDataPtr+1); - pMsg->iMsgSize = 3; - break; + case msgNoteKeyPressure: + pMsg->MsgData.NoteKeyPressure.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.NoteKeyPressure.iNote = *(pMsgDataPtr); + pMsg->MsgData.NoteKeyPressure.iPressure = *(pMsgDataPtr + 1); + pMsg->iMsgSize = 3; + break; - case msgSetParameter: - pMsg->MsgData.NoteParameter.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.NoteParameter.iControl = (tMIDI_CC)*(pMsgDataPtr); - pMsg->MsgData.NoteParameter.iParam = *(pMsgDataPtr+1); - pMsg->iMsgSize = 3; - break; + case msgSetParameter: + pMsg->MsgData.NoteParameter.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.NoteParameter.iControl = (tMIDI_CC) * (pMsgDataPtr); + pMsg->MsgData.NoteParameter.iParam = *(pMsgDataPtr + 1); + pMsg->iMsgSize = 3; + break; - case msgSetProgram: - pMsg->MsgData.ChangeProgram.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.ChangeProgram.iProgram = *(pMsgDataPtr); - pMsg->iMsgSize = 2; - break; + case msgSetProgram: + pMsg->MsgData.ChangeProgram.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.ChangeProgram.iProgram = *(pMsgDataPtr); + pMsg->iMsgSize = 2; + break; - case msgChangePressure: - pMsg->MsgData.ChangePressure.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.ChangePressure.iPressure = *(pMsgDataPtr); - pMsg->iMsgSize = 2; - break; + case msgChangePressure: + pMsg->MsgData.ChangePressure.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.ChangePressure.iPressure = *(pMsgDataPtr); + pMsg->iMsgSize = 2; + break; - case msgSetPitchWheel: - pMsg->MsgData.PitchWheel.iChannel = pMsg->iLastMsgChnl; - pMsg->MsgData.PitchWheel.iPitch = *(pMsgDataPtr) | (*(pMsgDataPtr+1) << 7); - pMsg->MsgData.PitchWheel.iPitch -= MIDI_WHEEL_CENTRE; - pMsg->iMsgSize = 3; - break; + case msgSetPitchWheel: + pMsg->MsgData.PitchWheel.iChannel = pMsg->iLastMsgChnl; + pMsg->MsgData.PitchWheel.iPitch = + *(pMsgDataPtr) | (*(pMsgDataPtr + 1) << 7); + pMsg->MsgData.PitchWheel.iPitch -= MIDI_WHEEL_CENTRE; + pMsg->iMsgSize = 3; + break; - case msgMetaEvent: - /* We can use 'pTrack->ptr' from now on, since meta events - ** always have bit 7 set */ - bptr = pTrack->ptr; - pMsg->MsgData.MetaEvent.iType = (tMIDI_META)*(pTrack->ptr+1); - pTrack->ptr = _midiReadVarLen(pTrack->ptr+2, &pMsg->iMsgSize); - sz = (pTrack->ptr-bptr)+pMsg->iMsgSize; - - if (_midiReadTrackCopyData(pMsg, pTrack->ptr, sz, FALSE) == FALSE) - return FALSE; + case msgMetaEvent: + /* We can use 'pTrack->ptr' from now on, since meta events + ** always have bit 7 set */ + bptr = pTrack->ptr; + pMsg->MsgData.MetaEvent.iType = (tMIDI_META) * (pTrack->ptr + 1); + pTrack->ptr = _midiReadVarLen(pTrack->ptr + 2, &pMsg->iMsgSize); + sz = (pTrack->ptr - bptr) + pMsg->iMsgSize; - /* Now copy the data...*/ - memcpy(pMsg->data, bptr, sz); + if (_midiReadTrackCopyData(pMsg, pTrack->ptr, sz, FALSE) == FALSE) + return FALSE; + + /* Now copy the data... */ + memcpy(pMsg->data, bptr, sz); - /* Now place it in a neat structure */ - switch(pMsg->MsgData.MetaEvent.iType) - { - case metaMIDIPort: - pMsg->MsgData.MetaEvent.Data.iMIDIPort = *(pTrack->ptr+0); - break; - case metaSequenceNumber: - pMsg->MsgData.MetaEvent.Data.iSequenceNumber = *(pTrack->ptr+0); - break; - case metaTextEvent: - case metaCopyright: - case metaTrackName: - case metaInstrument: - case metaLyric: - case metaMarker: - case metaCuePoint: - /* TODO - Add NULL terminator ??? */ - pMsg->MsgData.MetaEvent.Data.Text.pData = pTrack->ptr; - break; - case metaEndSequence: - /* NO DATA */ - break; - case metaSetTempo: - { - DWORD us = ((*(pTrack->ptr+0))<<16)|((*(pTrack->ptr+1))<<8)|(*(pTrack->ptr+2)); - pMsg->MsgData.MetaEvent.Data.Tempo.iBPM = 60000000L/us; - } - break; - case metaSMPTEOffset: - pMsg->MsgData.MetaEvent.Data.SMPTE.iHours = *(pTrack->ptr+0); - pMsg->MsgData.MetaEvent.Data.SMPTE.iMins= *(pTrack->ptr+1); - pMsg->MsgData.MetaEvent.Data.SMPTE.iSecs = *(pTrack->ptr+2); - pMsg->MsgData.MetaEvent.Data.SMPTE.iFrames = *(pTrack->ptr+3); - pMsg->MsgData.MetaEvent.Data.SMPTE.iFF = *(pTrack->ptr+4); - break; - case metaTimeSig: - pMsg->MsgData.MetaEvent.Data.TimeSig.iNom = *(pTrack->ptr+0); - pMsg->MsgData.MetaEvent.Data.TimeSig.iDenom = *(pTrack->ptr+1) * MIDI_NOTE_MINIM; - /* TODO: Variations without 24 & 8 */ - break; - case metaKeySig: - if (*pTrack->ptr & 0x80) - { - /* Do some trendy sign extending in reverse :) */ - pMsg->MsgData.MetaEvent.Data.KeySig.iKey = ((256-*pTrack->ptr)&keyMaskKey); - pMsg->MsgData.MetaEvent.Data.KeySig.iKey |= keyMaskNeg; - } - else - { - pMsg->MsgData.MetaEvent.Data.KeySig.iKey = (tMIDI_KEYSIG)(*pTrack->ptr&keyMaskKey); - } - if (*(pTrack->ptr+1)) - pMsg->MsgData.MetaEvent.Data.KeySig.iKey |= keyMaskMin; - break; - case metaSequencerSpecific: - pMsg->MsgData.MetaEvent.Data.Sequencer.iSize = pMsg->iMsgSize; - pMsg->MsgData.MetaEvent.Data.Sequencer.pData = pTrack->ptr; - break; - } + /* Now place it in a neat structure */ + switch (pMsg->MsgData.MetaEvent.iType) + { + case metaMIDIPort: + pMsg->MsgData.MetaEvent.Data.iMIDIPort = *(pTrack->ptr + 0); + break; + case metaSequenceNumber: + pMsg->MsgData.MetaEvent.Data.iSequenceNumber = *(pTrack->ptr + 0); + break; + case metaTextEvent: + case metaCopyright: + case metaTrackName: + case metaInstrument: + case metaLyric: + case metaMarker: + case metaCuePoint: + /* TODO - Add NULL terminator ??? */ + pMsg->MsgData.MetaEvent.Data.Text.pData = pTrack->ptr; + break; + case metaEndSequence: + /* NO DATA */ + break; + case metaSetTempo: + { + DWORD us = + ((*(pTrack->ptr + 0)) << 16) | ((*(pTrack->ptr + 1)) << 8) + | (*(pTrack->ptr + 2)); + pMsg->MsgData.MetaEvent.Data.Tempo.iBPM = 60000000L / us; + } + break; + case metaSMPTEOffset: + pMsg->MsgData.MetaEvent.Data.SMPTE.iHours = *(pTrack->ptr + 0); + pMsg->MsgData.MetaEvent.Data.SMPTE.iMins = *(pTrack->ptr + 1); + pMsg->MsgData.MetaEvent.Data.SMPTE.iSecs = *(pTrack->ptr + 2); + pMsg->MsgData.MetaEvent.Data.SMPTE.iFrames = *(pTrack->ptr + 3); + pMsg->MsgData.MetaEvent.Data.SMPTE.iFF = *(pTrack->ptr + 4); + break; + case metaTimeSig: + pMsg->MsgData.MetaEvent.Data.TimeSig.iNom = *(pTrack->ptr + 0); + pMsg->MsgData.MetaEvent.Data.TimeSig.iDenom = + *(pTrack->ptr + 1) * MIDI_NOTE_MINIM; + /* TODO: Variations without 24 & 8 */ + break; + case metaKeySig: + if (*pTrack->ptr & 0x80) + { + /* Do some trendy sign extending in reverse :) */ + pMsg->MsgData.MetaEvent.Data.KeySig.iKey = + ((256 - *pTrack->ptr) & keyMaskKey); + pMsg->MsgData.MetaEvent.Data.KeySig.iKey |= keyMaskNeg; + } + else + { + pMsg->MsgData.MetaEvent.Data.KeySig.iKey = + (tMIDI_KEYSIG) (*pTrack->ptr & keyMaskKey); + } + if (*(pTrack->ptr + 1)) + pMsg->MsgData.MetaEvent.Data.KeySig.iKey |= keyMaskMin; + break; + case metaSequencerSpecific: + pMsg->MsgData.MetaEvent.Data.Sequencer.iSize = pMsg->iMsgSize; + pMsg->MsgData.MetaEvent.Data.Sequencer.pData = pTrack->ptr; + break; + } - pTrack->ptr += pMsg->iMsgSize; - pMsg->iMsgSize = sz; - break; + pTrack->ptr += pMsg->iMsgSize; + pMsg->iMsgSize = sz; + break; - case msgSysEx1: - case msgSysEx2: - bptr = pTrack->ptr; - pTrack->ptr = _midiReadVarLen(pTrack->ptr+1, &pMsg->iMsgSize); - sz = (pTrack->ptr-bptr)+pMsg->iMsgSize; - - if (_midiReadTrackCopyData(pMsg, pTrack->ptr, sz, FALSE) == FALSE) - return FALSE; + case msgSysEx1: + case msgSysEx2: + bptr = pTrack->ptr; + pTrack->ptr = _midiReadVarLen(pTrack->ptr + 1, &pMsg->iMsgSize); + sz = (pTrack->ptr - bptr) + pMsg->iMsgSize; + + if (_midiReadTrackCopyData(pMsg, pTrack->ptr, sz, FALSE) == FALSE) + return FALSE; - /* Now copy the data... */ - memcpy(pMsg->data, bptr, sz); - pTrack->ptr += pMsg->iMsgSize; - pMsg->iMsgSize = sz; - pMsg->MsgData.SysEx.pData = pMsg->data; - pMsg->MsgData.SysEx.iSize = sz; - break; - } - /* - ** Standard MIDI messages use a common copy routine - */ - pMsg->bImpliedMsg = FALSE; - if ((pMsg->iType&0xf0) != 0xf0) - { - if (*pTrack->ptr & 0x80) - { - } - else - { - pMsg->bImpliedMsg = TRUE; - pMsg->iImpliedMsg = pMsg->iLastMsgType; - pMsg->iMsgSize--; - } - _midiReadTrackCopyData(pMsg, pTrack->ptr, pMsg->iMsgSize, TRUE); - pTrack->ptr+=pMsg->iMsgSize; - } - return TRUE; + /* Now copy the data... */ + memcpy(pMsg->data, bptr, sz); + pTrack->ptr += pMsg->iMsgSize; + pMsg->iMsgSize = sz; + pMsg->MsgData.SysEx.pData = pMsg->data; + pMsg->MsgData.SysEx.iSize = sz; + break; + } + /* + ** Standard MIDI messages use a common copy routine + */ + pMsg->bImpliedMsg = FALSE; + if ((pMsg->iType & 0xf0) != 0xf0) + { + if (*pTrack->ptr & 0x80) + { + } + else + { + pMsg->bImpliedMsg = TRUE; + pMsg->iImpliedMsg = pMsg->iLastMsgType; + pMsg->iMsgSize--; + } + _midiReadTrackCopyData(pMsg, pTrack->ptr, pMsg->iMsgSize, TRUE); + pTrack->ptr += pMsg->iMsgSize; + } + return TRUE; } -void midiReadInitMessage(MIDI_MSG *pMsg) +void midiReadInitMessage(MIDI_MSG * pMsg) { - pMsg->data = NULL; - pMsg->data_sz = 0; - pMsg->bImpliedMsg = FALSE; + pMsg->data = NULL; + pMsg->data_sz = 0; + pMsg->bImpliedMsg = FALSE; } -void midiReadFreeMessage(MIDI_MSG *pMsg) +void midiReadFreeMessage(MIDI_MSG * pMsg) { - if (pMsg->data) free((void *)pMsg->data); - pMsg->data = NULL; + if (pMsg->data) + free((void *) pMsg->data); + pMsg->data = NULL; }