Implemented a MIDI plug-in

CQTexperiment
Chris Moeller 2013-10-15 07:49:53 -07:00
parent ab97f832ed
commit 842932c322
47 changed files with 7040 additions and 0 deletions

View File

@ -62,6 +62,7 @@ td.icon { width: auto; }
<li>Apple Lossless</li>
<li>WMA Standard, Pro, Lossless, and Voice</li>
<li>TrueAudio</li>
<li>MIDI Sequences</li>
<li>Sequenced Module formats (IT, XM, S3M, MOD, STM, PTM, MTM, 669, PSM, AM, J2B, DSM, AMF, OKT/OKTA, and UMX)</li>
<li>Emulated Console formats supported by the Game_Music_Emu library (AY, GBS, HES, KSS, NSF/NSFE, SAP, SGC, SPC, and VGM/VGZ)</li>
<li>Many Emulated Console formats utilizing the PSF format (PSF, PSF2, SSF, DSF, QSF, GSF, NCSF, 2SF, and their respective mini variants)</li>

View File

@ -179,6 +179,7 @@
838491871808591F00E7332D /* NDHotKey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; };
838491881808593200E7332D /* NDHotKey.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; };
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; };
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; };
83E5E54C18087CA5001F3284 /* miniModeOffTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */; };
83E5E54D18087CA5001F3284 /* miniModeOnTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */; };
@ -464,6 +465,20 @@
remoteGlobalIDString = 32F1615514E6BB3B00D6AB2F;
remoteInfo = NDHotKey;
};
83B066A0180D5669008E3612 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83B0669C180D5668008E3612 /* MIDI.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 83B06687180D5668008E3612;
remoteInfo = MIDI;
};
83B06702180D5776008E3612 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83B0669C180D5668008E3612 /* MIDI.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 83B06686180D5668008E3612;
remoteInfo = MIDI;
};
83BCB8D817FC96F800760340 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8360EF0017F92B23005208A4 /* HighlyComplete.xcodeproj */;
@ -531,6 +546,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */,
8375B36517FFEF130092A79F /* Opus.bundle in CopyFiles */,
8359009D17FF06570060F3ED /* ArchiveSource.bundle in CopyFiles */,
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */,
@ -816,6 +832,7 @@
838491791808585C00E7332D /* NDHotKey.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = NDHotKey.xcodeproj; path = Frameworks/NDHotKey/NDHotKey.xcodeproj; sourceTree = "<group>"; };
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; };
83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = "<group>"; };
83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOffTemplate.pdf; path = Images/miniModeOffTemplate.pdf; sourceTree = "<group>"; };
83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOnTemplate.pdf; path = Images/miniModeOnTemplate.pdf; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
@ -1119,6 +1136,7 @@
17C808660C3BD0F8005707C4 /* CoreAudio.xcodeproj */,
8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */,
8375B05117FFEA400092A79F /* Opus.xcodeproj */,
83B0669C180D5668008E3612 /* MIDI.xcodeproj */,
);
name = PlugIns;
sourceTree = "<group>";
@ -1484,6 +1502,14 @@
name = Products;
sourceTree = "<group>";
};
83B0669D180D5668008E3612 /* Products */ = {
isa = PBXGroup;
children = (
83B066A1180D5669008E3612 /* MIDI.bundle */,
);
name = Products;
sourceTree = "<group>";
};
8E07AAEA0AAC90DC00A4B32F /* Preferences */ = {
isa = PBXGroup;
children = (
@ -1616,6 +1642,7 @@
buildRules = (
);
dependencies = (
83B06703180D5776008E3612 /* PBXTargetDependency */,
838491861808591400E7332D /* PBXTargetDependency */,
8375B36217FFEF010092A79F /* PBXTargetDependency */,
8375B36417FFEF010092A79F /* PBXTargetDependency */,
@ -1726,6 +1753,10 @@
ProductGroup = 8E8D40830CBB036600135C1B /* Products */;
ProjectRef = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
},
{
ProductGroup = 83B0669D180D5668008E3612 /* Products */;
ProjectRef = 83B0669C180D5668008E3612 /* MIDI.xcodeproj */;
},
{
ProductGroup = 17C8089F0C3BD1AB005707C4 /* Products */;
ProjectRef = 17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */;
@ -1900,6 +1931,13 @@
remoteRef = 8384917D1808585D00E7332D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
83B066A1180D5669008E3612 /* MIDI.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = MIDI.bundle;
remoteRef = 83B066A0180D5669008E3612 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
8E8D40870CBB036600135C1B /* M3u.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
@ -2213,6 +2251,11 @@
name = NDHotKey;
targetProxy = 838491851808591400E7332D /* PBXContainerItemProxy */;
};
83B06703180D5776008E3612 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = MIDI;
targetProxy = 83B06702180D5776008E3612 /* PBXContainerItemProxy */;
};
83BCB8D917FC96F800760340 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = HighlyComplete;

View File

@ -0,0 +1,342 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
83B066BA180D56B9008E3612 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 83B066B8180D56B9008E3612 /* InfoPlist.strings */; };
83B066F1180D5724008E3612 /* midi_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E3180D5724008E3612 /* midi_container.cpp */; };
83B066F2180D5724008E3612 /* midi_container.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B066E4180D5724008E3612 /* midi_container.h */; settings = {ATTRIBUTES = (Public, ); }; };
83B066F3180D5724008E3612 /* midi_processor_gmf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E5180D5724008E3612 /* midi_processor_gmf.cpp */; };
83B066F4180D5724008E3612 /* midi_processor_helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E6180D5724008E3612 /* midi_processor_helpers.cpp */; };
83B066F5180D5724008E3612 /* midi_processor_hmi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E7180D5724008E3612 /* midi_processor_hmi.cpp */; };
83B066F6180D5724008E3612 /* midi_processor_hmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E8180D5724008E3612 /* midi_processor_hmp.cpp */; };
83B066F7180D5724008E3612 /* midi_processor_lds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066E9180D5724008E3612 /* midi_processor_lds.cpp */; };
83B066F8180D5724008E3612 /* midi_processor_mids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066EA180D5724008E3612 /* midi_processor_mids.cpp */; };
83B066F9180D5724008E3612 /* midi_processor_mus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066EB180D5724008E3612 /* midi_processor_mus.cpp */; };
83B066FA180D5724008E3612 /* midi_processor_riff_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066EC180D5724008E3612 /* midi_processor_riff_midi.cpp */; };
83B066FB180D5724008E3612 /* midi_processor_standard_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066ED180D5724008E3612 /* midi_processor_standard_midi.cpp */; };
83B066FC180D5724008E3612 /* midi_processor_syx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066EE180D5724008E3612 /* midi_processor_syx.cpp */; };
83B066FD180D5724008E3612 /* midi_processor_xmi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B066EF180D5724008E3612 /* midi_processor_xmi.cpp */; };
83B066FE180D5724008E3612 /* midi_processor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B066F0180D5724008E3612 /* midi_processor.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
83B066AC180D56B9008E3612 /* midi_processing.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = midi_processing.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83B066B7180D56B9008E3612 /* midi_processing-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "midi_processing-Info.plist"; sourceTree = "<group>"; };
83B066B9180D56B9008E3612 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83B066E3180D5724008E3612 /* midi_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_container.cpp; sourceTree = "<group>"; };
83B066E4180D5724008E3612 /* midi_container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midi_container.h; sourceTree = "<group>"; };
83B066E5180D5724008E3612 /* midi_processor_gmf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_gmf.cpp; sourceTree = "<group>"; };
83B066E6180D5724008E3612 /* midi_processor_helpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_helpers.cpp; sourceTree = "<group>"; };
83B066E7180D5724008E3612 /* midi_processor_hmi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_hmi.cpp; sourceTree = "<group>"; };
83B066E8180D5724008E3612 /* midi_processor_hmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_hmp.cpp; sourceTree = "<group>"; };
83B066E9180D5724008E3612 /* midi_processor_lds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_lds.cpp; sourceTree = "<group>"; };
83B066EA180D5724008E3612 /* midi_processor_mids.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_mids.cpp; sourceTree = "<group>"; };
83B066EB180D5724008E3612 /* midi_processor_mus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_mus.cpp; sourceTree = "<group>"; };
83B066EC180D5724008E3612 /* midi_processor_riff_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_riff_midi.cpp; sourceTree = "<group>"; };
83B066ED180D5724008E3612 /* midi_processor_standard_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_standard_midi.cpp; sourceTree = "<group>"; };
83B066EE180D5724008E3612 /* midi_processor_syx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_syx.cpp; sourceTree = "<group>"; };
83B066EF180D5724008E3612 /* midi_processor_xmi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi_processor_xmi.cpp; sourceTree = "<group>"; };
83B066F0180D5724008E3612 /* midi_processor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midi_processor.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
83B066A8180D56B9008E3612 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
83B066A2180D56B9008E3612 = {
isa = PBXGroup;
children = (
83B066B5180D56B9008E3612 /* midi_processing */,
83B066AE180D56B9008E3612 /* Frameworks */,
83B066AD180D56B9008E3612 /* Products */,
);
sourceTree = "<group>";
};
83B066AD180D56B9008E3612 /* Products */ = {
isa = PBXGroup;
children = (
83B066AC180D56B9008E3612 /* midi_processing.framework */,
);
name = Products;
sourceTree = "<group>";
};
83B066AE180D56B9008E3612 /* Frameworks */ = {
isa = PBXGroup;
children = (
83B066B1180D56B9008E3612 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
83B066B1180D56B9008E3612 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
);
name = "Other Frameworks";
sourceTree = "<group>";
};
83B066B5180D56B9008E3612 /* midi_processing */ = {
isa = PBXGroup;
children = (
83B066E3180D5724008E3612 /* midi_container.cpp */,
83B066E4180D5724008E3612 /* midi_container.h */,
83B066E5180D5724008E3612 /* midi_processor_gmf.cpp */,
83B066E6180D5724008E3612 /* midi_processor_helpers.cpp */,
83B066E7180D5724008E3612 /* midi_processor_hmi.cpp */,
83B066E8180D5724008E3612 /* midi_processor_hmp.cpp */,
83B066E9180D5724008E3612 /* midi_processor_lds.cpp */,
83B066EA180D5724008E3612 /* midi_processor_mids.cpp */,
83B066EB180D5724008E3612 /* midi_processor_mus.cpp */,
83B066EC180D5724008E3612 /* midi_processor_riff_midi.cpp */,
83B066ED180D5724008E3612 /* midi_processor_standard_midi.cpp */,
83B066EE180D5724008E3612 /* midi_processor_syx.cpp */,
83B066EF180D5724008E3612 /* midi_processor_xmi.cpp */,
83B066F0180D5724008E3612 /* midi_processor.h */,
83B066B6180D56B9008E3612 /* Supporting Files */,
);
path = midi_processing;
sourceTree = "<group>";
};
83B066B6180D56B9008E3612 /* Supporting Files */ = {
isa = PBXGroup;
children = (
83B066B7180D56B9008E3612 /* midi_processing-Info.plist */,
83B066B8180D56B9008E3612 /* InfoPlist.strings */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
83B066A9180D56B9008E3612 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
83B066FE180D5724008E3612 /* midi_processor.h in Headers */,
83B066F2180D5724008E3612 /* midi_container.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
83B066AB180D56B9008E3612 /* midi_processing */ = {
isa = PBXNativeTarget;
buildConfigurationList = 83B066D4180D56B9008E3612 /* Build configuration list for PBXNativeTarget "midi_processing" */;
buildPhases = (
83B066A7180D56B9008E3612 /* Sources */,
83B066A8180D56B9008E3612 /* Frameworks */,
83B066A9180D56B9008E3612 /* Headers */,
83B066AA180D56B9008E3612 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = midi_processing;
productName = midi_processing;
productReference = 83B066AC180D56B9008E3612 /* midi_processing.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83B066A3180D56B9008E3612 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0500;
ORGANIZATIONNAME = "Christopher Snowhill";
};
buildConfigurationList = 83B066A6180D56B9008E3612 /* Build configuration list for PBXProject "midi_processing" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 83B066A2180D56B9008E3612;
productRefGroup = 83B066AD180D56B9008E3612 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
83B066AB180D56B9008E3612 /* midi_processing */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
83B066AA180D56B9008E3612 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83B066BA180D56B9008E3612 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
83B066A7180D56B9008E3612 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83B066F4180D5724008E3612 /* midi_processor_helpers.cpp in Sources */,
83B066F3180D5724008E3612 /* midi_processor_gmf.cpp in Sources */,
83B066FB180D5724008E3612 /* midi_processor_standard_midi.cpp in Sources */,
83B066FC180D5724008E3612 /* midi_processor_syx.cpp in Sources */,
83B066F5180D5724008E3612 /* midi_processor_hmi.cpp in Sources */,
83B066F8180D5724008E3612 /* midi_processor_mids.cpp in Sources */,
83B066F6180D5724008E3612 /* midi_processor_hmp.cpp in Sources */,
83B066F9180D5724008E3612 /* midi_processor_mus.cpp in Sources */,
83B066FA180D5724008E3612 /* midi_processor_riff_midi.cpp in Sources */,
83B066F1180D5724008E3612 /* midi_container.cpp in Sources */,
83B066FD180D5724008E3612 /* midi_processor_xmi.cpp in Sources */,
83B066F7180D5724008E3612 /* midi_processor_lds.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
83B066B8180D56B9008E3612 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
83B066B9180D56B9008E3612 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
83B066D2180D56B9008E3612 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
83B066D3180D56B9008E3612 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
};
name = Release;
};
83B066D5180D56B9008E3612 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = "midi_processing/midi_processing-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = framework;
};
name = Debug;
};
83B066D6180D56B9008E3612 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = "midi_processing/midi_processing-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = framework;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
83B066A6180D56B9008E3612 /* Build configuration list for PBXProject "midi_processing" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83B066D2180D56B9008E3612 /* Debug */,
83B066D3180D56B9008E3612 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83B066D4180D56B9008E3612 /* Build configuration list for PBXNativeTarget "midi_processing" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83B066D5180D56B9008E3612 /* Debug */,
83B066D6180D56B9008E3612 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 83B066A3180D56B9008E3612 /* Project object */;
}

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,244 @@
#ifndef _MIDI_CONTAINER_H_
#define _MIDI_CONTAINER_H_
#include <stdint.h>
#include <string>
#include <vector>
struct midi_event
{
enum
{
max_static_data_count = 16
};
enum event_type
{
note_off = 0,
note_on,
polyphonic_aftertouch,
control_change,
program_change,
channel_aftertouch,
pitch_wheel,
extended
};
unsigned long m_timestamp;
event_type m_type;
unsigned m_channel;
unsigned long m_data_count;
uint8_t m_data[max_static_data_count];
std::vector<uint8_t> m_ext_data;
midi_event() : m_timestamp(0), m_type(note_off), m_channel(0), m_data_count(0) { }
midi_event( const midi_event & p_in );
midi_event( unsigned long p_timestamp, event_type p_type, unsigned p_channel, const uint8_t * p_data, std::size_t p_data_count );
unsigned long get_data_count() const;
void copy_data( uint8_t * p_out, unsigned long p_offset, unsigned long p_count ) const;
};
class midi_track
{
std::vector<midi_event> m_events;
public:
midi_track() { }
midi_track(const midi_track & p_in);
void add_event( const midi_event & p_event );
std::size_t get_count() const;
const midi_event & operator [] ( std::size_t p_index ) const;
void remove_event( unsigned long index );
};
struct tempo_entry
{
unsigned long m_timestamp;
unsigned m_tempo;
tempo_entry() : m_timestamp(0), m_tempo(0) { }
tempo_entry(unsigned long p_timestamp, unsigned p_tempo);
};
class tempo_map
{
std::vector<tempo_entry> m_entries;
public:
void add_tempo( unsigned p_tempo, unsigned long p_timestamp );
unsigned long timestamp_to_ms( unsigned long p_timestamp, unsigned p_dtx ) const;
std::size_t get_count() const;
const tempo_entry & operator [] ( std::size_t p_index ) const;
};
struct system_exclusive_entry
{
std::size_t m_port;
std::size_t m_offset;
std::size_t m_length;
system_exclusive_entry() : m_port(0), m_offset(0), m_length(0) { }
system_exclusive_entry(const system_exclusive_entry & p_in);
system_exclusive_entry(std::size_t p_port, std::size_t p_offset, std::size_t p_length);
};
class system_exclusive_table
{
std::vector<uint8_t> m_data;
std::vector<system_exclusive_entry> m_entries;
public:
unsigned add_entry( const uint8_t * p_data, std::size_t p_size, std::size_t p_port );
void get_entry( unsigned p_index, const uint8_t * & p_data, std::size_t & p_size, std::size_t & p_port );
};
struct midi_stream_event
{
unsigned long m_timestamp;
uint32_t m_event;
midi_stream_event() : m_timestamp(0), m_event(0) { }
midi_stream_event(unsigned long p_timestamp, uint32_t p_event);
};
struct midi_meta_data_item
{
unsigned long m_timestamp;
std::string m_name;
std::string m_value;
midi_meta_data_item() : m_timestamp(0) { }
midi_meta_data_item(const midi_meta_data_item & p_in);
midi_meta_data_item(unsigned long p_timestamp, const char * p_name, const char * p_value);
};
class midi_meta_data
{
std::vector<midi_meta_data_item> m_data;
public:
midi_meta_data() { }
void add_item( const midi_meta_data_item & p_item );
void append( const midi_meta_data & p_data );
bool get_item( const char * p_name, midi_meta_data_item & p_out ) const;
std::size_t get_count() const;
const midi_meta_data_item & operator [] ( std::size_t p_index ) const;
};
class midi_container
{
public:
enum
{
clean_flag_emidi = 1 << 0,
clean_flag_instruments = 1 << 1,
clean_flag_banks = 1 << 2,
};
private:
unsigned m_form;
unsigned m_dtx;
std::vector<uint64_t> m_channel_mask;
std::vector<tempo_map> m_tempo_map;
std::vector<midi_track> m_tracks;
std::vector<uint8_t> m_port_numbers;
std::vector< std::vector< std::string > > m_device_names;
midi_meta_data m_extra_meta_data;
std::vector<unsigned long> m_timestamp_end;
std::vector<unsigned long> m_timestamp_loop_start;
std::vector<unsigned long> m_timestamp_loop_end;
unsigned long timestamp_to_ms( unsigned long p_timestamp, unsigned long p_subsong ) const;
/*
* Normalize port numbers properly
*/
template <typename T> void limit_port_number(T & number)
{
for ( unsigned i = 0; i < m_port_numbers.size(); i++ )
{
if ( m_port_numbers[ i ] == number )
{
number = i;
return;
}
}
m_port_numbers.push_back( number );
number = m_port_numbers.size() - 1;
}
template <typename T> void limit_port_number(T & number) const
{
for ( unsigned i = 0; i < m_port_numbers.size(); i++ )
{
if ( m_port_numbers[ i ] == number )
{
number = i;
return;
}
}
}
public:
midi_container() { m_device_names.resize( 16 ); }
void initialize( unsigned p_form, unsigned p_dtx );
void add_track( const midi_track & p_track );
void add_track_event( std::size_t p_track_index, const midi_event & p_event );
/*
* These functions are really only designed to merge and later remove System Exclusive message dumps
*/
void merge_tracks( const midi_container & p_source );
void set_track_count( unsigned count );
void set_extra_meta_data( const midi_meta_data & p_data );
/*
* Blah.
* Hack 0: Remove channel 16
* Hack 1: Remove channels 11-16
*/
void apply_hackfix( unsigned hack );
void serialize_as_stream( unsigned long subsong, std::vector<midi_stream_event> & p_stream, system_exclusive_table & p_system_exclusive, unsigned clean_flags ) const;
void serialize_as_standard_midi_file( std::vector<uint8_t> & p_midi_file ) const;
void promote_to_type1();
unsigned long get_subsong_count() const;
unsigned long get_subsong( unsigned long p_index ) const;
unsigned long get_timestamp_end(unsigned long subsong, bool ms = false) const;
unsigned get_format() const;
unsigned get_track_count() const;
unsigned get_channel_count(unsigned long subsong) const;
unsigned long get_timestamp_loop_start(unsigned long subsong, bool ms = false) const;
unsigned long get_timestamp_loop_end(unsigned long subsong, bool ms = false) const;
void get_meta_data( unsigned long subsong, midi_meta_data & p_out );
void scan_for_loops( bool p_xmi_loops, bool p_marker_loops );
static void encode_delta( std::vector<uint8_t> & p_out, unsigned long delta );
};
#endif

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>NoWork-Inc.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2013 Christopher Snowhill. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,61 @@
#ifndef _MIDI_PROCESSORS_H_
#define _MIDI_PROCESSORS_H_
#include "midi_container.h"
#ifndef _countof
template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];
#define _countof( array ) (sizeof( _ArraySizeHelper( array ) ))
#endif
class midi_processor
{
static const uint8_t end_of_track[2];
static const uint8_t loop_start[11];
static const uint8_t loop_end[9];
static const uint8_t hmp_default_tempo[5];
static const uint8_t xmi_default_tempo[5];
static const uint8_t mus_default_tempo[5];
static const uint8_t mus_controllers[15];
static const uint8_t lds_default_tempo[5];
static int decode_delta( std::vector<uint8_t>::const_iterator & it );
static unsigned decode_hmp_delta( std::vector<uint8_t>::const_iterator & it );
static unsigned decode_xmi_delta( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end );
static bool is_standard_midi( std::vector<uint8_t> const& p_file );
static bool is_riff_midi( std::vector<uint8_t> const& p_file );
static bool is_hmp( std::vector<uint8_t> const& p_file );
static bool is_hmi( std::vector<uint8_t> const& p_file );
static bool is_xmi( std::vector<uint8_t> const& p_file );
static bool is_mus( std::vector<uint8_t> const& p_file );
static bool is_mids( std::vector<uint8_t> const& p_file );
static bool is_lds( std::vector<uint8_t> const& p_file, const char * p_extension );
static bool is_gmf( std::vector<uint8_t> const& p_file );
static bool is_syx( std::vector<uint8_t> const& p_file );
static bool process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool needs_end_marker );
static bool process_standard_midi( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_riff_midi( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_hmp( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_hmi( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_xmi( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_mus( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_mids( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_lds( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_gmf( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_syx( std::vector<uint8_t> const& p_file, midi_container & p_out );
public:
static bool process_file( std::vector<uint8_t> const& p_file, const char * p_extension, midi_container & p_out );
static bool process_syx_file( std::vector<uint8_t> const& p_file, midi_container & p_out );
};
#endif

View File

@ -0,0 +1,52 @@
#include "midi_processor.h"
bool midi_processor::is_gmf( std::vector<uint8_t> const& p_file )
{
if ( p_file.size() < 32 ) return false;
if ( p_file[ 0 ] != 'G' || p_file[ 1 ] != 'M' || p_file[ 2 ] != 'F' || p_file[ 3 ] != 1 ) return false;
return true;
}
bool midi_processor::process_gmf( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
uint8_t buffer[10];
p_out.initialize( 0, 0xC0 );
uint16_t tempo = ( p_file[ 4 ] << 8 ) | p_file[ 5 ];
uint32_t tempo_scaled = tempo * 100000;
midi_track track;
buffer[0] = 0xFF;
buffer[1] = 0x51;
buffer[2] = tempo_scaled >> 16;
buffer[3] = tempo_scaled >> 8;
buffer[4] = tempo_scaled;
track.add_event( midi_event( 0, midi_event::extended, 0, buffer, 5 ) );
buffer[0] = 0xF0;
buffer[1] = 0x41;
buffer[2] = 0x10;
buffer[3] = 0x16;
buffer[4] = 0x12;
buffer[5] = 0x7F;
buffer[6] = 0x00;
buffer[7] = 0x00;
buffer[8] = 0x01;
buffer[9] = 0xF7;
track.add_event( midi_event( 0, midi_event::extended, 0, buffer, 10 ) );
buffer[0] = 0xFF;
buffer[1] = 0x2F;
track.add_event( midi_event( 0, midi_event::extended, 0, buffer, 2 ) );
p_out.add_track( track );
std::vector<uint8_t>::const_iterator it = p_file.begin() + 7;
return process_standard_midi_track( it, p_file.end(), p_out, false );
}

View File

@ -0,0 +1,68 @@
#include "midi_processor.h"
const uint8_t midi_processor::end_of_track[2] = {0xFF, 0x2F};
const uint8_t midi_processor::loop_start[11] = {0xFF, 0x06, 'l', 'o', 'o', 'p', 'S', 't', 'a', 'r', 't'};
const uint8_t midi_processor::loop_end[9] = {0xFF, 0x06, 'l', 'o', 'o', 'p', 'E', 'n', 'd'};
int midi_processor::decode_delta( std::vector<uint8_t>::const_iterator & it )
{
int delta = 0;
unsigned char byte;
do
{
byte = *it++;
delta = ( delta << 7 ) + ( byte & 0x7F );
}
while ( byte & 0x80 );
return delta;
}
bool midi_processor::process_file( std::vector<uint8_t> const& p_file, const char * p_extension, midi_container & p_out )
{
if ( is_standard_midi( p_file ) )
{
return process_standard_midi( p_file, p_out );
}
else if ( is_riff_midi( p_file ) )
{
return process_riff_midi( p_file, p_out );
}
else if ( is_hmp( p_file ) )
{
return process_hmp( p_file, p_out );
}
else if ( is_hmi( p_file ) )
{
return process_hmi( p_file, p_out );
}
else if ( is_xmi( p_file ) )
{
return process_xmi( p_file, p_out );
}
else if ( is_mus( p_file ) )
{
return process_mus( p_file, p_out );
}
else if ( is_mids( p_file ) )
{
return process_mids( p_file, p_out );
}
else if ( is_lds( p_file, p_extension ) )
{
return process_lds( p_file, p_out );
}
else if ( is_gmf( p_file ) )
{
return process_gmf( p_file, p_out );
}
else return false;
}
bool midi_processor::process_syx_file( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
if ( is_syx( p_file ) )
{
return process_syx( p_file, p_out );
}
else return false;
}

View File

@ -0,0 +1,209 @@
#include "midi_processor.h"
bool midi_processor::is_hmi( std::vector<uint8_t> const& p_file )
{
if ( p_file.size() < 12 ) return false;
if ( p_file[ 0 ] != 'H' || p_file[ 1 ] != 'M' || p_file[ 2 ] != 'I' || p_file[ 3 ] != '-' ||
p_file[ 4 ] != 'M' || p_file[ 5 ] != 'I' || p_file[ 6 ] != 'D' || p_file[ 7 ] != 'I' ||
p_file[ 8 ] != 'S' || p_file[ 9 ] != 'O' || p_file[ 10 ] != 'N' || p_file[ 11 ] != 'G' ) return false;
return true;
}
bool midi_processor::process_hmi( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
std::vector<uint8_t> buffer;
std::vector<uint8_t>::const_iterator it = p_file.begin() + 0xE4;
uint32_t track_count = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
uint32_t track_table_offset = it[ 4 ] | ( it[ 5 ] << 8 ) | ( it[ 6 ] << 16 ) | ( it[ 7 ] << 24 );
it = p_file.begin() + track_table_offset;
std::vector<uint32_t> track_offsets;
track_offsets.resize( track_count );
for ( unsigned i = 0; i < track_count; ++i )
{
track_offsets[ i ] = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
}
p_out.initialize( 1, 0xC0 );
{
midi_track track;
track.add_event( midi_event( 0, midi_event::extended, 0, hmp_default_tempo, _countof( hmp_default_tempo ) ) );
track.add_event( midi_event( 0, midi_event::extended, 0, end_of_track, _countof( end_of_track ) ) );
p_out.add_track( track );
}
for ( unsigned i = 0; i < track_count; ++i )
{
unsigned track_offset = track_offsets[ i ];
unsigned long track_length;
if ( i + 1 < track_count )
{
track_length = track_offsets[ i + 1 ] - track_offset;
}
else
{
track_length = p_file.size() - track_offset;
}
std::vector<uint8_t>::const_iterator track_body = p_file.begin() + track_offset;
std::vector<uint8_t>::const_iterator track_end = track_body + track_length;
if ( track_length < 13 ) return false;
if ( track_body[ 0 ] != 'H' || track_body[ 1 ] != 'M' || track_body[ 2 ] != 'I' || track_body[ 3 ] != '-' ||
track_body[ 4 ] != 'M' || track_body[ 5 ] != 'I' || track_body[ 6 ] != 'D' || track_body[ 7 ] != 'I' ||
track_body[ 8 ] != 'T' || track_body[ 9 ] != 'R' || track_body[ 10 ] != 'A' || track_body[ 11 ] != 'C' ||
track_body[ 12 ] != 'K' ) return false;
midi_track track;
unsigned current_timestamp = 0;
unsigned char last_event_code = 0xFF;
unsigned last_event_timestamp = 0;
if ( track_length < 0x4B + 4 ) return false;
uint32_t meta_offset = track_body[ 0x4B ] | ( track_body[ 0x4C ] << 8 ) | ( track_body[ 0x4D ] << 16 ) | ( track_body[ 0x4E ] << 24 );
if ( meta_offset && meta_offset + 1 < track_length )
{
buffer.resize( 2 );
std::copy( track_body + meta_offset, track_body + meta_offset + 2, buffer.begin() );
unsigned meta_size = buffer[ 1 ];
if ( meta_offset + 2 + meta_size > track_length ) return false;
buffer.resize( meta_size + 2 );
std::copy( track_body + meta_offset + 2, track_body + meta_offset + 2 + meta_size, buffer.begin() + 2 );
while ( meta_size > 0 && buffer[ meta_size + 1 ] == ' ' ) --meta_size;
if ( meta_size > 0 )
{
buffer[ 0 ] = 0xFF;
buffer[ 1 ] = 0x01;
track.add_event( midi_event( 0, midi_event::extended, 0, &buffer[0], meta_size + 2 ) );
}
}
if ( track_length < 0x57 + 4 ) return false;
uint32_t track_data_offset = track_body[ 0x57 ] | ( track_body[ 0x58 ] << 8 ) | ( track_body[ 0x59 ] << 16 ) | ( track_body[ 0x5A ] << 24 );
it = track_body + track_data_offset;
buffer.resize( 3 );
while ( it < track_end )
{
int delta = decode_delta( it );
if ( delta > 0xFFFF || delta < 0 )
{
current_timestamp = last_event_timestamp;
/*console::formatter() << "[foo_midi] Large HMI delta detected, shunting.";*/
}
else
{
current_timestamp += delta;
if ( current_timestamp > last_event_timestamp )
{
last_event_timestamp = current_timestamp;
}
}
buffer[ 0 ] = *it++;
if ( buffer[ 0 ] == 0xFF )
{
last_event_code = 0xFF;
buffer[ 1 ] = *it++;
int meta_count = decode_delta( it );
if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid HMI meta message" );*/
buffer.resize( meta_count + 2 );
std::copy( it, it + meta_count, buffer.begin() + 2 );
it += meta_count;
if ( buffer[ 1 ] == 0x2F && last_event_timestamp > current_timestamp )
{
current_timestamp = last_event_timestamp;
}
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &buffer[0], meta_count + 2 ) );
if ( buffer[ 1 ] == 0x2F ) break;
}
else if ( buffer[ 0 ] == 0xF0 )
{
last_event_code = 0xFF;
int system_exclusive_count = decode_delta( it );
if ( system_exclusive_count < 0 ) return false; /*throw exception_io_data( "Invalid HMI System Exclusive message" );*/
buffer.resize( system_exclusive_count + 1 );
std::copy( it, it + system_exclusive_count, buffer.begin() + 1 );
it += system_exclusive_count;
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &buffer[0], system_exclusive_count + 1 ) );
}
else if ( buffer[ 0 ] == 0xFE )
{
last_event_code = 0xFF;
buffer[ 1 ] = *it++;
if ( buffer[ 1 ] == 0x10 )
{
it += 2;
buffer[ 2 ] = *it++;
it += buffer[ 2 ] + 4;
}
else if ( buffer[ 1 ] == 0x12 )
{
it += 2;
}
else if ( buffer[ 1 ] == 0x13 )
{
it += 10;
}
else if ( buffer[ 1 ] == 0x14 )
{
it += 2;
p_out.add_track_event( 0, midi_event( current_timestamp, midi_event::extended, 0, loop_start, _countof( loop_start ) ) );
}
else if ( buffer[ 1 ] == 0x15 )
{
it += 6;
p_out.add_track_event( 0, midi_event( current_timestamp, midi_event::extended, 0, loop_end, _countof( loop_end ) ) );
}
else return false; /*throw exception_io_data( "Unexpected HMI meta event" );*/
}
else if ( buffer[ 0 ] <= 0xEF )
{
unsigned bytes_read = 1;
if ( buffer[ 0 ] >= 0x80 )
{
buffer[ 1 ] = *it++;
last_event_code = buffer[ 0 ];
}
else
{
if ( last_event_code == 0xFF ) return false; /*throw exception_io_data( "HMI used shortened event after Meta or SysEx message" );*/
buffer[ 1 ] = buffer[ 0 ];
buffer[ 0 ] = last_event_code;
}
midi_event::event_type type = (midi_event::event_type)( ( buffer[ 0 ] >> 4 ) - 8 );
unsigned channel = buffer[ 0 ] & 0x0F;
if ( type != midi_event::program_change && type != midi_event::channel_aftertouch )
{
buffer[ 2 ] = *it++;
bytes_read = 2;
}
track.add_event( midi_event( current_timestamp, type, channel, &buffer[ 1 ], bytes_read ) );
if ( type == midi_event::note_on )
{
buffer[ 2 ] = 0x00;
int note_length = decode_delta( it );
if ( note_length < 0 ) return false; /*throw exception_io_data( "Invalid HMI note message" );*/
unsigned note_end_timestamp = current_timestamp + note_length;
if ( note_end_timestamp > last_event_timestamp ) last_event_timestamp = note_end_timestamp;
track.add_event( midi_event( note_end_timestamp, midi_event::note_on, channel, &buffer[1], bytes_read ) );
}
}
else return false; /*throw exception_io_data( "Unexpected HMI status code" );*/
}
p_out.add_track( track );
}
return true;
}

View File

@ -0,0 +1,147 @@
#include "midi_processor.h"
const uint8_t midi_processor::hmp_default_tempo[5] = {0xFF, 0x51, 0x18, 0x80, 0x00};
bool midi_processor::is_hmp( std::vector<uint8_t> const& p_file )
{
if ( p_file.size() < 8 ) return false;
if ( p_file[ 0 ] != 'H' || p_file[ 1 ] != 'M' || p_file[ 2 ] != 'I' || p_file[ 3 ] != 'M' ||
p_file[ 4 ] != 'I' || p_file[ 5 ] != 'D' || p_file[ 6 ] != 'I' ||
( p_file[ 7 ] != 'P' && p_file[ 7 ] != 'R' ) ) return false;
return true;
}
unsigned midi_processor::decode_hmp_delta( std::vector<uint8_t>::const_iterator & it )
{
unsigned delta = 0;
unsigned shift = 0;
unsigned char byte;
do
{
byte = *it++;
delta = delta + ( ( byte & 0x7F ) << shift );
shift += 7;
}
while ( !( byte & 0x80 ) );
return delta;
}
bool midi_processor::process_hmp( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
bool is_funky = p_file[ 7 ] == 'R';
uint8_t track_count_8;
uint16_t dtx = 0xC0;
std::vector<uint8_t>::const_iterator it = p_file.begin() + ( is_funky ? 0x1A : 0x30 );
track_count_8 = *it;
if ( is_funky )
{
dtx = ( p_file[ 0x4C ] << 16 ) | p_file[ 0x4D ];
}
p_out.initialize( 1, dtx );
{
midi_track track;
track.add_event( midi_event( 0, midi_event::extended, 0, hmp_default_tempo, _countof( hmp_default_tempo ) ) );
track.add_event( midi_event( 0, midi_event::extended, 0, end_of_track, _countof( end_of_track ) ) );
p_out.add_track( track );
}
uint8_t buffer[ 4 ];
buffer[ 0 ] = *it++;
while ( it < p_file.end() )
{
if ( buffer[ 0 ] != 0xFF )
{
buffer[ 0 ] = *it++;
continue;
}
buffer[ 1 ] = *it++;
if ( buffer[ 1 ] != 0x2F )
{
buffer[ 0 ] = buffer[ 1 ];
continue;
}
break;
}
it += ( is_funky ? 3 : 5 );
unsigned track_count = track_count_8;
for ( unsigned i = 1; i < track_count; ++i )
{
uint16_t track_size_16;
uint32_t track_size_32;
if ( is_funky )
{
track_size_16 = it[ 0 ] | ( it[ 1 ] << 8 );
it += 2;
track_size_32 = track_size_16 - 4;
if ( p_file.end() - it < track_size_32 + 2 ) break;
it += 2;
}
else
{
track_size_32 = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
track_size_32 -= 12;
if ( p_file.end() - it < track_size_32 + 8 ) break;
it += 4;
}
midi_track track;
unsigned current_timestamp = 0;
std::vector<uint8_t> buffer;
buffer.resize( 3 );
std::vector<uint8_t>::const_iterator track_end = it + track_size_32;
while ( it < track_end )
{
unsigned delta = decode_hmp_delta( it );
current_timestamp += delta;
buffer[ 0 ] = *it++;
if ( buffer[ 0 ] == 0xFF )
{
buffer[ 1 ] = *it++;
int meta_count = decode_delta( it );
if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid HMP meta message" );*/
buffer.resize( meta_count + 2 );
std::copy( it, it + meta_count, buffer.begin() + 2 );
it += meta_count;
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &buffer[0], meta_count + 2 ) );
if ( buffer[ 1 ] == 0x2F ) break;
}
else if ( buffer[ 0 ] >= 0x80 && buffer[ 0 ] <= 0xEF )
{
unsigned bytes_read = 2;
switch ( buffer[ 0 ] & 0xF0 )
{
case 0xC0:
case 0xD0:
bytes_read = 1;
}
std::copy( it, it + bytes_read, buffer.begin() + 1 );
it += bytes_read;
track.add_event( midi_event( current_timestamp, (midi_event::event_type)( ( buffer[ 0 ] >> 4 ) - 8 ), buffer[ 0 ] & 0x0F, &buffer[1], bytes_read ) );
}
else return false; /*throw exception_io_data( "Unexpected status code in HMP track" );*/
}
it = track_end + ( is_funky ? 0 : 4 );
p_out.add_track( track );
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,120 @@
#include "midi_processor.h"
bool midi_processor::is_mids( std::vector<uint8_t> const& p_file )
{
if ( p_file.size() < 8 ) return false;
if ( p_file[ 0 ] != 'R' || p_file[ 1 ] != 'I' || p_file[ 2 ] != 'F' || p_file[ 3 ] != 'F' ) return false;
uint32_t size = p_file[ 4 ] | ( p_file[ 5 ] << 8 ) | ( p_file[ 6 ] << 16 ) | ( p_file[ 7 ] << 24 );
if ( size < 8 || ( p_file.size() < size + 8 ) ) return false;
if ( p_file[ 8 ] != 'M' || p_file[ 9 ] != 'I' || p_file[ 10 ] != 'D' || p_file[ 11 ] != 'S' ||
p_file[ 12 ] != 'f' || p_file[ 13 ] != 'm' || p_file[ 14 ] != 't' || p_file[ 15 ] != ' ' ) return false;
return true;
}
bool midi_processor::process_mids( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
std::vector<uint8_t>::const_iterator it = p_file.begin() + 16;
uint32_t fmt_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
uint32_t time_format = 1;
/*uint32_t max_buffer = 0;*/
uint32_t flags = 0;
if ( fmt_size >= 4 )
{
time_format = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
fmt_size -= 4;
}
if ( fmt_size >= 4 )
{
/*max_buffer = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );*/
it += 4;
fmt_size -= 4;
}
if ( fmt_size >= 4 )
{
flags = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
fmt_size -= 4;
}
it += fmt_size;
if ( fmt_size & 1 ) ++it;
p_out.initialize( 0, time_format );
if ( it[ 0 ] != 'd' || it[ 1 ] != 'a' || it[ 2 ] != 't' || it[ 3 ] != 'a' ) return false; /*throw exception_io_data( "MIDS missing RIFF data chunk" );*/
it += 4;
{
midi_track track;
track.add_event( midi_event( 0, midi_event::extended, 0, end_of_track, _countof( end_of_track ) ) );
p_out.add_track( track );
}
uint32_t data_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
std::vector<uint8_t>::const_iterator body_end = it + data_size;
uint32_t segment_count = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
bool is_eight_byte = !!(flags & 1);
midi_track track;
unsigned current_timestamp = 0;
for ( unsigned i = 0; i < segment_count; ++i )
{
it += 4;
uint32_t segment_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
std::vector<uint8_t>::const_iterator segment_end = it + segment_size;
while ( it < segment_end && it < body_end )
{
uint32_t delta = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
uint32_t event;
current_timestamp += delta;
if ( !is_eight_byte ) it += 4;
event = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 );
it += 4;
if ( event >> 24 == 0x01 )
{
uint8_t buffer[ 5 ] = { 0xFF, 0x51 };
buffer[ 2 ] = (uint8_t)( event >> 16 );
buffer[ 3 ] = (uint8_t)( event >> 8 );
buffer[ 4 ] = (uint8_t)event;
p_out.add_track_event( 0, midi_event( current_timestamp, midi_event::extended, 0, buffer, sizeof( buffer ) ) );
}
else if ( !( event >> 24 ) )
{
unsigned event_code = ( event & 0xF0 ) >> 4;
if ( event_code >= 0x8 && event_code <= 0xE )
{
unsigned bytes_to_write = 1;
uint8_t buffer[2];
buffer[ 0 ] = (uint8_t)( event >> 8 );
if ( event_code != 0xC && event_code != 0xD )
{
buffer[ 1 ] = (uint8_t)( event >> 16 );
bytes_to_write = 2;
}
track.add_event( midi_event( current_timestamp, (midi_event::event_type)( event_code - 8 ), event & 0x0F, buffer, bytes_to_write ) );
}
}
}
}
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, end_of_track, _countof( end_of_track ) ) );
p_out.add_track( track );
return true;
}

View File

@ -0,0 +1,140 @@
#include "midi_processor.h"
const uint8_t midi_processor::mus_default_tempo[5] = {0xFF, 0x51, 0x09, 0xA3, 0x1A};
const uint8_t midi_processor::mus_controllers[15] = {0,0,1,7,10,11,91,93,64,67,120,123,126,127,121};
bool midi_processor::is_mus( std::vector<uint8_t> const& p_file )
{
if ( p_file.size() < 0x20 ) return false;
if ( p_file[ 0 ] != 'M' || p_file[ 1 ] != 'U' || p_file[ 2 ] != 'S' || p_file[ 3 ] != 0x1A ) return false;
uint16_t length = p_file[ 4 ] | ( p_file[ 5 ] << 8 );
uint16_t offset = p_file[ 6 ] | ( p_file[ 7 ] << 8 );
uint16_t instrument_count = p_file[ 12 ] | ( p_file[ 13 ] << 8 );
if ( offset >= 16 + instrument_count * 2 && offset < 16 + instrument_count * 4 && offset + length <= p_file.size() ) return true;
return false;
}
bool midi_processor::process_mus( std::vector<uint8_t> const& p_file, midi_container & p_out )
{
uint16_t length = p_file[ 4 ] | ( p_file[ 5 ] << 8 );
uint16_t offset = p_file[ 6 ] | ( p_file[ 7 ] << 8 );
p_out.initialize( 0, 0x59 );
{
midi_track track;
track.add_event( midi_event( 0, midi_event::extended, 0, mus_default_tempo, _countof( mus_default_tempo ) ) );
track.add_event( midi_event( 0,