2
0
Fork 0

Custom jucer project and app icon

This commit is contained in:
George Reales 2020-04-29 20:04:37 +02:00
parent 55af434b95
commit 4f15396e81
41 changed files with 145 additions and 4737 deletions

BIN
Media/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -1,147 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="wUKQiT" name="JuceOPLVSTi" projectType="audioplug" version="1.0.0"
bundleIdentifier="com.plainweave.JuceOPLVSTi" buildVST="1" buildAU="1"
pluginName="JuceOPLVSTi" pluginDesc="JuceOPLVSTi" pluginManufacturer="Plainweave Software"
pluginManufacturerCode="Pwve" pluginCode="JOPL" pluginChannelConfigs="{0, 1}"
pluginIsSynth="1" pluginWantsMidiIn="1" pluginProducesMidiOut="0"
pluginSilenceInIsSilenceOut="0" pluginEditorRequiresKeys="0"
pluginAUExportPrefix="JuceOPLVSTiAU" aaxIdentifier="com.plainweave.JuceOPLVSTi"
pluginAAXCategory="2" jucerVersion="5.3.2" buildVST3="0" buildRTAS="0"
buildAAX="0" includeBinaryInAppConfig="1" pluginIsMidiEffectPlugin="0"
companyWebsite="https://bsutherland.github.io/JuceOPLVSTi/" buildAUv3="0"
displaySplashScreen="1" reportAppUsage="1" splashScreenColour="Dark"
buildStandalone="0" enableIAA="0" companyCopyright="" pluginFormats="buildVST,buildAU"
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn">
<MAINGROUP id="TOefyq" name="JuceOPLVSTi">
<GROUP id="{DCA755EB-7953-0641-E719-95C7850E5B2B}" name="Source">
<FILE id="AqQcu5" name="ChannelButtonLookAndFeel.cpp" compile="1" resource="0"
file="Source/ChannelButtonLookAndFeel.cpp"/>
<FILE id="yqL2ZN" name="ChannelButtonLookAndFeel.h" compile="0" resource="0"
file="Source/ChannelButtonLookAndFeel.h"/>
<FILE id="mSWBsr" name="OPLLookAndFeel.cpp" compile="1" resource="0"
file="Source/OPLLookAndFeel.cpp"/>
<FILE id="igacSV" name="OPLLookAndFeel.h" compile="0" resource="0"
file="Source/OPLLookAndFeel.h"/>
<FILE id="KRj0DZ" name="tests.cpp" compile="1" resource="0" file="Source/tests.cpp"/>
<FILE id="LVSdHL" name="InstrumentLoader.h" compile="0" resource="0"
file="Source/InstrumentLoader.h"/>
<FILE id="SX7G0u" name="SbiLoader.cpp" compile="1" resource="0" file="Source/SbiLoader.cpp"/>
<FILE id="g2OCfO" name="SbiLoader.h" compile="0" resource="0" file="Source/SbiLoader.h"/>
<FILE id="CGPOGV" name="IntFloatParameter.cpp" compile="1" resource="0"
file="Source/IntFloatParameter.cpp"/>
<FILE id="uAEGVV" name="IntFloatParameter.h" compile="0" resource="0"
file="Source/IntFloatParameter.h"/>
<FILE id="GnuXsD" name="EnumFloatParameter.cpp" compile="1" resource="0"
file="Source/EnumFloatParameter.cpp"/>
<FILE id="GQm1JF" name="EnumFloatParameter.h" compile="0" resource="0"
file="Source/EnumFloatParameter.h"/>
<FILE id="cyDyMZ" name="FloatParameter.cpp" compile="1" resource="0"
file="Source/FloatParameter.cpp"/>
<FILE id="RwbIyF" name="FloatParameter.h" compile="0" resource="0"
file="Source/FloatParameter.h"/>
<FILE id="SyIvF1" name="PluginGui.cpp" compile="1" resource="0" file="Source/PluginGui.cpp"/>
<FILE id="a2DQGI" name="PluginGui.h" compile="0" resource="0" file="Source/PluginGui.h"/>
<FILE id="BZFxoj" name="adlib.h" compile="0" resource="0" file="Source/adlib.h"/>
<FILE id="c6G4EF" name="config.h" compile="0" resource="0" file="Source/config.h"/>
<FILE id="TnpE3r" name="dbopl.cpp" compile="1" resource="0" file="Source/dbopl.cpp"/>
<FILE id="r3zBZz" name="dbopl.h" compile="0" resource="0" file="Source/dbopl.h"/>
<FILE id="pXX3j1" name="dosbox.h" compile="0" resource="0" file="Source/dosbox.h"/>
<FILE id="TLHYVa" name="hardware.h" compile="0" resource="0" file="Source/hardware.h"/>
<FILE id="fZWteg" name="hiopl.cpp" compile="1" resource="0" file="Source/hiopl.cpp"/>
<FILE id="OiMwKI" name="hiopl.h" compile="0" resource="0" file="Source/hiopl.h"/>
<FILE id="mZbr8b" name="inout.h" compile="0" resource="0" file="Source/inout.h"/>
<FILE id="ZBjR5F" name="logging.h" compile="0" resource="0" file="Source/logging.h"/>
<FILE id="aR7Eu7" name="mixer.h" compile="0" resource="0" file="Source/mixer.h"/>
<FILE id="KCyK6B" name="opl.h" compile="0" resource="0" file="Source/opl.h"/>
<FILE id="t6cmDm" name="pic.h" compile="0" resource="0" file="Source/pic.h"/>
<FILE id="Phxzxb" name="PluginProcessor.cpp" compile="1" resource="0"
file="Source/PluginProcessor.cpp"/>
<FILE id="IvGocs" name="PluginProcessor.h" compile="0" resource="0"
file="Source/PluginProcessor.h"/>
<FILE id="ep2XEF" name="setup.h" compile="0" resource="0" file="Source/setup.h"/>
</GROUP>
</MAINGROUP>
<MODULES>
<MODULES id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULES id="juce_audio_devices" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_formats" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_processors" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_core" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_cryptography" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_data_structures" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_events" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_graphics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_basics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_extra" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_opengl" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_video" showAllCode="1" useLocalCopy="1"/>
</MODULES>
<JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
<EXPORTFORMATS>
<VS2015 targetFolder="Builds/VisualStudio2015" vstFolder="C:\code\audio\VST3 SDK"
extraCompilerFlags="/wd4458" vst3Folder="">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
isDebug="1" optimisation="1" targetName="JuceOPLVSTi" debugInformationFormat="ProgramDatabase"
enablePluginBinaryCopyStep="0"/>
<CONFIGURATION name="Release - 64-bit" winWarningLevel="4" generateManifest="1"
winArchitecture="x64" isDebug="0" optimisation="3" targetName="JuceOPLVSTi x64"
warningsAreErrors="1" headerPath="" debugInformationFormat="ProgramDatabase"
enablePluginBinaryCopyStep="0" linkTimeOptimisation="1"/>
<CONFIGURATION name="Release - 32-bit" winWarningLevel="4" generateManifest="1"
winArchitecture="32-bit" isDebug="0" optimisation="3" targetName="JuceOPLVSTi"
warningsAreErrors="1" headerPath="" debugInformationFormat="ProgramDatabase"
enablePluginBinaryCopyStep="0" linkTimeOptimisation="1"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_video" path="..\JUCE\modules"/>
<MODULEPATH id="juce_opengl" path="..\JUCE\modules"/>
<MODULEPATH id="juce_gui_extra" path="..\JUCE\modules"/>
<MODULEPATH id="juce_gui_basics" path="..\JUCE\modules"/>
<MODULEPATH id="juce_graphics" path="..\JUCE\modules"/>
<MODULEPATH id="juce_events" path="..\JUCE\modules"/>
<MODULEPATH id="juce_data_structures" path="..\JUCE\modules"/>
<MODULEPATH id="juce_cryptography" path="..\JUCE\modules"/>
<MODULEPATH id="juce_core" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_processors" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_formats" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_devices" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_basics" path="..\JUCE\modules"/>
</MODULEPATHS>
</VS2015>
<VS2017 targetFolder="Builds/VisualStudio2017">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
debugInformationFormat="ProgramDatabase" enablePluginBinaryCopyStep="0"
linkTimeOptimisation="0" isDebug="1" optimisation="1" targetName="JuceOPLVSTi"/>
<CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
debugInformationFormat="ProgramDatabase" enablePluginBinaryCopyStep="0"
linkTimeOptimisation="1" isDebug="0" optimisation="3" targetName="JuceOPLVSTi x64"
warningsAreErrors="0"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_video" path="..\JUCE\modules"/>
<MODULEPATH id="juce_opengl" path="..\JUCE\modules"/>
<MODULEPATH id="juce_gui_extra" path="..\JUCE\modules"/>
<MODULEPATH id="juce_gui_basics" path="..\JUCE\modules"/>
<MODULEPATH id="juce_graphics" path="..\JUCE\modules"/>
<MODULEPATH id="juce_events" path="..\JUCE\modules"/>
<MODULEPATH id="juce_data_structures" path="..\JUCE\modules"/>
<MODULEPATH id="juce_cryptography" path="..\JUCE\modules"/>
<MODULEPATH id="juce_core" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_processors" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_formats" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_devices" path="..\JUCE\modules"/>
<MODULEPATH id="juce_audio_basics" path="..\JUCE\modules"/>
</MODULEPATHS>
</VS2017>
</EXPORTFORMATS>
<LIVE_SETTINGS>
<WINDOWS systemHeaderPath="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include"
liveWindowsTargetPlatformVersion="10.0.10586.0" defines=""/>
</LIVE_SETTINGS>
</JUCERPROJECT>
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="wUKQiT" name="OPL" projectType="audioplug" version="1.0.0"
bundleIdentifier="com.discodsp.OPL" pluginName="OPL" pluginDesc="OPL"
pluginManufacturer="discoDSP" pluginManufacturerCode="DDSP" pluginCode="OPL"
pluginChannelConfigs="{0, 1}" pluginIsSynth="1" pluginWantsMidiIn="1"
pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0" pluginEditorRequiresKeys="0"
pluginAUExportPrefix="oplAU" aaxIdentifier="com.discodsp.opl"
pluginAAXCategory="2" jucerVersion="5.4.7" includeBinaryInAppConfig="1"
pluginIsMidiEffectPlugin="0" companyWebsite="https://www.discodsp.com/"
splashScreenColour="Dark" companyCopyright="" pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
pluginFormats="buildAU,buildStandalone,buildVST,buildVST3,enableIAA"
buildVST="1" buildVST3="1" buildAU="1" buildAUv3="0" buildRTAS="0"
buildAAX="0" buildStandalone="1" enableIAA="1" companyName="discoDSP"
companyEmail="contactus@discodsp.com" pluginRTASDisableBypass="0"
pluginRTASDisableMultiMono="0" pluginAAXDisableBypass="0" pluginAAXDisableMultiMono="0"
pluginAUMainType="'aumu'" pluginVST3Category="Instrument,Synth"
pluginVSTCategory="kPlugCategSynth">
<MAINGROUP id="TOefyq" name="OPL">
<GROUP id="{DCA755EB-7953-0641-E719-95C7850E5B2B}" name="Source">
<FILE id="aNR5I9" name="icon.png" compile="0" resource="0" file="Media/icon.png"/>
<FILE id="AqQcu5" name="ChannelButtonLookAndFeel.cpp" compile="1" resource="0"
file="Source/ChannelButtonLookAndFeel.cpp"/>
<FILE id="yqL2ZN" name="ChannelButtonLookAndFeel.h" compile="0" resource="0"
file="Source/ChannelButtonLookAndFeel.h"/>
<FILE id="mSWBsr" name="OPLLookAndFeel.cpp" compile="1" resource="0"
file="Source/OPLLookAndFeel.cpp"/>
<FILE id="igacSV" name="OPLLookAndFeel.h" compile="0" resource="0"
file="Source/OPLLookAndFeel.h"/>
<FILE id="KRj0DZ" name="tests.cpp" compile="1" resource="0" file="Source/tests.cpp"/>
<FILE id="LVSdHL" name="InstrumentLoader.h" compile="0" resource="0"
file="Source/InstrumentLoader.h"/>
<FILE id="SX7G0u" name="SbiLoader.cpp" compile="1" resource="0" file="Source/SbiLoader.cpp"/>
<FILE id="g2OCfO" name="SbiLoader.h" compile="0" resource="0" file="Source/SbiLoader.h"/>
<FILE id="CGPOGV" name="IntFloatParameter.cpp" compile="1" resource="0"
file="Source/IntFloatParameter.cpp"/>
<FILE id="uAEGVV" name="IntFloatParameter.h" compile="0" resource="0"
file="Source/IntFloatParameter.h"/>
<FILE id="GnuXsD" name="EnumFloatParameter.cpp" compile="1" resource="0"
file="Source/EnumFloatParameter.cpp"/>
<FILE id="GQm1JF" name="EnumFloatParameter.h" compile="0" resource="0"
file="Source/EnumFloatParameter.h"/>
<FILE id="cyDyMZ" name="FloatParameter.cpp" compile="1" resource="0"
file="Source/FloatParameter.cpp"/>
<FILE id="RwbIyF" name="FloatParameter.h" compile="0" resource="0"
file="Source/FloatParameter.h"/>
<FILE id="SyIvF1" name="PluginGui.cpp" compile="1" resource="0" file="Source/PluginGui.cpp"/>
<FILE id="a2DQGI" name="PluginGui.h" compile="0" resource="0" file="Source/PluginGui.h"/>
<FILE id="BZFxoj" name="adlib.h" compile="0" resource="0" file="Source/adlib.h"/>
<FILE id="c6G4EF" name="config.h" compile="0" resource="0" file="Source/config.h"/>
<FILE id="TnpE3r" name="dbopl.cpp" compile="1" resource="0" file="Source/dbopl.cpp"/>
<FILE id="r3zBZz" name="dbopl.h" compile="0" resource="0" file="Source/dbopl.h"/>
<FILE id="pXX3j1" name="dosbox.h" compile="0" resource="0" file="Source/dosbox.h"/>
<FILE id="TLHYVa" name="hardware.h" compile="0" resource="0" file="Source/hardware.h"/>
<FILE id="fZWteg" name="hiopl.cpp" compile="1" resource="0" file="Source/hiopl.cpp"/>
<FILE id="OiMwKI" name="hiopl.h" compile="0" resource="0" file="Source/hiopl.h"/>
<FILE id="mZbr8b" name="inout.h" compile="0" resource="0" file="Source/inout.h"/>
<FILE id="ZBjR5F" name="logging.h" compile="0" resource="0" file="Source/logging.h"/>
<FILE id="aR7Eu7" name="mixer.h" compile="0" resource="0" file="Source/mixer.h"/>
<FILE id="KCyK6B" name="opl.h" compile="0" resource="0" file="Source/opl.h"/>
<FILE id="t6cmDm" name="pic.h" compile="0" resource="0" file="Source/pic.h"/>
<FILE id="Phxzxb" name="PluginProcessor.cpp" compile="1" resource="0"
file="Source/PluginProcessor.cpp"/>
<FILE id="IvGocs" name="PluginProcessor.h" compile="0" resource="0"
file="Source/PluginProcessor.h"/>
<FILE id="ep2XEF" name="setup.h" compile="0" resource="0" file="Source/setup.h"/>
</GROUP>
</MAINGROUP>
<MODULES>
<MODULES id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULES id="juce_audio_devices" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_formats" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_processors" showAllCode="1" useLocalCopy="1"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="1" useGlobalPath="0"/>
<MODULES id="juce_core" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_cryptography" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_data_structures" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_events" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_graphics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_basics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_extra" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_opengl" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_video" showAllCode="1" useLocalCopy="1"/>
</MODULES>
<JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
<EXPORTFORMATS>
<XCODE_IPHONE targetFolder="Builds/iOS" iosDevelopmentTeamID="" iosScreenOrientation="landscape"
iPadScreenOrientation="landscape" UIFileSharingEnabled="1" UIStatusBarHidden="1"
iosBackgroundAudio="1" iosBackgroundBle="1" UISupportsDocumentBrowser="1"
iosDeviceFamily="2" smallIcon="aNR5I9" bigIcon="aNR5I9">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug"/>
<CONFIGURATION isDebug="0" name="Release" linkTimeOptimisation="1"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_video" path="modules"/>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_cryptography" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
</MODULEPATHS>
</XCODE_IPHONE>
<XCODE_MAC targetFolder="Builds/MacOSX" iosDevelopmentTeamID=""
vstLegacyFolder="modules/vstsdk2.4" vst3Folder="modules/vstsdk3"
smallIcon="aNR5I9" bigIcon="aNR5I9">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug"/>
<CONFIGURATION isDebug="0" name="Release" linkTimeOptimisation="1"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_video" path="modules"/>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_cryptography" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
</MODULEPATHS>
</XCODE_MAC>
</EXPORTFORMATS>
<LIVE_SETTINGS>
<WINDOWS systemHeaderPath="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include"
liveWindowsTargetPlatformVersion="10.0.10586.0" defines=""/>
<OSX/>
</LIVE_SETTINGS>
</JUCERPROJECT>

View File

@ -1,23 +0,0 @@
@ECHO OFF
IF [%1]==[] GOTO usage
ECHO Building Windows Release
SET RELEASE_VERSION=%1
MSBUILD Builds\VisualStudio2015\JuceOPLVSTi.vcxproj /p:Configuration="Release - 32-bit" /p:Platform="x86"
MSBUILD Builds\VisualStudio2015\JuceOPLVSTi.vcxproj /p:Configuration="Release - 64-bit" /p:Platform="x64"
MKDIR %RELEASE_TEMP%
COPY "Builds\VisualStudio2015\Release - 32-bit\JuceOPLVSTi.dll" .
COPY "Builds\VisualStudio2015\x64\Release - 64-bit\JuceOPLVSTi x64.dll" .
REM We can zip using jar from the JDK!
REM http://stackoverflow.com/a/29879102/1480560
DEL JuceOPLVSTi_%RELEASE_VERSION%.zip
jar -cMf JuceOPLVSTi_%RELEASE_VERSION%.zip "JuceOPLVSTi x64.dll" JuceOPLVSTi.dll Instruments
DEL "JuceOPLVSTi x64.dll" JuceOPLVSTi.dll
GOTO :eof
:usage
ECHO Specify version on command line (eg 0-14-1)

View File

@ -1,182 +0,0 @@
---------------------------------------------------------------
DRO2MIDI - version 1.6 (2013-11-29)
Written by malvineous@shikadi.net
Heavily based upon IMF2MIDI written by Guenter Nagler in 1996
http://www.shikadi.net/utils/
---------------------------------------------------------------
// What is it?
////////////////
DRO2MIDI converts Adlib music (in .dro, .imf or .raw format) into standard
MIDI files, so that it can be played or edited in most audio applications, or
so the notes can be extracted to be played on a real instrument.
// Features
/////////////
* Converts DOSBox .dro captures, id Software .imf songs and Rdos .raw captures
* Converts OPL frequency changes into MIDI pitchbends
* Tries to map Adlib instruments to MIDI instruments as best it can, but
these mappings can be easily added to and changed
* Instruments can also be mapped to MIDI percussion
* OPL rhythm-mode percussion is converted (v1.4 adds support for user-defined
mapping via new syntax in the mapping file)
* The OPL conversion constant can be changed (see -c option) to more
accurately convert notes without excessive pitchbend events
// Usage
//////////
Linux: $ dro2midi file.dro file.mid
Windows: C:\>dro2midi file.dro file.mid
For a list of the command line options run dro2midi with no parameters or
see below for more details. For best results, all the .txt data files should
be in the current directory.
Instrument mappings between Adlib registers and MIDI instruments are stored in
inst.txt. This file contains a number of existing mappings, but additional
mappings can easily be added. During conversion, if an exact match cannot
be found the mapping with the closest Adlib parameters will be used instead.
A message will be printed when this happens, along with a line that can be
copied into inst.txt to provide an exact match. This approximation can have
the unfortunate side effect of providing some odd conversions, such as
converting a bass-line into a monotonic drum.
To get a perfect conversion you may wish to delete all but the first
"all-zero" instrument in inst.txt, which will cause all instruments to be
converted as a piano. You can then copy the definitions printed during
conversion one by one into inst.txt, to assign the best-sounding instrument
without worring about any default mappings taking over. Alternatively the -i
option can be used which will disable the closest-match algorithm, and only
exact matches will be used (again, anything that can't be exactly matched will
be mapped as a piano.)
// Command-line options
/////////////////////////
-p disables generation of MIDI pitchbends. This results in a single note-on
when the instrument sounds, but no further pitch change results until the
note is switched off again. This can also be used to prevent the large number
of small pitchbends generated when the conversion constant is slightly off (but
see the -c option, which now provides a better way around this.)
-a will, if pitchbends are disabled with -p, approximate any pitchbend by
playing the nearest note to the new pitch at the time. This results in a
"hammering" of notes during a pitchbend, which while humourous, is probably
of limited use.
-r disables the conversion of OPL rhythm mode instruments. As OPL rhythm mode
conversion is now quite flexible, this option should rarely be needed.
-i will disable the approximation algorithm which selects similar instruments
when an exact match cannot be found in the mapping file (insts.txt). This is
useful when trying to create a perfect map for a single song, as it makes it
easier to pick out which instruments are being mapped. This option should not
be used for the final conversion however, as any instruments that haven't been
precisely mapped will come out (by default) as a grand piano. (This default
mapping is simply the first entry in insts.txt.)
-c changes the conversion constant used when converting OPL notes into their
MIDI equivalents. This is the heart of what DRO2MIDI does. Unfortunately
depending on which set of documents are available, those writing OPL *players*
are told the conversion constant is either 49716, or 50000. Thus half the
games out there use one, and half use the other. The result of using the wrong
constant in the DRO2MIDI conversion is a tiny difference in pitch when the song
is played (about 1/17th of a cent.) Most people will be unable to hear the
difference between these two values, however if the wrong constant is used by
DRO2MIDI during the conversion into MIDI, the resulting file will contain
thousands of small pitchbend events, as it tries to approximate the exact OPL
note played. Using -c to try a different constant should solve this problem.
The default constant is 49716, and "-c alt" will change the constant to 50000.
It is possible to specify an arbitrary constant like "-c 49999" however this
should be unnecessary unless the same nonstandard constant was used wherever
the song was originally played. Note that no error checking is performed here,
so out of range values could easily crash the program (not that that's a major
problem though...) After conversion the number of pitchbend events is
displayed at the end of the output, so it will be obvious when the correct
constant is in use as this number will be significantly smaller than with
any other constant.
-v disables the volume detection. Normally DRO2MIDI will take the OPL
carrier's "Level" amount and translate it to a MIDI note velocity. This will
result in the output MIDI file more accurately matching the loud and quiet
parts of the OPL song. Some songs (e.g. Stunts) somehow manage to work with
these volume levels set to zero, which results in very quiet MIDI files (there
is an internal limit as to how quiet a note can sound to prevent it being lost
entirely.) If your output MIDI file is much too quiet, this option will cause
all notes to be played at maximum velocity.
-s instructs dro2midi to write all detected instruments to a .sbi file. This
is a 52 byte binary instrument format for OPL chips created by Creative Labs.
It is supported by applications written to work with the OPL, such as Ad Lib
Tracker 2.
// inst.txt
/////////////
The instrument mappings are stored in inst.txt, in a format like this:
NO 07-12/4F-00/F2-F2/60-72/08/00-00: patch=15 # Tubular bells
These lines are printed automatically when an unknown instrument is encounted.
All you will need to do is copy and paste the line into insts.txt and choose
a MIDI instrument for it. The file itself is read in from the current
directory during conversion, so if you run DRO2MIDI in another folder remember
to copy the file across too or your mappings won't be used.
The first two characters indicate what type of instrument it is. The
hexadecimal numbers that follow are the Adlib register values for that
instrument. "patch=15" assigns MIDI instrument #15 for this Adlib instrument.
For percussion, "drum=35" could be used instead. Anything after a # symbol is
treated as a comment. See the comments at the top of the file for more
detailed information.
The instrument names (and values to supply to the patch= parameter) are stored
in patch.txt, and the drum names (and numbers) in drum.txt. You may find
these files helpful to reference when selecting instruments for conversion.
(These two files are read in from the current directory during conversion to
allow the display of instrument names in status messages instead of just
numbers.)
Note that the parser for insts.txt file is quick and dirty, so it's easy to
get a syntax error - for example, an otherwise blank line with a single space
on it will cause an error (so if you get an error about a blank line, make
sure it really is blank!)
// License
////////////
DRO2MIDI was based on IMF2MIDI by Guenter Nagler. DRO2MIDI is released under
the GPL license, except where it is incompatible with IMF2MIDI's original
license, in which case IMF2MIDI's license takes precedence.
---- Begin IMF2MIDI license ----
IMF2MIDI (c) 1996 was created by Guenter Nagler.
IMF2MIDI is free and may be used as you wish with this one exception:
You may NOT charge any fee or derive any profit for distribution
of IMF2MIDI. Thus, you may NOT sell or bundle IMF2MIDI with any
product in a retail environment (shareware disk distribution, CD-ROM,
etc.) without permission of the author.
You may give IMF2MIDI to your friends, upload it to a BBS, or ftp it to
another internet site, as long as you don't charge anything for it.
---- End IMF2MIDI license ----
// Contact
////////////
Source code is available at http://www.shikadi.net/utils/
You can e-mail me at malvineous@shikadi.net

View File

@ -1 +0,0 @@
cl midiio.cpp dro2midi.cpp /link /OUT:dro2midi.exe

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
//
// gen_test_midi.cpp - by malvineous@shikadi.net
//
// Generate a MIDI file that plays one note from all 128 GM instruments (in
// order), followed by all the percussion notes.
//
// When this file is played through an OPL synthesiser capable of MIDI
// playback, then captured through DOSBox, it will provide a complete set of
// OPL patches that can easily be associated back to MIDI instruments.
//
#include "midiio.hpp"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#define WRITE_BINARY "wb"
#define READ_TEXT "r"
int main(int argc, char**argv)
{
if (argc != 2) {
fprintf(stderr, "no output filename given\n");
return 1;
}
MidiWrite *write = new MidiWrite(argv[1]);
if (!write) {
fprintf(stderr, "out of memory\n");
return 1;
}
if (!write->getf()) {
perror(argv[1]);
return 1;
}
float tempo = 120.0;
int resolution = 280;
write->head(/* version */ 0, /* track count updated later */0, resolution);
write->track();
write->tempo((long)(60000000.0 / tempo));
write->tact(4,4,24,8);
write->volume(1, 127);
write->volume(9, 127);
for (int i = 0; i < 128; i++) {
write->program(1, i);
write->noteon(1, 60, 127);
write->time(50);
write->noteoff(1, 60);
write->time(50);
}
/*
// Need to play a normal note for percussion to get DOSBox to start capturing
// OPL data! (Why hasn't my patch to fix that been incorporated yet?!)
write->noteon(1, 60, 127);
write->time(50);
write->noteoff(1, 60);
write->time(200);
for (int i = 35; i < 82; i++) {
write->noteon(9, i, 127);
write->time(50);
write->noteoff(9, i);
write->time(50);
}*/
delete write;
return 0;
}

View File

@ -1,21 +0,0 @@
#!/bin/sh
# Usage:
#
# ./make
#
# or if you have a cross compiler for i586-pc-mingw32 installed
#
# ./make i586-pc-mingw32 .exe
#
if [ "$1" != "" ]; then
PLATFORM="$1"-
TARGET="dro2midi$2"
else
PLATFORM=""
TARGET="dro2midi"
fi
${PLATFORM}g++ -o ${TARGET} dro2midi.cpp midiio.cpp &&
${PLATFORM}strip ${TARGET}

File diff suppressed because it is too large Load Diff

View File

@ -1,402 +0,0 @@
#ifndef __MIDIIO__
#define __MIDIIO__
#include <stdio.h>
#ifndef MIDI_BUFSIZE
#define MIDI_BUFSIZE 1024
#endif
// opening modes of a midi file
#define WRITE_BINARY "wb"
#define READ_BINARY "rb"
const unsigned long MThd = 0x4D546864ul;
const unsigned long MTrk = 0x4D54726Bul;
// different standard midi formats
#define VERSION_MULTICHANNEL 0
#define VERSION_SINGLECHANNEL 1
#define VERSION_MULTISONG 2
#define OPTION_NOCONTROLS 1 // no control details but general information
#define OPTION_NOEVENTS 2 // no track events at all
#define OPTION_NOMETAEVENTS 4 // no meta details but general information
#define OPTION_NOSYSEVENTS 8 // no sysex details but general information
#define OPTION_NONOTEEVENTS 16 // no note events (8x or 9x)
#define OPTION_NOPOLYEVENTS 32 // no poly aftertouch events (Ax)
#define OPTION_NOCONTROLEVENTS 64 // no control events at all (Bx)
#define OPTION_NOPROGRAMEVENTS 128 // no program change events (Cx)
#define OPTION_NOAFTERTOUCHEVENTS 256 // no aftertouch events (Dx)
#define OPTION_NOPITCHBENDEVENTS 512 // no pitchbend events (Ex)
#define OPTION_NOREALTIMEEVENTS 1024 // no realtime events (Fx)
// getchannel delivers a valid channel or:
#define NOCHANNEL (-1)
#define MULTICHANNEL (-2)
#define VALIDCHANNEL(ch) ((ch) >= 0 && (ch) <= 15)
#define gm_drumchannel 9
#define SAYCHANNEL(ch) ((ch) + 1) // 0..15 in midi format but spoken 1..16!
// for use of param what in function text()
#define meta_text 1
#define meta_copyright 2
#define meta_trackname 3
#define meta_instrument 4
#define meta_lyric 5
#define meta_marker 6
#define meta_cuepoint 7
#define meta_endtrack 0x2f
#define ctrl_highbank 0
#define ctrl_wheel 1
#define ctrl_breath 2
#define ctrl_foot 4
#define ctrl_portamentotime 5
#define ctrl_data 6
#define ctrl_volume 7
#define ctrl_balance 10
#define ctrl_expression 11
#define ctrl_lowbank 32
#define ctrl_hold 64
#define ctrl_reverb 91
#define ctrl_chorus 93
#define ctrl_datainc 96
#define ctrl_datadec 97
#define ctrl_lowrpn 100
#define ctrl_highrpn 101
#define ctrl_resetctrlrs 121
#define ctrl_allnotesoff 123
#define balance_left 0
#define balance_center 64
#define balance_right 127
#define volume_mute 0
#define volume_full 127
#define bpm(ticks) (60000000.0 / (ticks))
#define ticks(beats) ((unsigned long)(60000000.0 / (beats)))
#define tempo_60bpm (1000000L)
#define tempo_120bpm (500000L)
#define tempo_240bpm (250000L)
class MidiRead
{
public:
static const char* copyright();
MidiRead(const char* filename, FILE* f = 0);
virtual ~MidiRead();
FILE* getf();
int run();
int runhead();
int runtrack(int trackno);
int runevent(long trackend);
long getpos() { return pos_; }
long geteventpos() { return pos_; }
long getcurpos() { return curpos_; }
unsigned long getcurtime() { return curtime_; } // in midi units
virtual void head(unsigned version, unsigned tracks, unsigned clicksperquarter);
virtual void track(int trackno, long length, int channel);
virtual void endtrack(int trackno); // closing track
virtual void time(unsigned long ticks); // delay between events
virtual void event(int what, int len = 0, unsigned char* data = 0);
// these are event categories:
virtual void meta(int what, int len, const unsigned char* data);
// these are special meta events:
virtual void text(int what, int len, const char* whattext, const unsigned char* txt);
virtual void end(); // end of track command
virtual void prefixchannel(unsigned char channel);
virtual void prefixport(unsigned char port);
virtual void seqnumber(unsigned int seqno);
virtual void smpteofs(int hour, int min, int sec, int frame, int fracframe);
virtual void tact(int nom, int denom, int clicksperbeat, int notes32perbeat);
virtual void tempo(unsigned long microsecperbeat);
virtual void key(int signature, int isminor); // C=0, -7=7flats +7=7sharps
virtual void program(int channel, int prg);
virtual void control(int channel, int what, int val); // general controls
// special controls:
virtual void highbank(int channel, int val);
virtual void wheel(int channel, int val);
virtual void breath(int channel, int val);
virtual void foot(int channel, int val);
virtual void portamentotime(int channel, int val);
virtual void data(int channel, int val);
virtual void volume(int channel, int val);
virtual void balance(int channel, int val);
virtual void expression(int channel, int val);
virtual void lowbank(int channel, int val);
virtual void hold(int channel, int val);
virtual void reverb(int channel, int val);
virtual void chorus(int channel, int val);
virtual void datainc(int channel, int val);
virtual void datadec(int channel, int val);
virtual void lowrpn(int channel, int val);
virtual void highrpn(int channel, int val);
virtual void resetctrlrs(int channel, int val);
virtual void allnotesoff(int channel, int val);
virtual void pitchbendrange(int channel, int val);
virtual void noteon(int channel, int note, int vel);
virtual void noteoff(int channel, int note, int vel);
virtual void pitchbend(int channel, int val);
virtual void polyaftertouch(int channel, int note, int val);
virtual void aftertouch(int channel, int val);
virtual void songpos(unsigned pos);
virtual void songselect(unsigned char song);
virtual void tunerequest();
virtual void timingclock();
virtual void start();
virtual void cont();
virtual void stop();
virtual void activesense();
virtual void sysex(int syslen, const unsigned char* sysdata);
// these are special sysex events:
virtual void xgreset();
virtual void gmreset();
virtual void gsreset();
virtual void gsexit();
virtual void endmidi(); // after last track
virtual void error(const char* msg);
virtual void warning(const char* msg);
virtual void percent(int perc);
int getchannel() { return curchannel_; }
void setchannel(int channel);
static const char* progname(int n, int channel);
static const char* notename(unsigned char note);
int options_;
int version_, tracks_, clicks_, trackno_;
void seek(long pos);
int getbyte();
unsigned getword();
unsigned long gettri();
unsigned long getlong();
unsigned long getdelta();
unsigned char* get(int len);
unsigned char* need(int nbytes);
unsigned long microsec(unsigned long units, unsigned long msperbeats);
long units(unsigned long microsec, unsigned long msperbeats);
// use scanchannel only at start of track!
int scanchannel(unsigned long maxlen); // channel 0-15 or -1=no channel or -2=multichannels
// use sysevent only directly after reading F0 or F7
int scansysevent(unsigned long maxlen);
protected:
const char *midiname_;
FILE* f_;
unsigned char shouldclose_; // 0=no, otherwise=yes
long filesize_;
unsigned char buf_[MIDI_BUFSIZE];
int buflen_, bufpos_;
int curchannel_;
unsigned long curtime_;
int percent_;
int lastcode_;
unsigned long tracklen_;
long pos_, curpos_;
unsigned char curdeltalen_; // number of bytes read by recent getdelta() call
};
class MidiWrite
{
public:
static const char* copyright();
MidiWrite(const char* filename);
virtual ~MidiWrite();
FILE* getf();
long getcurpos() { return curpos_; }
long getcurtime() { return curtime_; }
void cleardelta();
void head(int version = 1, int tracks = 0, unsigned clicksperquarter = 192);
void track();
void endtrack();
void event(int what, int len, const unsigned char* data);
void text(int what, int len, const unsigned char* txt);
void meta(int what, int len, const unsigned char* data); // 0xff ....
virtual void prefixchannel(unsigned char channel);
virtual void prefixport(unsigned char port);
virtual void seqnumber(unsigned int seqno);
virtual void smpteofs(int hour, int min, int sec, int frame, int fracframe);
virtual void key(int signature, int isminor);
void tact(int nom, int denom, int v1, int v2);
void tempo(unsigned long microsecperbeat);
void end();
void program(int channel, int prg);
void control(int channel, int what, int val);
// these are special controls
void highbank(int channel, int val);
void wheel(int channel, int val);
void breath(int channel, int val);
void foot(int channel, int val);
void portamentotime(int channel, int val);
void data(int channel, int val);
void volume(int channel, int val);
void balance(int channel, int val);
void expression(int channel, int val);
void lowbank(int channel, int val);
void hold(int channel, int val);
void reverb(int channel, int val);
void chorus(int channel, int val);
void datainc(int channel, int val);
void datadec(int channel, int val);
void lowrpn(int channel, int val);
void highrpn(int channel, int val);
void resetctrlrs(int channel, int val);
void allnotesoff(int channel, int val);
void pitchbendrange(int channel, int halfnotes);
void noteon(int channel, int note, int vel);
void noteoff(int channel, int note, int vel = 0);
void time(unsigned long ticks);
void pitchbend(int channel, int val);
void polyaftertouch(int channel, int note, int val);
void aftertouch(int channel, int val);
void songpos(unsigned pos);
void songselect(unsigned char song);
void tunerequest();
void timingclock();
void start();
void cont();
void stop();
void activesense();
void sysex(int syslen, const unsigned char* sysdata);
void xgreset();
void gmreset();
void gsreset();
void gsexit();
void putbyte(unsigned char val);
void putcode(unsigned char code);
void putword(unsigned val);
void puttri(unsigned long val);
void putlong(unsigned long val);
void putdelta(unsigned long val);
void puttime();
void put(int len, const unsigned char* c);
void seek(long pos);
virtual void error(const char* msg);
virtual void warning(const char* msg);
int unitsperquarter();
protected:
const char *midiname_;
FILE* f_;
long trackpos_, curpos_, filesize_;
int trackchannel_, trackcount_, lastcode_, endtrack_;
unsigned char buf_[MIDI_BUFSIZE];
int bufpos_, buflen_;
unsigned long curdelta_;
unsigned long curtime_;
int clicks_;
void flush();
};
class MidiCopy : public MidiRead
{
public:
MidiCopy(const char* filename, FILE* f = 0);
void setoutput(MidiWrite* dest);
void stopoutput();
MidiWrite* getoutput();
void mapchannel(int channel, int newchannel);
void ignorechannel(int channel);
virtual void head(unsigned version, unsigned tracks, unsigned clicksperquarter);
virtual void track(int trackno, long length, int channel);
virtual void endtrack(int trackno);
virtual void time(unsigned long ticks);
virtual void event(int what, int len = 0, unsigned char* data = 0);
virtual void meta(int what, int len, unsigned char* data);
virtual void text(int what, int len, char* whattext, unsigned char* txt);
virtual void end();
virtual void prefixchannel(unsigned char channel);
virtual void prefixport(unsigned char port);
virtual void seqnumber(unsigned int seqno);
virtual void smpteofs(int hour, int min, int sec, int frame, int fracframe);
virtual void tact(int nom, int denom, int clicksperbeat, int notes32perbeat);
virtual void tempo(unsigned long microsecperbeat);
virtual void key(int signature, int isminor); // C=0, -7=7flats +7=7sharps
virtual void program(int channel, int prg);
virtual void control(int channel, int what, int val);
virtual void highbank(int channel, int val);
virtual void wheel(int channel, int val);
virtual void breath(int channel, int val);
virtual void foot(int channel, int val);
virtual void portamentotime(int channel, int val);
virtual void data(int channel, int val);
virtual void volume(int channel, int val);
virtual void balance(int channel, int val);
virtual void expression(int channel, int val);
virtual void lowbank(int channel, int val);
virtual void hold(int channel, int val);
virtual void reverb(int channel, int val);
virtual void chorus(int channel, int val);
virtual void datainc(int channel, int val);
virtual void datadec(int channel, int val);
virtual void lowrpn(int channel, int val);
virtual void highrpn(int channel, int val);
virtual void resetctrlrs(int channel, int val);
virtual void allnotesoff(int channel, int val);
virtual void noteon(int channel, int note, int vel);
virtual void noteoff(int channel, int note, int vel);
virtual void pitchbend(int channel, int val);
virtual void polyaftertouch(int channel, int note, int val);
virtual void aftertouch(int channel, int val);
virtual void songpos(unsigned pos);
virtual void songselect(unsigned char song);
virtual void tunerequest();
virtual void timingclock();
virtual void start();
virtual void cont();
virtual void stop();
virtual void activesense();
virtual void sysex(int syslen, unsigned char* sysdata);
virtual void gmreset();
virtual void gsreset();
virtual void gsexit();
virtual void xgreset();
protected:
MidiWrite* dest_;
int mapchannel_[16]; // channel 0-15 or events are ignored for invalid channel
};
#endif

0
img/Two-OP AM.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

0
img/Two-OP FM.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

0
img/abs_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

0
img/adlib.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
img/algo_switch_off.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 162 B

0
img/algo_switch_on.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 168 B

0
img/algo_switch_on2.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

0
img/algo_switch_on3.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

0
img/alternating_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

0
img/bassdrum.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 234 B

0
img/camel_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 174 B

0
img/channeloff.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

0
img/channelon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

0
img/cymbal.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 237 B

0
img/disabled.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

0
img/full_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

0
img/half_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 179 B

0
img/hihat.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

0
img/line_border_horiz.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 108 B

After

Width:  |  Height:  |  Size: 108 B

0
img/line_border_vert.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 107 B

0
img/logarithmic_saw.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 206 B

0
img/quarter_sine.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

0
img/snare.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

0
img/square.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 179 B

0
img/toggle_off_sq.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

0
img/toggle_on_sq.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 134 B

0
img/tom.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

0
img/yamaha.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,13 +0,0 @@
lvls = [.75, 1.5, 3, 6, 12, 24]
def get_db(i):
db = 0.0
for d in lvls:
if i & 0x1:
db += d
i >>= 1
return db
for i in range(2**6):
db = get_db(i)
print '"%.2f dB",' % db,

View File

@ -1,340 +0,0 @@
import sys
import json
REG_SCOPE = {
0x00: 'Chip',
0x20: '0x20',
0x30: '0x20',
0x40: '0x40',
0x50: '0x40',
0x60: 'Attack/decay',
0x70: 'Attack/decay',
0x80: 'Sustain/release',
0x90: 'Sustain/release',
0xA0: 'Frequency (L)',
0xB0: 'Key on/off/Frequency(H)',
0xE0: 'Wave select',
0xF0: 'Wave select',
}
# Map register ranges to channel + operator
OPERATOR_MAP = {
0x00: (1, 1),
0x01: (2, 1),
0x02: (3, 1),
0x03: (1, 2),
0x04: (2, 2),
0x05: (3, 2),
0x08: (4, 1),
0x09: (5, 1),
0x0a: (6, 1),
0x0b: (4, 2),
0x0c: (4, 2),
0x0d: (6, 2),
0x10: (7, 1),
0x11: (8, 1),
0x12: (9, 1),
0x13: (7, 2),
0x14: (8, 2),
0x15: (9, 2),
}
OSC_MAP = {1: 'mod', 2: 'car'}
def reg_to_chan_and_op(reg):
# from REGOP in opl driver
#return ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f )
chan, op = OPERATOR_MAP.get(reg % 32, (-1, 1))
print 'ch%02d.%s: ' % (chan, OSC_MAP[op]),
return chan, op
def interpret_00(reg, val, ev):
regs = {1:'TEST', 2:'Timer 1', 3:'Timer 2', 4:'Timer Ctrl', 8:'CSM/keysplit'}
print '%02X (%s)' % (reg, regs.get(reg, '??')),
def interpret_20(reg, val, ev):
ch, op = reg_to_chan_and_op(reg)
ev[2]['ch'] = ch
bitfields = {7: 'tre', 6: 'vib', 5: 'sus', 4:'ksr'}
bf = val & 0xf0
opts = []
for b, opt in bitfields.iteritems():
optset = 'X' if (bf & (0x1 << b)) else '-'
opts.append('%s:%s' % (opt, optset))
ev[op-1][opt]=optset
fm_mult = val & 0x0f
mults = {0:0.5, 11:10, 13:12, 14:15}
fm_mult = mults.get(fm_mult, fm_mult)
opts.append('fm_mult:x%d' % (fm_mult))
ev[op-1]['fm_mult'] = fm_mult
print '; '.join(opts) ,
def _db_atten_to_factor(atten_db):
return (10 ** -(atten_db / 10))
def interpret_40(reg, val, ev):
ch, op = reg_to_chan_and_op(reg)
ev[2]['ch'] = ch
bit_db = {5:24, 4:12, 3:6, 2:3, 1:1.5, 0:0.75}
oct_db = {0:0, 0x40:1.5, 0x80:3, 0xC0:6}
lvl = 0.0
for b, db in bit_db.iteritems():
if (val & (0x1 << b)):
lvl += db
db_oct = oct_db[val & 0xC0]
oct_scale = '-%d dB/8ve' % db_oct
factor = _db_atten_to_factor(lvl)
ev[op-1]['db'] = lvl
ev[op-1]['db_oct'] = db_oct
ev[op-1]['scale'] = factor
print '%.2f dB; (x%.4f) %s' % (lvl, factor, oct_scale) ,
def interpret_60(reg, val, ev):
ch, op = reg_to_chan_and_op(reg)
ev[2]['ch'] = ch
a = val >> 4
d = val & 0x0f
ev[op-1]['a'] = a
ev[op-1]['d'] = d
print 'Att: 0x%1x; Dec: 0x%1x' % (a, d) ,
def interpret_80(reg, val, ev):
ch, op = reg_to_chan_and_op(reg)
ev[2]['ch'] = ch
s = val >> 4
r = val & 0x0f
ev[op-1]['s'] = s
ev[op-1]['r'] = r
print 'Sus: 0x%1x; Rel: 0x%1x' % (s, r) ,
def interpret_A0(reg, val, ev):
global freq_lsb
freq_lsb = val
chan = 1 + reg % 0xA0
print 'ch%02d: Freq-LSB=%02X' % (chan, val) ,
def interpret_B0(reg, val, ev):
global freq_lsb
try:
freq_lsb
except NameError:
freq_lsb = 0
oct = (val >> 2) & 0x7
fnum = ((val & 0x3) << 8) + freq_lsb
chan = 1 + reg % 0xB0
key = 'ON' if (1 << 5) & val else 'off'
frq = _fnum_to_hz(fnum, oct)
ev[1]['frq'] = frq
ev[2]['key'] = key
ev[2]['ch'] = chan
#ev[0]['gate'] = key
print 'ch%02d: Key-%s; f0x%03X oct:%d (%.4f Hz)' % (chan, key, fnum, oct, frq) ,
'''
A0-A8: Frequency Number:
Determines the pitch of the note. Highest bits of F-Number are stored
in the register below.
B0-B8: Key On / Block Number / F-Number(hi bits):
bit 5: KEY-ON. When 1, channel output is enabled.
bits 2-4: Block Number. Roughly determines the octave.
bits 0-1: Frequency Number. 2 highest bits of the above register.
The following formula is used to determine F-Number and Block:
F-Number = Music Frequency * 2^(20-Block) / 49716 Hz
'''
def _fnum_to_hz(fnum, octave):
return (49716.0 * fnum) / (2 ** (21 - octave))
def interpret_BD(reg, val, ev):
print '* BD' ,
def interpret_C0(reg, val, ev):
alg = 'ADD' if val & 0x1 else 'MODULATE'
feedback = (val >> 1) & 0xc
ev[2]['alg'] = alg
ev[2]['feedback'] = feedback
print 'feedback: %d algo: %s' % (feedback, alg) ,
def interpret_E0(reg, val, ev):
ch, op = reg_to_chan_and_op(reg)
ev[2]['ch'] = ch
waves = {0: 'SIN', 1: 'HALFSIN', 2: 'ABSSIN', 3: 'QUARTSIN'}
wav = waves[val & 0x3]
ev[op-1]['wav'] = wav
print wav ,
def interpret_write(ts, reg, val, ev):
print '%10d : ' % ts,
if reg >= 0x01 and reg <= 0x08:
interpret_00(reg, val, ev)
elif reg >= 0x20 and reg <= 0x35:
interpret_20(reg, val, ev)
elif reg >= 0x40 and reg <= 0x55:
interpret_40(reg, val, ev)
elif reg >= 0x60 and reg <= 0x75:
interpret_60(reg, val, ev)
elif reg >= 0x80 and reg <= 0x95:
interpret_80(reg, val, ev)
elif reg >= 0xA0 and reg <= 0xA8:
interpret_A0(reg, val, ev)
elif reg >= 0xB0 and reg <= 0xB8:
interpret_B0(reg, val, ev)
elif reg == 0xBD:
interpret_BD(reg, val, ev)
elif reg >= 0xC0 and reg <= 0xC8:
interpret_C0(reg, val, ev)
elif reg >= 0xE0 and reg <= 0xF5:
interpret_E0(reg, val, ev)
else:
print '?????',
print
#scope = REG_SCOPE.get(reg & 0xF0, '??')
#chan, operator = reg_to_chan_and_op(reg)
#aprint '%10f : %02d.%1d : %02x : %20s' % (float(ts)/1000, chan, operator, val, scope)
def parse_opldump(stream):
events = dict()
t0 = tp = False
line = stream.readline()
while len(line) >= 1:
ts, opl2, op = line.split(':')
if 'OPL2' == opl2:
ts = int(ts)
if not t0:
t0 = ts
ts -= t0
reg, val = op.split('=')
reg = int(reg, 16)
val = int(val, 16)
try:
ev = events[ts]
except KeyError:
ev = [dict(), dict(), dict()]
events[ts] = ev
interpret_write(ts, reg, val, ev)
line = stream.readline()
return events
def get_javascript_for(event):
mod = event[0]
car = event[1]
anc = event[2]
indent = 8*' '
lines = []
if 'ch' in anc:
lines.append('var ch = opl2.channels[%d];\n' % (anc['ch'] - 1))
if 'fm_mult' in car:
lines.append('ch.setModulatorMultiplier(%d); ch.setCarrierMultiplier(%d);\n' % (mod['fm_mult'], car['fm_mult']))
if 'scale' in car:
lines.append('ch.setModulatorAttenuation(%f); ch.setCarrierAttenuation(%f);\n' % (mod['scale'], car['scale']))
if 'a' in mod:
lines.append('ch.setEnvParams(ch.modEnv, 1/%d, 1/%d, 1/%d, 1/%d);\n' % (mod['a'], mod['d'], mod['s']+1, mod['r']))
if 'a' in car:
lines.append('ch.setEnvParams(ch.carEnv, 1/%d, 1/%d, 1/%d, 1/%d);\n' % (car['a'], car['d'], car['s']+1, car['r']))
if 'wav' in car:
lines.append('ch.setCarrierWaveform(ch.%s); ch.setModulatorWaveform(ch.%s);\n' % (car['wav'], mod['wav']))
if 'key' in anc:
if 'ON' == anc['key'].upper():
lines.append('ch.noteOn(%f);\n' % car['frq'])
elif 'OFF' == anc['key'].upper():
lines.append('ch.noteOff();\n')
return indent + indent.join(lines)
def find_unique_instruments(events):
instruments = dict()
ilist = list()
timestamps = events.keys()
timestamps.sort()
for t in timestamps:
ev = events[t]
try: # get rid of fields which don't define uniqueness
del ev[2]['key']
del ev[2]['ch']
del ev[1]['frq']
except KeyError:
pass
instr_json = json.dumps(ev, indent=2)
if instr_json not in instruments:
instruments[instr_json] = t
ilist.append(instr_json)
return ilist, instruments
def print_instrument(json_i, ts):
print
print '@ %10d:' % ts
try:
d = json.loads(json_i)
print 'Waveforms: %10s%10s' % (d[0]['wav'], d[1]['wav'])
print 'Freq mult: %9dx%9dx' % (d[0]['fm_mult'], d[1]['fm_mult'])
print 'Levels: %7d dB%7d dB' % (-d[0]['db'], -d[1]['db'])
envs = (d[0]['a'], d[0]['d'], d[0]['s'], d[0]['r'], d[1]['a'], d[1]['d'], d[1]['s'], d[1]['r'])
print 'Envelopes: %1x %1x %1x %1x %1x %1x %1x %1x' % envs
except KeyError:
print 'incomplete instrument?'
# Conversions mapping to VST floating point values
W2F = {'SIN':0, 'HALFSIN':.33, 'ABSSIN':.66, 'QUARTSIN':1}
def m2f(mult):
if mult < 1: # half frq
return 0
else:
return float(mult)/15.0
def a2f(att_db):
a = float(att_db)/0.75
return a/63.0
def b2f(bool_param):
if 'X' == bool_param:
return 1.0
else:
return 0.0
D2F = {0:0.0,1.5:0.33,3.0:0.66,6.0:1.0}
def e2f(env_val):
return float(env_val)/15.0
def output_instrument_vst_program(json_i, ts):
try:
d = json.loads(json_i)
m=d[0]; c=d[1]
lines = [
' const float i_params_%d[] = {' % ts,
' %.6ff, %.6ff, // waveforms' % (W2F[c['wav']], W2F[m['wav']]),
' %.6ff, %.6ff, // frq multipliers' % (m2f(c['fm_mult']), m2f(m['fm_mult'])),
' %.6ff, %.6ff, // attenuation' % (a2f(c['db']), a2f(m['db'])),
' %.1ff, %.1ff, %.1ff, %.1ff, // tre / vib / sus / ks' % tuple([b2f(c[x]) for x in ['tre', 'vib', 'sus', 'ksr']]),
' %.1ff, %.1ff, %.1ff, %.1ff, // tre / vib / sus / ks' % tuple([b2f(m[x]) for x in ['tre', 'vib', 'sus', 'ksr']]),
' %.6ff, %.6ff, // KSR/8ve' % (D2F[c['db_oct']], D2F[m['db_oct']]),
' %.6ff, // algorithm' % (1.0 if 'ADD'==d[2]['alg'] else 0.0),
' %.6ff, // feedback' % (float(d[2]['feedback'])/7.0),
' %.1ff, %.1ff, %.1ff, %.1ff, // adsr' % tuple([e2f(c[x]) for x in ['a', 'd', 's', 'r']]),
' %.1ff, %.1ff, %.1ff, %.1ff, // adsr' % tuple([e2f(m[x]) for x in ['a', 'd', 's', 'r']]),
' };',
' std::vector<float> v_i_params_%d (i_params_%d, i_params_%d + sizeof(i_params_%d) / sizeof(float));' % (ts,ts,ts,ts),
' programs["Instr %d"] = std::vector<float>(v_i_params_%d);' % (ts, ts),
]
print
print '\n'.join(lines)
except KeyError:
pass
#print
#print '// incomplete instrument..'
def main(argv):
events = parse_opldump(sys.stdin)
ilist, instruments = find_unique_instruments(events)
for i in ilist:
output_instrument_vst_program(i, instruments[i])
#print i, instruments[i]
#print_instrument(i, instruments[i])
if '__main__' == __name__:
main(sys.argv)

View File

@ -1,45 +0,0 @@
import glob
import os
class SBI:
def __init__(self, sbi_data):
if sbi_data[0:3] != b'SBI':
raise ValueError('Invalid file header.')
if len(sbi_data) != 52:
raise ValueError('Invalid file size.')
self.register_values = sbi_data[36:]
def __eq__(self, other):
return isinstance(other, SBI) and self.register_values == other.register_values
def __hash__(self):
return hash(self.register_values)
# Requires Python 3.5+
def find_distinct_sbis(root_dir):
sbis = {}
bad = []
for filename in glob.iglob(os.path.join(root_dir, '**', '*.sbi'), recursive=True):
with open(filename, 'rb') as f:
try:
sbi = SBI(f.read())
try:
dup_filename = sbis[sbi]
print('Duplicate SBI file: %s (duplicate of %s)' % (filename, dup_filename))
bad.append(filename)
except KeyError:
sbis[sbi] = filename
except ValueError as e:
print('Invalid SBI file: %s (%s)' % (filename, e))
bad.append(filename)
return sbis, bad
if __name__ == '__main__':
distinct_sbis, to_delete = find_distinct_sbis('.')
print('Found %d distinct SBI files' % len(distinct_sbis))
print('Writing batch file..')
with open('delete_bad_sbis.cmd', 'w') as batch_file:
for delete in to_delete:
print('DEL %s' % delete, file=batch_file)