# HG changeset patch # User Matti Hamalainen # Date 1375725080 -10800 # Node ID a14cc6c5d7ef3021ded10a194a468b58f22ebc5f # Parent de2ee75a142f718ec0edeba40c259a2f10bbfcdd Possibly fix 64-bit issues. Probably not. diff -r de2ee75a142f -r a14cc6c5d7ef src/midifile.c --- a/src/midifile.c Mon Aug 05 20:26:11 2013 +0300 +++ b/src/midifile.c Mon Aug 05 20:51:20 2013 +0300 @@ -24,45 +24,48 @@ #include #include #include +#include #ifndef __APPLE__ #include #endif #include "midifile.h" +#include "mendian.h" + /* ** Internal Data Structures */ typedef struct { - BYTE note, chn; - BYTE valid, p2; - DWORD end_pos; + Uint8 note, chn; + Uint8 valid, p2; + Uint32 end_pos; } MIDI_LAST_NOTE; typedef struct { - BYTE *ptr; - BYTE *pBase; - BYTE *pEnd; + Uint8 *ptr; + Uint8 *pBase; + Uint8 *pEnd; - DWORD pos; - DWORD dt; + Uint32 pos; + Uint32 dt; /* For Reading MIDI Files */ - DWORD sz; /* size of whole iTrack */ + Uint32 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 */ + Uint32 iBlockSize; /* max size of track */ + Uint8 iDefaultChannel; /* use for write only */ + Uint8 last_status; /* used for running status */ 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 */ + Uint32 iHeaderSize; + /**/ Uint16 iVersion; /* 0, 1 or 2 */ + Uint16 iNumTracks; /* number of tracks... (will be 1 for MIDI type 0) */ + Uint16 PPQN; /* pulses per quarter note */ } MIDI_HEADER; typedef struct @@ -71,8 +74,9 @@ BOOL bOpenForWriting; MIDI_HEADER Header; - BYTE *ptr; /* to whole data block */ - DWORD file_sz; + + Uint8 *ptr, *curr, *end; + size_t file_size; MIDI_FILE_TRACK Track[MAX_MIDI_TRACKS]; } _MIDI_FILE; @@ -82,10 +86,7 @@ ** Internal Functions */ #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)) - -#define _VAR_CAST _MIDI_FILE *pMF = (_MIDI_FILE *)_pMF +#define _VAR_CAST _MIDI_FILE *pMF = (_MIDI_FILE *)_pMF #define IsFilePtrValid(pMF) (pMF) #define IsTrackValid(_x) (_midiValidateTrack(pMF, _x)) #define IsChannelValid(_x) ((_x)>=1 && (_x)<=16) @@ -93,12 +94,128 @@ #define IsMessageValid(_x) ((_x)>=msgNoteOff && (_x)<=msgMetaEvent) +static void midiErrorV(_MIDI_FILE *pMF, const char *fmt, va_list ap) +{ + printf("MIDI: "); + vprintf(fmt, ap); +} + + +static void midiError(_MIDI_FILE *pMF, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + midiErrorV(pMF, fmt, ap); + va_end(ap); +} + + +static int midiStrNCmp(_MIDI_FILE *pMF, const char *str, const size_t n) +{ + if (pMF->curr + n < pMF->end) + { + int res = strncmp((char *) pMF->curr, str, n); + pMF->curr += n; + return res; + } + else + return 1; +} + + +static BOOL midiSkip(_MIDI_FILE *pMF, const size_t n) +{ + pMF->curr += n; + return (pMF->curr < pMF->end); +} + + +static BOOL midiGetBE32(_MIDI_FILE *pMF, Uint32 *val) +{ + if (pMF->curr + sizeof(Uint32) < pMF->end) + { + Uint32 tmp; + memcpy(&tmp, pMF->curr, sizeof(Uint32)); + *val = DM_BE32_TO_NATIVE(tmp); + + pMF->curr += sizeof(Uint32); + return TRUE; + } + else + return FALSE; +} + + +static BOOL midiGetBE16(_MIDI_FILE *pMF, Uint16 *val) +{ + if (pMF->curr + sizeof(Uint16) < pMF->end) + { + Uint16 tmp; + memcpy(&tmp, pMF->curr, sizeof(Uint16)); + *val = DM_BE16_TO_NATIVE(tmp); + + pMF->curr += sizeof(Uint16); + return TRUE; + } + else + return FALSE; +} + + +static BOOL midiGetByte(_MIDI_FILE *pMF, Uint8 *val) +{ + if (pMF->curr + sizeof(Uint8) < pMF->end) + { + memcpy(val, pMF->curr, sizeof(Uint8)); + pMF->curr += sizeof(Uint8); + return TRUE; + } + else + return FALSE; +} + + static void midiFree(void *ptr) { if (ptr != NULL) free(ptr); } + +static BOOL midiWriteBE32(FILE *fp, const Uint32 val) +{ + Uint32 result = DM_NATIVE_TO_BE32(val); + return (fwrite(&result, sizeof(result), 1, fp) == 1); +} + + +static BOOL midiWriteBE16(FILE *fp, const Uint16 val) +{ + Uint16 result = DM_NATIVE_TO_BE16(val); + return (fwrite(&result, sizeof(result), 1, fp) == 1); +} + + +static BOOL midiWriteByte(FILE *fp, const Uint8 val) +{ + return fputc(val, fp) == val; +} + + +static BOOL midiWriteData(FILE *fp, const Uint8 *data, const size_t n) +{ + return fwrite(data, sizeof(Uint8), n, fp) == n; +} + + +static BOOL midiWriteStr(FILE *fp, const char *str) +{ + size_t len = strlen(str); + return fwrite(str, sizeof(char), strlen(str), fp) == len; +} + + static BOOL _midiValidateTrack(const _MIDI_FILE *pMF, int iTrack) { if (!IsFilePtrValid(pMF)) @@ -121,7 +238,7 @@ return TRUE; } -static BYTE *_midiWriteVarLen(BYTE * ptr, int n) +static Uint8 *_midiWriteVarLen(Uint8 * ptr, int n) { register long buffer; register long value = n; @@ -136,7 +253,7 @@ while (TRUE) { - *ptr++ = (BYTE) buffer; + *ptr++ = (Uint8) buffer; if (buffer & 0x80) buffer >>= 8; else @@ -149,10 +266,10 @@ /* Return a ptr to valid block of memory to store a message ** of up to sz_reqd bytes */ -static BYTE *_midiGetPtr(_MIDI_FILE *pMF, int iTrack, int sz_reqd) +static Uint8 *_midiGetPtr(_MIDI_FILE *pMF, int iTrack, int sz_reqd) { - const DWORD mem_sz_inc = 8092; /* arbitary */ - BYTE *ptr; + const Uint32 mem_sz_inc = 8092; /* arbitary */ + Uint8 *ptr; int curr_offset; MIDI_FILE_TRACK *pTrack = &pMF->Track[iTrack]; @@ -161,7 +278,7 @@ { curr_offset = ptr - pTrack->pBase; if ((ptr = - (BYTE *) realloc(pTrack->pBase, + (Uint8 *) realloc(pTrack->pBase, mem_sz_inc + pTrack->iBlockSize))) { pTrack->pBase = ptr; @@ -256,23 +373,17 @@ _MIDI_FILE *pMF = (_MIDI_FILE *) malloc(sizeof(_MIDI_FILE)); int i; - if (!pMF) + if (pMF == NULL) return NULL; - if (!bOverwriteIfExists) + if (!bOverwriteIfExists && (pMF->pFile = fopen(pFilename, "r")) != NULL) { - if ((pMF->pFile = fopen(pFilename, "r"))) - { - fclose(pMF->pFile); - midiFree(pMF); - return NULL; - } + fclose(pMF->pFile); + midiFree(pMF); + return NULL; } - if ((pMF->pFile = fopen(pFilename, "wb+"))) - { /*empty */ - } - else + if ((pMF->pFile = fopen(pFilename, "wb+")) == NULL) { midiFree(pMF); return NULL; @@ -290,16 +401,15 @@ pMF->Track[i].pEnd = NULL; pMF->Track[i].iBlockSize = 0; pMF->Track[i].dt = 0; - pMF->Track[i].iDefaultChannel = (BYTE) (i & 0xf); + pMF->Track[i].iDefaultChannel = (Uint8) (i & 0xf); - memset(pMF->Track[i].LastNote, '\0', sizeof(pMF->Track[i].LastNote)); + 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; @@ -315,7 +425,7 @@ ** 0-15. Thus, the fudge factor of 1 :) */ prev = pMF->Track[iTrack].iDefaultChannel + 1; - pMF->Track[iTrack].iDefaultChannel = (BYTE) (iChannel - 1); + pMF->Track[iTrack].iDefaultChannel = (Uint8) (iChannel - 1); return prev; } @@ -338,7 +448,7 @@ if (!IsFilePtrValid(pMF)) return MIDI_PPQN_DEFAULT; prev = pMF->Header.PPQN; - pMF->Header.PPQN = (WORD) PPQN; + pMF->Header.PPQN = (Uint16) PPQN; return prev; } @@ -360,7 +470,7 @@ if (iVersion < 0 || iVersion > 2) return MIDI_VERSION_DEFAULT; prev = pMF->Header.iVersion; - pMF->Header.iVersion = (WORD) iVersion; + pMF->Header.iVersion = (Uint16) iVersion; return prev; } @@ -374,73 +484,96 @@ MIDI_FILE *midiFileOpen(const char *pFilename) { - FILE *fp = fopen(pFilename, "rb"); _MIDI_FILE *pMF = NULL; - BYTE *ptr; BOOL bValidFile = FALSE; - long size; + FILE *fp; + int i; + + if ((fp = fopen(pFilename, "rb")) == NULL) + goto error; - if (fp) + if ((pMF = (_MIDI_FILE *) malloc(sizeof(_MIDI_FILE))) == NULL) + goto error; + + fseek(fp, 0L, SEEK_END); + pMF->file_size = ftell(fp); + + if ((pMF->curr = pMF->ptr = (Uint8 *) malloc(pMF->file_size)) == NULL) { - 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; + midiError(pMF, "Could not allocate %d bytes for MIDI file.\n", pMF->file_size); + goto error; + } - dwData = *((DWORD *) (ptr + 4)); - pMF->Header.iHeaderSize = SWAP_DWORD(dwData); + fseek(fp, 0L, SEEK_SET); + if (fread(pMF->ptr, sizeof(Uint8), pMF->file_size, fp) != pMF->file_size) + { + midiError(pMF, "Error reading file data.\n"); + goto error; + } - wData = *((WORD *) (ptr + 8)); - pMF->Header.iVersion = (WORD) SWAP_WORD(wData); + /* Is this a valid MIDI file ? */ + if (midiStrNCmp(pMF, "MThd", 4) != 0) + { + midiError(pMF, "Not a MIDI file.\n"); + goto error; + } + + midiSkip(pMF, 4); - wData = *((WORD *) (ptr + 10)); - pMF->Header.iNumTracks = (WORD) SWAP_WORD(wData); - - wData = *((WORD *) (ptr + 12)); - pMF->Header.PPQN = (WORD) SWAP_WORD(wData); + if (!midiGetBE32(pMF, &pMF->Header.iHeaderSize) || + !midiGetBE16(pMF, &pMF->Header.iVersion) || + !midiGetBE16(pMF, &pMF->Header.iNumTracks) || + !midiGetBE16(pMF, &pMF->Header.PPQN)) + { + midiError(pMF, "Error reading MIDI file header.\n"); + goto error; + } - 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; - } + midiSkip(pMF, pMF->Header.iHeaderSize + 8); - 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; - } + /* + ** Get all tracks + */ + for (i = 0; i < MAX_MIDI_TRACKS; ++i) + { + pMF->Track[i].pos = 0; + pMF->Track[i].last_status = 0; + } - pMF->bOpenForWriting = FALSE; - pMF->pFile = NULL; - bValidFile = TRUE; - } - } + for (i = 0; i < pMF->Header.iNumTracks; ++i) + { + if (midiStrNCmp(pMF, "MTrk", 4) != 0) + { + midiError(pMF, "Expected track %d data, not found.\n", i); + goto error; + } + + pMF->Track[i].pBase = pMF->curr; + pMF->Track[i].ptr = pMF->curr + 8; + + midiSkip(pMF, 4); + if (!midiGetBE32(pMF, &pMF->Track[i].sz)) + { + midiError(pMF, "Could not read MTrk size.\n"); + goto error; } + midiSkip(pMF, 4); + + pMF->Track[i].pEnd = pMF->curr + pMF->Track[i].sz; + + midiSkip(pMF, pMF->Track[i].sz); + } + + pMF->bOpenForWriting = FALSE; + pMF->pFile = NULL; + bValidFile = TRUE; + + +error: + // Cleanup if (fp != NULL) fclose(fp); - } if (!bValidFile) { @@ -466,12 +599,12 @@ } BOOL midiFileFlushTrack(MIDI_FILE *_pMF, int iTrack, BOOL bFlushToEnd, - DWORD dwEndTimePos) + Uint32 dwEndTimePos) { - int sz; - BYTE *ptr; + size_t sz, i; + Uint8 *ptr; MIDI_END_POINT *pEndPoints; - int num, i, mx_pts; + int num, mx_pts; BOOL bNoChanges = TRUE; _VAR_CAST; @@ -509,7 +642,7 @@ qsort(pEndPoints, mx_pts, sizeof(MIDI_END_POINT), qs_cmp_pEndPoints); i = 0; - while ((dwEndTimePos >= (DWORD) pEndPoints[i].iEndPos || bFlushToEnd) + while ((dwEndTimePos >= (Uint32) pEndPoints[i].iEndPos || bFlushToEnd) && i < mx_pts) { ptr = _midiGetPtr(pMF, iTrack, DT_DEF); @@ -524,7 +657,7 @@ pMF->Track[iTrack].pos); /* msgNoteOn msgNoteOff */ *ptr++ = - (BYTE) (msgNoteOff | pMF->Track[iTrack].LastNote[num].chn); + (Uint8) (msgNoteOff | pMF->Track[iTrack].LastNote[num].chn); *ptr++ = pMF->Track[iTrack].LastNote[num].note; *ptr++ = 0; @@ -580,15 +713,9 @@ if (pMF->bOpenForWriting) { - WORD iNumTracks = 0; - WORD wTest = 256; - BOOL bSwap = FALSE; + Uint16 iNumTracks = 0; int i; - /* Intel processor style-endians need byte swap :( */ - if (*((BYTE *) & wTest) == 0) - bSwap = TRUE; - /* Flush our buffers */ for (i = 0; i < MAX_MIDI_TRACKS; ++i) { @@ -602,62 +729,39 @@ /* ** Header */ + if (!midiWriteStr(pMF->pFile, "MThd") || + !midiWriteBE32(pMF->pFile, 6) || + !midiWriteBE16(pMF->pFile, iNumTracks == 1 ? pMF->Header.iVersion : 1) || + !midiWriteBE16(pMF->pFile, iNumTracks) || + !midiWriteBE16(pMF->pFile, pMF->Header.PPQN)) { - 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); + midiError(pMF, "Could not write MThd header.\n"); + goto error; + } - 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); + size_t sz = pMF->Track[i].ptr - pMF->Track[i].pBase; + if (!midiWriteStr(pMF->pFile, "MTrk") || + !midiWriteBE32(pMF->pFile, sz) || + !midiWriteData(pMF->pFile, pMF->Track[i].pBase, sz)) + { + midiError(pMF, "Could not write track #%d data.\n", i); + goto error; + } - /* 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 */ midiFree(pMF->Track[i].pBase); } - + } } - if (pMF->pFile) +error: + if (pMF->pFile != NULL) return fclose(pMF->pFile) ? FALSE : TRUE; midiFree(pMF); @@ -671,7 +775,7 @@ BOOL midiSongAddSMPTEOffset(MIDI_FILE *_pMF, int iTrack, int iHours, int iMins, int iSecs, int iFrames, int iFFrames) { - static BYTE tmp[] = + static Uint8 tmp[] = { msgMetaEvent, metaSMPTEOffset, 0x05, 0, 0, 0, 0, 0 }; _VAR_CAST; @@ -687,11 +791,11 @@ 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; + tmp[3] = (Uint8) iHours; + tmp[4] = (Uint8) iMins; + tmp[5] = (Uint8) iSecs; + tmp[6] = (Uint8) iFrames; + tmp[7] = (Uint8) iFFrames; return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } @@ -705,7 +809,7 @@ 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 Uint8 tmp[] = { msgMetaEvent, metaTimeSig, 0x04, 0, 0, 0, 0 }; _VAR_CAST; if (!IsFilePtrValid(pMF)) @@ -713,16 +817,16 @@ if (!IsTrackValid(iTrack)) return FALSE; - tmp[3] = (BYTE) iNom; - tmp[4] = (BYTE) (MIDI_NOTE_MINIM / iDenom); - tmp[5] = (BYTE) iClockInMetroTick; - tmp[6] = (BYTE) iNotated32nds; + tmp[3] = (Uint8) iNom; + tmp[4] = (Uint8) (MIDI_NOTE_MINIM / iDenom); + tmp[5] = (Uint8) iClockInMetroTick; + tmp[6] = (Uint8) iNotated32nds; return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } BOOL midiSongAddKeySig(MIDI_FILE *_pMF, int iTrack, tMIDI_KEYSIG iKey) { - static BYTE tmp[] = { msgMetaEvent, metaKeySig, 0x02, 0, 0 }; + static Uint8 tmp[] = { msgMetaEvent, metaKeySig, 0x02, 0, 0 }; _VAR_CAST; if (!IsFilePtrValid(pMF)) @@ -730,14 +834,14 @@ if (!IsTrackValid(iTrack)) return FALSE; - tmp[3] = (BYTE) ((iKey & keyMaskKey) * ((iKey & keyMaskNeg) ? -1 : 1)); - tmp[4] = (BYTE) ((iKey & keyMaskMin) ? 1 : 0); + tmp[3] = (Uint8) ((iKey & keyMaskKey) * ((iKey & keyMaskNeg) ? -1 : 1)); + tmp[4] = (Uint8) ((iKey & keyMaskMin) ? 1 : 0); return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } BOOL midiSongAddTempo(MIDI_FILE *_pMF, int iTrack, int iTempo) { - static BYTE tmp[] = { msgMetaEvent, metaSetTempo, 0x03, 0, 0, 0 }; + static Uint8 tmp[] = { msgMetaEvent, metaSetTempo, 0x03, 0, 0, 0 }; int us; /* micro-seconds per qn */ _VAR_CAST; @@ -747,28 +851,28 @@ return FALSE; us = 60000000L / iTempo; - tmp[3] = (BYTE) ((us >> 16) & 0xff); - tmp[4] = (BYTE) ((us >> 8) & 0xff); - tmp[5] = (BYTE) ((us >> 0) & 0xff); + tmp[3] = (Uint8) ((us >> 16) & 0xff); + tmp[4] = (Uint8) ((us >> 8) & 0xff); + tmp[5] = (Uint8) ((us >> 0) & 0xff); return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } BOOL midiSongAddMIDIPort(MIDI_FILE *_pMF, int iTrack, int iPort) { - static BYTE tmp[] = { msgMetaEvent, metaMIDIPort, 1, 0 }; + static Uint8 tmp[] = { msgMetaEvent, metaMIDIPort, 1, 0 }; _VAR_CAST; if (!IsFilePtrValid(pMF)) return FALSE; if (!IsTrackValid(iTrack)) return FALSE; - tmp[3] = (BYTE) iPort; + tmp[3] = (Uint8) iPort; return midiTrackAddRaw(pMF, iTrack, sizeof(tmp), tmp, FALSE, 0); } BOOL midiSongAddEndSequence(MIDI_FILE *_pMF, int iTrack) { - static BYTE tmp[] = { msgMetaEvent, metaEndSequence, 0 }; + static Uint8 tmp[] = { msgMetaEvent, metaEndSequence, 0 }; _VAR_CAST; if (!IsFilePtrValid(pMF)) @@ -784,10 +888,10 @@ ** midiTrack* Functions */ BOOL midiTrackAddRaw(MIDI_FILE *_pMF, int iTrack, int data_sz, - const BYTE * pData, BOOL bMovePtr, int dt) + const Uint8 * pData, BOOL bMovePtr, int dt) { MIDI_FILE_TRACK *pTrk; - BYTE *ptr; + Uint8 *ptr; int dtime; _VAR_CAST; @@ -819,7 +923,7 @@ BOOL midiTrackIncTime(MIDI_FILE *_pMF, int iTrack, int iDeltaTime, BOOL bOverridePPQN) { - DWORD will_end_at; + Uint32 will_end_at; _VAR_CAST; if (!IsFilePtrValid(pMF)) @@ -838,7 +942,7 @@ BOOL midiTrackAddText(MIDI_FILE *_pMF, int iTrack, tMIDI_TEXT iType, const char *pTxt) { - BYTE *ptr; + Uint8 *ptr; int sz; _VAR_CAST; @@ -852,8 +956,8 @@ { *ptr++ = 0; /* delta-time=0 */ *ptr++ = msgMetaEvent; - *ptr++ = (BYTE) iType; - ptr = _midiWriteVarLen((BYTE *) ptr, sz); + *ptr++ = (Uint8) iType; + ptr = _midiWriteVarLen((Uint8 *) ptr, sz); strcpy((char *) ptr, pTxt); pMF->Track[iTrack].ptr = ptr + sz; return TRUE; @@ -891,7 +995,7 @@ BOOL midiTrackSetPitchWheel(MIDI_FILE *pMF, int iTrack, int iWheelPos) { - WORD wheel = (WORD) iWheelPos; + Uint16 wheel = (Uint16) iWheelPos; /* bitshift 7 instead of eight because we're dealing with 7 bit numbers */ wheel += MIDI_WHEEL_CENTRE; @@ -902,8 +1006,8 @@ BOOL midiTrackAddMsg(MIDI_FILE *_pMF, int iTrack, tMIDI_MSG iMsg, int iParam1, int iParam2) { - BYTE *ptr; - BYTE data[3]; + Uint8 *ptr; + Uint8 data[3]; int sz; _VAR_CAST; @@ -918,11 +1022,11 @@ if (!ptr) return FALSE; - data[0] = (BYTE) (iMsg | pMF->Track[iTrack].iDefaultChannel); - data[1] = (BYTE) (iParam1 & 0x7f); - data[2] = (BYTE) (iParam2 & 0x7f); + data[0] = (Uint8) (iMsg | pMF->Track[iTrack].iDefaultChannel); + data[1] = (Uint8) (iParam1 & 0x7f); + data[2] = (Uint8) (iParam2 & 0x7f); /* - ** Is this msg a single, or double BYTE, prm? + ** Is this msg a single, or double Uint8, prm? */ switch (iMsg) { @@ -944,7 +1048,7 @@ int iVol, BOOL bAutoInc, BOOL bOverrideLength) { MIDI_FILE_TRACK *pTrk; - BYTE *ptr; + Uint8 *ptr; BOOL bSuccess = FALSE; int i, chn; @@ -967,16 +1071,16 @@ 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].note = (Uint8) iNote; + pTrk->LastNote[i].chn = (Uint8) 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; + *ptr++ = (Uint8) (msgNoteOn | chn); + *ptr++ = (Uint8) iNote; + *ptr++ = (Uint8) iVol; break; } @@ -1021,10 +1125,10 @@ /* ** midiRead* Functions */ -static BYTE *_midiReadVarLen(BYTE * ptr, DWORD * num) +static Uint8 *_midiReadVarLen(Uint8 * ptr, Uint32 * num) { - register DWORD value; - register BYTE c; + register Uint32 value; + register Uint8 c; if ((value = *ptr++) & 0x80) { @@ -1040,12 +1144,12 @@ } -static BOOL _midiReadTrackCopyData(MIDI_MSG * pMsg, BYTE * ptr, DWORD sz, +static BOOL _midiReadTrackCopyData(MIDI_MSG * pMsg, Uint8 * ptr, Uint32 sz, BOOL bCopyPtrData) { if (sz > pMsg->data_sz) { - pMsg->data = (BYTE *) realloc(pMsg->data, sz); + pMsg->data = (Uint8 *) realloc(pMsg->data, sz); pMsg->data_sz = sz; } @@ -1068,7 +1172,7 @@ MIDI_MSG * pMsg) { MIDI_FILE_TRACK *pTrack; - BYTE *bptr, *pMsgDataPtr; + Uint8 *bptr, *pMsgDataPtr; int sz; _VAR_CAST; @@ -1102,7 +1206,7 @@ } pMsg->iLastMsgType = (tMIDI_MSG) pMsg->iType; - pMsg->iLastMsgChnl = (BYTE) ((*pTrack->ptr) & 0x0f) + 1; + pMsg->iLastMsgChnl = (Uint8) ((*pTrack->ptr) & 0x0f) + 1; switch (pMsg->iType) { @@ -1191,7 +1295,7 @@ break; case metaSetTempo: { - DWORD us = + Uint32 us = ((*(pTrack->ptr + 0)) << 16) | ((*(pTrack->ptr + 1)) << 8) | (*(pTrack->ptr + 2)); pMsg->MsgData.MetaEvent.Data.Tempo.iBPM = 60000000L / us; diff -r de2ee75a142f -r a14cc6c5d7ef src/midifile.h --- a/src/midifile.h Mon Aug 05 20:26:11 2013 +0300 +++ b/src/midifile.h Mon Aug 05 20:51:20 2013 +0300 @@ -1,7 +1,9 @@ #ifndef _MIDIFILE_H #define _MIDIFILE_H -#include "midiinfo.h" /* enumerations and constants for GM */ +#include "midiinfo.h" /* enumerations and constants for GM */ +#include "mtypes.h" + /* * midiFile.c - Header file for Steevs MIDI Library @@ -25,7 +27,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* +/* ** All functions start with one of the following prefixes: ** midiFile* For non-GM features that relate to the file, and have ** no use once the file has been created, i.e. CreateFile @@ -36,24 +38,6 @@ */ /* -** Types because we're dealing with files, and need to be careful -*/ -#ifndef XXX -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -#endif - -typedef int BOOL; -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - - -/* ** MIDI Constants */ #define MIDI_PPQN_DEFAULT 384 @@ -68,142 +52,175 @@ /* ** MIDI structures, accessibly externably */ -typedef void MIDI_FILE; -typedef struct { - tMIDI_MSG iType; +typedef void MIDI_FILE; +typedef struct +{ + tMIDI_MSG iType; - DWORD dt; /* delta time */ - DWORD dwAbsPos; - DWORD iMsgSize; + Uint32 dt; /* delta time */ + Uint32 dwAbsPos; + Uint32 iMsgSize; - BOOL bImpliedMsg; - tMIDI_MSG iImpliedMsg; + BOOL bImpliedMsg; + tMIDI_MSG iImpliedMsg; + + /* Raw data chunk */ + Uint8 *data; /* dynamic data block */ + Uint32 data_sz; - /* Raw data chunk */ - BYTE *data; /* dynamic data block */ - DWORD data_sz; - - union { - struct { - int iNote; - int iChannel; - int iVolume; - } NoteOn; - struct { - int iNote; - int iChannel; - } NoteOff; - struct { - int iNote; - int iChannel; - int iPressure; - } NoteKeyPressure; - struct { - int iChannel; - tMIDI_CC iControl; - int iParam; - } NoteParameter; - struct { - int iChannel; - int iProgram; - } ChangeProgram; - struct { - int iChannel; - int iPressure; - } ChangePressure; - struct { - int iChannel; - int iPitch; - } PitchWheel; - struct { - tMIDI_META iType; - union { - int iMIDIPort; - int iSequenceNumber; - struct { - BYTE *pData; - } Text; - struct { - int iBPM; - } Tempo; - struct { - int iHours, iMins; - int iSecs, iFrames,iFF; - } SMPTE; - struct { - tMIDI_KEYSIG iKey; - } KeySig; - struct { - int iNom, iDenom; - } TimeSig; - struct { - BYTE *pData; - int iSize; - } Sequencer; - } Data; - } MetaEvent; - struct { - BYTE *pData; - int iSize; - } SysEx; - } MsgData; + union + { + struct + { + int iNote; + int iChannel; + int iVolume; + } NoteOn; + struct + { + int iNote; + int iChannel; + } NoteOff; + struct + { + int iNote; + int iChannel; + int iPressure; + } NoteKeyPressure; + struct + { + int iChannel; + tMIDI_CC iControl; + int iParam; + } NoteParameter; + struct + { + int iChannel; + int iProgram; + } ChangeProgram; + struct + { + int iChannel; + int iPressure; + } ChangePressure; + struct + { + int iChannel; + int iPitch; + } PitchWheel; + struct + { + tMIDI_META iType; + union + { + int iMIDIPort; + int iSequenceNumber; + struct + { + Uint8 *pData; + } Text; + struct + { + int iBPM; + } Tempo; + struct + { + int iHours, iMins; + int iSecs, iFrames, iFF; + } SMPTE; + struct + { + tMIDI_KEYSIG iKey; + } KeySig; + struct + { + int iNom, iDenom; + } TimeSig; + struct + { + Uint8 *pData; + int iSize; + } Sequencer; + } Data; + } MetaEvent; + struct + { + Uint8 *pData; + int iSize; + } SysEx; + } MsgData; - /* State information - Please treat these as private*/ - tMIDI_MSG iLastMsgType; - BYTE iLastMsgChnl; - - } MIDI_MSG; + /* State information - Please treat these as private */ + tMIDI_MSG iLastMsgType; + Uint8 iLastMsgChnl; + +} MIDI_MSG; + /* ** midiFile* Prototypes */ -MIDI_FILE *midiFileCreate(const char *pFilename, BOOL bOverwriteIfExists); -int midiFileSetTracksDefaultChannel(MIDI_FILE *pMF, int iTrack, int iChannel); -int midiFileGetTracksDefaultChannel(const MIDI_FILE *pMF, int iTrack); -BOOL midiFileFlushTrack(MIDI_FILE *pMF, int iTrack, BOOL bFlushToEnd, DWORD dwEndTimePos); -BOOL midiFileSyncTracks(MIDI_FILE *pMF, int iTrack1, int iTrack2); -int midiFileSetPPQN(MIDI_FILE *pMF, int PPQN); -int midiFileGetPPQN(const MIDI_FILE *pMF); -int midiFileSetVersion(MIDI_FILE *pMF, int iVersion); -int midiFileGetVersion(const MIDI_FILE *pMF); -MIDI_FILE *midiFileOpen(const char *pFilename); -BOOL midiFileClose(MIDI_FILE *pMF); +MIDI_FILE *midiFileCreate(const char *pFilename, BOOL bOverwriteIfExists); +int midiFileSetTracksDefaultChannel(MIDI_FILE *pMF, int iTrack, + int iChannel); +int midiFileGetTracksDefaultChannel(const MIDI_FILE *pMF, int iTrack); +BOOL midiFileFlushTrack(MIDI_FILE *pMF, int iTrack, BOOL bFlushToEnd, + Uint32 dwEndTimePos); +BOOL midiFileSyncTracks(MIDI_FILE *pMF, int iTrack1, int iTrack2); +int midiFileSetPPQN(MIDI_FILE *pMF, int PPQN); +int midiFileGetPPQN(const MIDI_FILE *pMF); +int midiFileSetVersion(MIDI_FILE *pMF, int iVersion); +int midiFileGetVersion(const MIDI_FILE *pMF); +MIDI_FILE *midiFileOpen(const char *pFilename); +BOOL midiFileClose(MIDI_FILE *pMF); /* ** midiSong* Prototypes */ -BOOL midiSongAddSMPTEOffset(MIDI_FILE *pMF, int iTrack, int iHours, int iMins, int iSecs, int iFrames, int iFFrames); -BOOL midiSongAddSimpleTimeSig(MIDI_FILE *pMF, int iTrack, int iNom, int iDenom); -BOOL midiSongAddTimeSig(MIDI_FILE *pMF, int iTrack, int iNom, int iDenom, int iClockInMetroTick, int iNotated32nds); -BOOL midiSongAddKeySig(MIDI_FILE *pMF, int iTrack, tMIDI_KEYSIG iKey); -BOOL midiSongAddTempo(MIDI_FILE *pMF, int iTrack, int iTempo); -BOOL midiSongAddMIDIPort(MIDI_FILE *pMF, int iTrack, int iPort); -BOOL midiSongAddEndSequence(MIDI_FILE *pMF, int iTrack); +BOOL midiSongAddSMPTEOffset(MIDI_FILE *pMF, int iTrack, int iHours, + int iMins, int iSecs, int iFrames, int iFFrames); +BOOL midiSongAddSimpleTimeSig(MIDI_FILE *pMF, int iTrack, int iNom, + int iDenom); +BOOL midiSongAddTimeSig(MIDI_FILE *pMF, int iTrack, int iNom, int iDenom, + int iClockInMetroTick, int iNotated32nds); +BOOL midiSongAddKeySig(MIDI_FILE *pMF, int iTrack, tMIDI_KEYSIG iKey); +BOOL midiSongAddTempo(MIDI_FILE *pMF, int iTrack, int iTempo); +BOOL midiSongAddMIDIPort(MIDI_FILE *pMF, int iTrack, int iPort); +BOOL midiSongAddEndSequence(MIDI_FILE *pMF, int iTrack); /* ** midiTrack* Prototypes */ -BOOL midiTrackAddRaw(MIDI_FILE *pMF, int iTrack, int iDataSize, const BYTE *pData, BOOL bMovePtr, int iDeltaTime); -BOOL midiTrackIncTime(MIDI_FILE *pMF, int iTrack, int iDeltaTime, BOOL bOverridePPQN); -BOOL midiTrackAddText(MIDI_FILE *pMF, int iTrack, tMIDI_TEXT iType, const char *pTxt); -BOOL midiTrackAddMsg(MIDI_FILE *pMF, int iTrack, tMIDI_MSG iMsg, int iParam1, int iParam2); -BOOL midiTrackSetKeyPressure(MIDI_FILE *pMF, int iTrack, int iNote, int iAftertouch); -BOOL midiTrackAddControlChange(MIDI_FILE *pMF, int iTrack, tMIDI_CC iCCType, int iParam); -BOOL midiTrackAddProgramChange(MIDI_FILE *pMF, int iTrack, int iInstrPatch); -BOOL midiTrackChangeKeyPressure(MIDI_FILE *pMF, int iTrack, int iDeltaPressure); -BOOL midiTrackSetPitchWheel(MIDI_FILE *pMF, int iTrack, int iWheelPos); -BOOL midiTrackAddNote(MIDI_FILE *pMF, int iTrack, int iNote, int iLength, int iVol, BOOL bAutoInc, BOOL bOverrideLength); -BOOL midiTrackAddRest(MIDI_FILE *pMF, int iTrack, int iLength, BOOL bOverridePPQN); -BOOL midiTrackGetEndPos(MIDI_FILE *pMF, int iTrack); +BOOL midiTrackAddRaw(MIDI_FILE *pMF, int iTrack, int iDataSize, + const Uint8 * pData, BOOL bMovePtr, int iDeltaTime); +BOOL midiTrackIncTime(MIDI_FILE *pMF, int iTrack, int iDeltaTime, + BOOL bOverridePPQN); +BOOL midiTrackAddText(MIDI_FILE *pMF, int iTrack, tMIDI_TEXT iType, + const char *pTxt); +BOOL midiTrackAddMsg(MIDI_FILE *pMF, int iTrack, tMIDI_MSG iMsg, int iParam1, + int iParam2); +BOOL midiTrackSetKeyPressure(MIDI_FILE *pMF, int iTrack, int iNote, + int iAftertouch); +BOOL midiTrackAddControlChange(MIDI_FILE *pMF, int iTrack, tMIDI_CC iCCType, + int iParam); +BOOL midiTrackAddProgramChange(MIDI_FILE *pMF, int iTrack, int iInstrPatch); +BOOL midiTrackChangeKeyPressure(MIDI_FILE *pMF, int iTrack, + int iDeltaPressure); +BOOL midiTrackSetPitchWheel(MIDI_FILE *pMF, int iTrack, int iWheelPos); +BOOL midiTrackAddNote(MIDI_FILE *pMF, int iTrack, int iNote, int iLength, + int iVol, BOOL bAutoInc, BOOL bOverrideLength); +BOOL midiTrackAddRest(MIDI_FILE *pMF, int iTrack, int iLength, + BOOL bOverridePPQN); +BOOL midiTrackGetEndPos(MIDI_FILE *pMF, int iTrack); /* ** midiRead* Prototypes */ -int midiReadGetNumTracks(const MIDI_FILE *pMF); -BOOL midiReadGetNextMessage(const MIDI_FILE *pMF, int iTrack, MIDI_MSG *pMsg); -void midiReadInitMessage(MIDI_MSG *pMsg); -void midiReadFreeMessage(MIDI_MSG *pMsg); +int midiReadGetNumTracks(const MIDI_FILE *pMF); +BOOL midiReadGetNextMessage(const MIDI_FILE *pMF, int iTrack, + MIDI_MSG * pMsg); +void midiReadInitMessage(MIDI_MSG * pMsg); +void midiReadFreeMessage(MIDI_MSG * pMsg); #endif /* _MIDIFILE_H */ -