41char *
strcopy(
char * _dest,
const char * _source );
80#if ( defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN ) || \
81 defined(__BIG_ENDIAN__) || \
82 defined(__ARMEB__) || \
83 defined(__THUMBEB__) || \
84 defined(__AARCH64EB__) || \
85 defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
86 #define SWAP_WORD(w) (w)
87 #define SWAP_DWORD(d) (d)
89 #define SWAP_WORD(w) (WORD)(((w)>>8)|((w)<<8))
90 #define SWAP_DWORD(d) (DWORD)((d)>>24)|(((d)>>8)&0xff00)|(((d)<<8)&0xff0000)|(((d)<<24))
93#define _VAR_CAST MidiFileInternal *pMF = (MidiFileInternal *)_pMF
94#define IsFilePtrValid(pMF) (pMF)
95#define IsTrackValid(_x) (_midiValidateTrack(pMF, _x))
96#define IsChannelValid(_x) ((_x)>=1 && (_x)<=16)
97#define IsNoteValid(_x) ((_x)>=0 && (_x)<128)
98#define IsMessageValid(_x) ((_x)>=messageNoteOff && (_x)<=messageMetaEvent)
121static BYTE *_midiWriteVarLen(
BYTE *ptr,
int n){
123register long value=n;
125 buffer = value & 0x7f;
126 while ((value >>= 7) > 0)
130 buffer += (value & 0x7f);
135 *ptr++ = (
BYTE)buffer;
147const DWORD mem_sz_inc = 8092;
153 if (ptr == NULL || ptr+sz_reqd > pTrack->
pEnd)
155 curr_offset = ptr-pTrack->
pBase;
161 pTrack->
ptr = ptr+curr_offset;
174static int _midiGetLength(
int ppqn,
int iNoteLen,
int bOverride)
245 if (!pMF)
return NULL;
247 if (!bOverwriteIfExists)
249 if ((pMF->
pFile = fopen(pFilename,
"r")))
257 if ((pMF->
pFile = fopen(pFilename,
"wb+")))
347FILE *fp = fopen(pFilename,
"rb");
357 fseek(fp, 0
L, SEEK_END);
361 fseek(fp, 0
L, SEEK_SET);
364 if (*(ptr+0) ==
'M' && *(ptr+1) ==
'T' &&
365 *(ptr+2) ==
'h' && *(ptr+3) ==
'd')
371 dwData = *((
DWORD *)(ptr+4));
374 wData = *((
WORD *)(ptr+8));
377 wData = *((
WORD *)(ptr+10));
380 wData = *((
WORD *)(ptr+12));
395 dwData = *((
DWORD *)(ptr+4));
413 if (pMF)
free((
void *)pMF);
425static int qs_cmp_pEndPoints(
const void *e1,
const void *e2)
442 if (!_midiValidateTrack(pMF, iTrack))
return FALSE;
450 pEndPoints[mx_pts].
iIdx = i;
458 dwEndTimePos = pEndPoints[mx_pts-1].
iEndPos;
460 dwEndTimePos = pMF->
Track[iTrack].
pos;
465 qsort(pEndPoints, mx_pts,
sizeof(
MIDI_END_POINT), qs_cmp_pEndPoints);
468 while ((dwEndTimePos >= (
DWORD)pEndPoints[i].iEndPos || bFlushToEnd) && i<mx_pts)
470 ptr = _midiGetPtr(pMF, iTrack,
DT_DEF);
474 num = pEndPoints[i].
iIdx;
490 free((
void *)pEndPoints);
527 if (*((
BYTE *)&wTest) == 0)
541 const BYTE mthd[4] = {
'M',
'T',
'h',
'd'};
546 fwrite(mthd,
sizeof(
BYTE), 4, pMF->
pFile);
549 fwrite(&dwData,
sizeof(
DWORD), 1, pMF->
pFile);
553 if (bSwap) iNumTracks =
SWAP_WORD(iNumTracks);
555 if (bSwap) PPQN =
SWAP_WORD(wData);
else PPQN = wData;
557 fwrite(&iNumTracks,
sizeof(
WORD), 1, pMF->
pFile);
558 fwrite(&PPQN,
sizeof(
WORD), 1, pMF->
pFile);
564 const BYTE mtrk[4] = {
'M',
'T',
'r',
'k'};
567 fwrite(&mtrk,
sizeof(
BYTE), 4, pMF->
pFile);
594 if (iMins<0 || iMins>59) iMins=0;
595 if (iSecs<0 || iSecs>59) iSecs=0;
596 if (iFrames<0 || iFrames>24) iFrames=0;
598 tmp[3] = (
BYTE)iHours;
599 tmp[4] = (
BYTE)iMins;
600 tmp[5] = (
BYTE)iSecs;
601 tmp[6] = (
BYTE)iFrames;
602 tmp[7] = (
BYTE)iFFrames;
622 tmp[5] = (
BYTE)iClockInMetroTick;
623 tmp[6] = (
BYTE)iNotated32nds;
649 us = 60000000L/iTempo;
650 tmp[3] = (
BYTE)((us>>16)&0xff);
651 tmp[4] = (
BYTE)((us>>8)&0xff);
652 tmp[5] = (
BYTE)((us>>0)&0xff);
663 tmp[3] = (
BYTE)iPort;
688 pTrk = &pMF->
Track[iTrack];
689 ptr = _midiGetPtr(pMF, iTrack, data_sz+
DT_DEF);
697 ptr = _midiWriteVarLen(ptr, dtime);
698 memcpy(ptr, pData, data_sz);
702 pTrk->
ptr = ptr+data_sz;
716 will_end_at = _midiGetLength(pMF->
Header.
PPQN, iDeltaTime, bOverridePPQN);
734 if ((ptr = _midiGetPtr(pMF, iTrack, sz+
DT_DEF)))
738 *ptr++ = (
BYTE)iType;
739 ptr = _midiWriteVarLen((
BYTE *)ptr, sz);
789 ptr = _midiGetPtr(pMF, iTrack,
DT_DEF);
794 data[1] = (
BYTE)(iParam1 & 0x7f);
795 data[2] = (
BYTE)(iParam2 & 0x7f);
824 pTrk = &pMF->
Track[iTrack];
825 ptr = _midiGetPtr(pMF, iTrack,
DT_DEF);
830 iLength = _midiGetLength(pMF->
Header.
PPQN, iLength, bOverrideLength);
841 ptr = _midiWriteVarLen(ptr, pTrk->
dt);
843 *ptr++ = (
BYTE)iNote;
853 pTrk->
pos += pTrk->
dt;
868 iLength = _midiGetLength(pMF->
Header.
PPQN, iLength, bOverridePPQN);
886 if ((value = *ptr++) & 0x80)
891 value = (value << 7) + ((c = *ptr++) & 0x7f);
910 if (bCopyPtrData && ptr)
911 memcpy(pMsg->
data, ptr, sz);
925BYTE *bptr, *pMsgDataPtr;
931 pTrack = &pMF->
Track[iTrack];
932 if (pTrack->
ptr >= pTrack->
pEnd)
935 pTrack->
ptr = _midiReadVarLen(pTrack->
ptr, &pMsg->
dt);
936 pTrack->
pos += pMsg->
dt;
940 if (*pTrack->
ptr & 0x80)
943 pMsgDataPtr = pTrack->
ptr+1;
945 if (pMsg->
iType == 0xf0)
951 pMsgDataPtr = pTrack->
ptr;
1043 if (_midiReadTrackCopyData(pMsg, pTrack->
ptr, sz,
FALSE) ==
FALSE)
1046 memcpy(pMsg->
data, bptr, sz);
1069 DWORD us = ((*(pTrack->
ptr+0))<<16)|((*(pTrack->
ptr+1))<<8)|(*(pTrack->
ptr+2));
1085 if (*pTrack->
ptr & 0x80)
1094 if (*(pTrack->
ptr+1))
1114 if (_midiReadTrackCopyData(pMsg, pTrack->
ptr, sz,
FALSE) ==
FALSE)
1117 memcpy(pMsg->
data, bptr, sz);
1125 if ((pMsg->
iType&0xf0) != 0xf0)
1127 if (*pTrack->
ptr & 0x80)
1155static char *szPatchList[128] = {
1156 "Acoustic Grand Piano",
1157 "Bright Acoustic Piano",
1158 "Electric Grand Piano",
1180 "Acoustic Guitar (nylon)",
1181 "Acoustic Guitar (steel)",
1182 "Electric Guitar (jazz)",
1183 "Electric Guitar (clean)",
1184 "Electric Guitar (muted)",
1185 "Overdriven Guitar",
1186 "Distortion Guitar",
1189 "Electric Bass (finger)",
1190 "Electric Bass (picked)",
1201 "Pizzicato strings",
1204 "String ensemble 1",
1205 "String ensemble 2",
1237 "Lead 5 (Sawtooth)",
1238 "Lead 5 (Calliope)",
1243 "Lead 5 (Bass+lead)",
1246 "Pad 3 (Polysynth)",
1253 "FX 2 (Soundtrack)",
1255 "FX 4 (Atmosphere)",
1256 "FX 5 (Brightness)",
1276 "Guitar fret noise",
1286static char *szGMDrums[128]={
1322 "Acoustic Kick Drum",
1323 "Electric Kick Drum",
1325 "Acoustic Snare Drum",
1327 "Electric Snare Drum ",
1377static char *szCCList[] = {
1394 "General Purpose 1",
1395 "General Purpose 2",
1396 "General Purpose 3",
1397 "General Purpose 4",
1410 "lsb-32",
"lsb-33",
"lsb-34",
"lsb-35",
"lsb-36",
"lsb-37",
"lsb-38",
1411 "lsb-39",
"lsb-40",
"lsb-41",
"lsb-42",
"lsb-43",
"lsb-44",
"lsb-45",
1412 "lsb-46",
"lsb-47",
"lsb-48",
"lsb-49",
"lsb-50",
"lsb-51",
"lsb-52",
1413 "lsb-53",
"lsb-54",
"lsb-55",
"lsb-56",
"lsb-57",
"lsb-58",
"lsb-59",
1414 "lsb-60",
"lsb-61",
"lsb-62",
"lsb-63",
1420 "Legato Foot Switch",
1432 "General Purpose 5",
1433 "General Purpose 6",
1434 "General Purpose 7",
1435 "General Purpose 8",
1436 "Portamento Control",
1450 "Non Reg Param LSB",
1451 "Non Ref Param MSB",
1473 "Reset All Controllers",
1482static char *szNoteName[] = {
1497static float fFreqlist[] = {
1514 if (iInstr < 0 || iInstr > 127)
1516 strcopy(pName, szPatchList[iInstr]);
1522 if (iInstr < 0 || iInstr > 127)
1524 strcopy(pName, szGMDrums[iInstr]);
1541 strcopy(pName,
"Note key pressure");
1545 strcopy(pName,
"Set parameter");
1549 strcopy(pName,
"Set program");
1553 strcopy(pName,
"Change pressure");
1557 strcopy(pName,
"Set pitch wheel");
1580 if (iCC < 0 || iCC > 127)
1582 strcopy(pName, szCCList[iCC]);
1588static char *iKeysList[2][8] = {
1589{
"C ",
"G ",
"D ",
"A ",
"E ",
"B ",
"F#",
"C#", },
1590{
"C ",
"F ",
"Bb",
"Eb",
"Ab",
"Db",
"Gb",
"Cb", },
1593int iRootNum = (iKey&7);
1597 strcopy(pName,iKeysList[iFlats?1:0][iRootNum]);
1598 strcat(pName,iMin?
" Min":
" Maj");
1604 if (iEvent<1 || iEvent>7)
return FALSE;
1627 default:
return FALSE;
1635int note_map[] = {9, 11, 0, 2, 4, 5, 7};
1639 strncpy(
cpy, pName, 15);
1643 while(!isalpha(*p) && *p)
1648 note = toupper(*p)-
'A';
1649 if (note >= 0 && note <= 7)
1651 note = note_map[note];
1667 if (!pStr)
return NULL;
1669 if (iNote<0 || iNote>127)
1672 sprintf(pStr,
"%s%d", szNoteName[iNote%12], ((iNote-
MIDI_NOTE_C0)/12));
1679int oct = iNote/12-5;
1682 if (iNote<0 || iNote>127)
return 0;
1684 freq = fFreqlist[iNote%12];
1687 freq *= 2.0f, oct--;
1690 freq /= 2.0f, oct++;
1697int iNote, iBestNote=0;
1698float fDiff=20000, f;
1700 for(iNote=0;iNote<127;++iNote)
1703 f -= fFreq;
if (f<0) f=-f;
1715int muGuessChord(
const int *pNoteStatus,
const int channel,
const int lowRange,
const int highRange) {
1719 int startNote = 999;
1722 int chordAdditions = 0;
1728 for(i=lowRange;i<=highRange;++i) {
1729 if (pNoteStatus[channel*128 + i]) {
1735 if ((i%12) < startNote) {
1741 if (lowestNote == 999) {
1747 if (octave[startNote+3] && octave[startNote+8]) {
1748 chordRoot = startNote+8;
1750 }
else if (octave[startNote+5] && octave[startNote+9]) {
1751 chordRoot = startNote+5;
1753 }
else if (octave[startNote+4] && octave[startNote+7]) {
1754 chordRoot = startNote;
1756 }
else if (octave[startNote+4] && octave[startNote+9]) {
1757 chordRoot = startNote+9;
1759 }
else if (octave[startNote+5] && octave[startNote+8]) {
1760 chordRoot = startNote+5;
1762 }
else if (octave[startNote+3] && octave[startNote+7]) {
1763 chordRoot = startNote;
1765 }
else if (octave[startNote+3] && octave[startNote+6]) {
1766 chordRoot = lowestNote;
1768 }
else if (octave[startNote+6] && octave[startNote+9]) {
1769 chordRoot = lowestNote;
1771 }
else if (octave[startNote+4] && octave[startNote+8]) {
1772 chordRoot = lowestNote;
1775 if (octave[chordRoot + 10]) {
1778 if (octave[chordRoot + 11]) {
1781 if (octave[chordRoot + 2]) {
1787 if (chordType == 0) {
1791 return chordRoot | chordType | chordAdditions | (lowestNote<<16);
1798 if (root < 0 || root > 11) {
1802 if (bass < 0 || bass > 11) {
1806 strcopy(str, szNoteName[root]);
1815 strcat(str,
" aug");
1818 strcat(str,
" dim");
1834 strcat(str, szNoteName[bass]);
int midiTrackAddText(MidiFile *_pMF, int iTrack, MidiTextInfo iType, const char *pTxt)
float muGetFreqFromNote(int iNote)
int midiTrackAddRest(MidiFile *_pMF, int iTrack, int iLength, int bOverridePPQN)
int muGetMetaName(char *pName, MidiMetaInfo iEvent)
struct _MidiFileInternal MidiFileInternal
int midiTrackAddControlChange(MidiFile *pMF, int iTrack, MidiControlCommand iCCType, int iParam)
int muGetMIDIMsgName(char *pName, MidiMessage iMsg)
int midiTrackSetKeyPressure(MidiFile *pMF, int iTrack, int iNote, int iAftertouch)
int midiSongAddSimpleTimeSig(MidiFile *_pMF, int iTrack, int iNom, int iDenom)
int midiTrackAddNote(MidiFile *_pMF, int iTrack, int iNote, int iLength, int iVol, int bAutoInc, int bOverrideLength)
int muGetKeySigName(char *pName, MidiNote iKey)
int muGetNoteFromName(const char *pName)
int muGuessChord(const int *pNoteStatus, const int channel, const int lowRange, const int highRange)
int midiFileGetPPQN(const MidiFile *_pMF)
int midiTrackAddRaw(MidiFile *_pMF, int iTrack, int data_sz, const BYTE *pData, int bMovePtr, int dt)
int midiFileSetPPQN(MidiFile *_pMF, int PPQN)
int midiTrackGetEndPos(MidiFile *_pMF, int iTrack)
int midiSongAddTempo(MidiFile *_pMF, int iTrack, int iTempo)
int midiFileSetVersion(MidiFile *_pMF, int iVersion)
MidiFile * midiFileOpen(const char *pFilename)
int muGetNoteFromFreq(float fFreq)
int muGetControlName(char *pName, MidiControlCommand iCC)
int midiReadGetNextMessage(const MidiFile *_pMF, int iTrack, MidiMessagePayload *pMsg)
int midiSongAddTimeSig(MidiFile *_pMF, int iTrack, int iNom, int iDenom, int iClockInMetroTick, int iNotated32nds)
char * muGetChordName(char *str, int chord)
void midiReadInitMessage(MidiMessagePayload *pMsg)
int midiTrackSetPitchWheel(MidiFile *pMF, int iTrack, int iWheelPos)
int midiFileGetVersion(const MidiFile *_pMF)
struct _MidiFileTrack MidiFileTrack
struct _MidiHeader MidiHeader
int midiTrackAddMsg(MidiFile *_pMF, int iTrack, MidiMessage iMsg, int iParam1, int iParam2)
#define IsChannelValid(_x)
struct _MidiLastNote MidiLastNote
int muGetInstrumentName(char *pName, int iInstr)
#define IsMessageValid(_x)
int midiSongAddMIDIPort(MidiFile *_pMF, int iTrack, int iPort)
#define IsFilePtrValid(pMF)
MidiFile * midiFileCreate(const char *pFilename, int bOverwriteIfExists)
char * muGetNameFromNote(char *pStr, int iNote)
char * strcopy(char *_dest, const char *_source)
int midiFileSyncTracks(MidiFile *_pMF, int iTrack1, int iTrack2)
int midiSongAddEndSequence(MidiFile *_pMF, int iTrack)
int midiFileFlushTrack(MidiFile *_pMF, int iTrack, int bFlushToEnd, DWORD dwEndTimePos)
int muGetTextName(char *pName, MidiTextInfo iEvent)
int midiFileSetTracksDefaultChannel(MidiFile *_pMF, int iTrack, int iChannel)
int midiSongAddSMPTEOffset(MidiFile *_pMF, int iTrack, int iHours, int iMins, int iSecs, int iFrames, int iFFrames)
int midiTrackIncTime(MidiFile *_pMF, int iTrack, int iDeltaTime, int bOverridePPQN)
int midiTrackAddProgramChange(MidiFile *pMF, int iTrack, int iInstrPatch)
int midiTrackChangeKeyPressure(MidiFile *pMF, int iTrack, int iDeltaPressure)
int midiFileGetTracksDefaultChannel(const MidiFile *_pMF, int iTrack)
int midiSongAddKeySig(MidiFile *_pMF, int iTrack, MidiNote iKey)
int midiReadGetNumTracks(const MidiFile *_pMF)
void midiReadFreeMessage(MidiMessagePayload *pMsg)
int muGetDrumName(char *pName, int iInstr)
int midiFileClose(MidiFile *_pMF)
enum _MidiMetaInfo MidiMetaInfo
#define MIDI_DURATION_MINIM
#define MIDI_DURATION_DOTTED_SEMIQUAVER
#define MIDI_DURATION_DOTTED_QUAVER
#define MIDI_DURATION_QUAVER
#define MIDI_DURATION_TRIPLE_CROCHET
struct _MidiMessagePayload MidiMessagePayload
#define MIDI_DURATION_SEMIQUAVER
#define MIDI_DURATION_BREVE
#define MIDI_VERSION_DEFAULT
enum _MidiMessage MidiMessage
#define MIDI_DURATION_DOTTED_SEMIDEMIQUAVER
#define MIDI_DURATION_DOTTED_MINIM
enum _ControlCommand MidiControlCommand
#define MAX_TRACK_POLYPHONY
#define MIDI_WHEEL_CENTRE
enum _MidiTextInfo MidiTextInfo
#define MIDI_DURATION_SEMIDEMIQUAVER
#define MIDI_PPQN_DEFAULT
#define MIDI_DURATION_DOTTED_CROCHET
@ metaInfoSequencerSpecific
#define cpy(ticks, adrmode)
MidiFileTrack Track[MAX_MIDI_TRACKS]
MidiLastNote LastNote[MAX_TRACK_POLYPHONY]
MidiControlCommand iControl
union _MidiMessagePayload::_MsgData MsgData
char version[MAX_TEMPORARY_STORAGE]
struct _MidiMessagePayload::_MsgData::_NoteOff NoteOff
struct _MidiMessagePayload::_MsgData::_SysEx SysEx
struct _MidiMessagePayload::_MsgData::_NoteParameter NoteParameter
struct _MidiMessagePayload::_MsgData::_MetaEvent MetaEvent
struct _MidiMessagePayload::_MsgData::_NoteKeyPressure NoteKeyPressure
struct _MidiMessagePayload::_MsgData::_PitchWheel PitchWheel
struct _MidiMessagePayload::_MsgData::_ChangeProgram ChangeProgram
struct _MidiMessagePayload::_MsgData::_ChangePressure ChangePressure
struct _MidiMessagePayload::_MsgData::_NoteOn NoteOn