aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2019-05-30 18:11:59 +0300
committerWohlstand <admin@wohlnet.ru>2019-05-30 18:11:59 +0300
commit283b2f249a17eba3be8a98e09f1d009e2ef20aee (patch)
tree71f6bc4ae5a54fbce43ef3b0e612d6aeccbe9b9d
parent6878f4ead2cbf01f62a5d5903229a994cacad9b6 (diff)
downloadlibADLMIDI-283b2f249a17eba3be8a98e09f1d009e2ef20aee.tar.gz
libADLMIDI-283b2f249a17eba3be8a98e09f1d009e2ef20aee.tar.bz2
libADLMIDI-283b2f249a17eba3be8a98e09f1d009e2ef20aee.zip
Continue work on a new db format with a small dumper
-rw-r--r--utils/gen_adldata/file_formats/load_wopl.h11
-rw-r--r--utils/gen_adldata/gen_adldata.cc6
-rw-r--r--utils/gen_adldata/progs_cache.cpp173
-rw-r--r--utils/gen_adldata/progs_cache.h121
4 files changed, 289 insertions, 22 deletions
diff --git a/utils/gen_adldata/file_formats/load_wopl.h b/utils/gen_adldata/file_formats/load_wopl.h
index cd8765e..cef475f 100644
--- a/utils/gen_adldata/file_formats/load_wopl.h
+++ b/utils/gen_adldata/file_formats/load_wopl.h
@@ -18,7 +18,7 @@ enum class WOPL_Flags
WOPL_RhythmModeMask = 0x38,
};
-static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
+static bool LoadWopl(BanksDump &db, const char *fn, unsigned bank, const char *prefix)
{
FILE *fp = std::fopen(fn, "rb");
if(!fp)
@@ -27,6 +27,7 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
std::fflush(stderr);
return false;
}
+
std::fseek(fp, 0, SEEK_END);
std::vector<unsigned char> data(size_t(std::ftell(fp)));
std::rewind(fp);
@@ -63,6 +64,8 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
setup.volumeModel = (int)data[0x12];
setup.scaleModulators = false;
+ size_t bankDb = (unsigned)db.initBank(bank, static_cast<uint_fast16_t>((static_cast<unsigned>(data[0x11]) << 8) | static_cast<unsigned>(data[0x12])));
+
// Validate file format by size calculation
if(version == 1)
{
@@ -98,12 +101,14 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
percussion_offset = melodic_offset + (insSize * 128 * mbanks_count);
- uint32_t root_offsets[2] = {melodic_offset, percussion_offset};
+ //uint32_t root_sizes[2] = {mbanks_count, pbanks_count};
+ uint32_t root_sizes[2] = {1, 1};
+ uint32_t root_offsets[2] = {melodic_offset, percussion_offset};
for(size_t bset = 0; bset < 2; bset++)
{
bool is_percussion = (bset == 1);
- for(uint32_t bankno = 0; bankno < 1; bankno++) // only first melodic bank (Until multi-banks support will be implemented)
+ for(uint32_t bankno = 0; bankno < root_sizes[bset]; bankno++) // only first melodic bank (Until multi-banks support will be implemented)
{
uint32_t bank_offset = root_offsets[bset] + (bankno * insSize * 128);
diff --git a/utils/gen_adldata/gen_adldata.cc b/utils/gen_adldata/gen_adldata.cc
index 7cb4528..1896c43 100644
--- a/utils/gen_adldata/gen_adldata.cc
+++ b/utils/gen_adldata/gen_adldata.cc
@@ -46,6 +46,8 @@ int main(int argc, char**argv)
return 1;
}
+ BanksDump db;
+
std::fprintf(outFile, "\
#include \"adldata.hh\"\n\
\n\
@@ -130,7 +132,7 @@ int main(int argc, char**argv)
else
if(format == "WOPL")
{
- if(!LoadWopl(filepath.c_str(), bank, prefix.c_str()))
+ if(!LoadWopl(db, filepath.c_str(), bank, prefix.c_str()))
{
std::fprintf(stderr, "Failed to load bank %u, file %s!\n", bank, filepath.c_str());
return 1;
@@ -565,6 +567,8 @@ int main(int argc, char**argv)
std::fclose(outFile);
+ db.exportBanks(std::string(outFile_s) + "x");
+
std::printf("Generation of ADLMIDI data has been completed!\n");
std::fflush(stdout);
}
diff --git a/utils/gen_adldata/progs_cache.cpp b/utils/gen_adldata/progs_cache.cpp
index 10124a8..df78026 100644
--- a/utils/gen_adldata/progs_cache.cpp
+++ b/utils/gen_adldata/progs_cache.cpp
@@ -1,4 +1,5 @@
#include "progs_cache.h"
+#include <cstdio>
InstrumentDataTab insdatatab;
@@ -121,3 +122,175 @@ insdata MakeNoSoundIns()
return { {0x00, 0x10, 0x07, 0x07, 0xF7, 0xF7, 0x00, 0x00, 0xFF, 0xFF, 0x00}, 0, false};
}
+
+size_t BanksDump::initBank(size_t bankId, uint_fast16_t bankSetup)
+{
+#if 0
+ assert(bankId <= banks.size());
+ if(bankId >= banks.size())
+ banks.emplace_back();
+ BankEntry &b = banks[bankId];
+#else
+ banks.emplace_back();
+ BankEntry &b = banks.back();
+#endif
+ b.bankId = bankId;
+ b.bankSetup = bankSetup;
+ return b.bankId;
+}
+
+void BanksDump::addMidiBank(size_t bankId, bool percussion, BanksDump::MidiBank b)
+{
+ assert(bankId < banks.size());
+ BankEntry &be = banks[bankId];
+
+ auto it = std::find(midiBanks.begin(), midiBanks.end(), b);
+ if(it == midiBanks.end())
+ {
+ b.midiBankId = midiBanks.size();
+ midiBanks.push_back(b);
+ }
+ else
+ {
+ b.midiBankId = it->midiBankId;
+ }
+
+ if(percussion)
+ be.percussion.push_back(b.midiBankId);
+ else
+ be.melodic.push_back(b.midiBankId);
+}
+
+void BanksDump::addInstrument(BanksDump::MidiBank &bank, size_t patchId, BanksDump::InstrumentEntry e, BanksDump::Operator *ops)
+{
+ assert(patchId < 128);
+ size_t opsCount = ((e.instFlags & InstrumentEntry::WOPL_Ins_4op) != 0 ||
+ (e.instFlags & InstrumentEntry::WOPL_Ins_Pseudo4op) != 0) ?
+ 4 : 2;
+ for(size_t op = 0; op < opsCount; op++)
+ {
+ Operator o = ops[op];
+ auto it = std::find(operators.begin(), operators.end(), o);
+ if(it == operators.end())
+ {
+ o.opId = operators.size();
+ e.ops[op] = static_cast<int_fast32_t>(o.opId);
+ operators.push_back(o);
+ }
+ else
+ {
+ e.ops[op] = static_cast<int_fast32_t>(it->opId);
+ }
+ }
+
+ auto it = std::find(instruments.begin(), instruments.end(), e);
+ if(it == instruments.end())
+ {
+ e.instId = instruments.size();
+ instruments.push_back(e);
+ }
+ else
+ {
+ e.instId = it->instId;
+ }
+ bank.instruments[patchId] = static_cast<int_fast32_t>(e.instId);
+}
+
+void BanksDump::exportBanks(const std::string &outPath, const std::string &headerName)
+{
+ FILE *out = std::fopen(outPath.c_str(), "w");
+
+ std::fprintf(out, "/**********************************************************\n"
+ " This file is generated by `gen_adldata` automatically\n"
+ " Don't edit it directly!\n"
+ " To modify content of this file, modify banks\n"
+ " and re-run the `gen_adldata` build step.\n"
+ "***********************************************************/\n\n"
+ "#include \"%s\"\n\n\n", headerName.c_str());
+
+ std::fprintf(out, "const size_t g_embeddedBanksCount = %zu;\n\n", banks.size());
+ std::fprintf(out, "const BanksDump::BankEntry g_embeddedBanks[] =\n"
+ "{\n");
+ for(const BankEntry &be : banks)
+ {
+ std::fprintf(out, " {\n");
+ std::fprintf(out, " 0x%04lX, %zu, %zu,",
+ be.bankSetup,
+ be.melodic.size(),
+ be.percussion.size());
+ // Melodic banks
+ std::fprintf(out, " { ");
+ for(const size_t &me : be.melodic)
+ std::fprintf(out, "%zu, ", me);
+ std::fprintf(out, " },\n");
+
+ // Percussive banks
+ std::fprintf(out, " { ");
+ for(const size_t &me : be.percussion)
+ std::fprintf(out, "%zu, ", me);
+ std::fprintf(out, " }\n");
+
+ std::fprintf(out, " },\n");
+ }
+
+ std::fprintf(out, "}\n\n");
+
+
+ std::fprintf(out, "const BanksDump::MidiBank g_embeddedBanksMidi[] =\n"
+ "{\n");
+ for(const MidiBank &be : midiBanks)
+ {
+ std::fprintf(out, " {\n");
+ std::fprintf(out, " %u, %u,", be.msb, be.lsb);
+
+ std::fprintf(out, " { ");
+ for(size_t i = 0; i < 128; i++)
+ std::fprintf(out, "%ld, ", be.instruments[i]);
+ std::fprintf(out, " },\n");
+
+ std::fprintf(out, " },\n");
+ }
+ std::fprintf(out, "}\n\n");
+
+
+ std::fprintf(out, "const BanksDump::InstrumentEntry g_embeddedBanksInstruments[] =\n"
+ "{\n");
+ for(const InstrumentEntry &be : instruments)
+ {
+ size_t opsCount = ((be.instFlags & InstrumentEntry::WOPL_Ins_4op) != 0 ||
+ (be.instFlags & InstrumentEntry::WOPL_Ins_Pseudo4op) != 0) ? 4 : 2;
+ std::fprintf(out, " {\n");
+ std::fprintf(out, " %u, %u, %d, %u, %lu, %d, %lu, %lu, %lu, ",
+ be.noteOffset1,
+ be.noteOffset2,
+ be.midiVelocityOffset,
+ be.percussionKeyNumber,
+ be.instFlags,
+ be.secondVoiceDetune,
+ be.fbConn,
+ be.delay_on_ms,
+ be.delay_off_ms);
+
+ if(opsCount == 4)
+ std::fprintf(out, "{%ld, %ld, %ld, %ld}",
+ be.ops[0], be.ops[1], be.ops[2], be.ops[3]);
+ else
+ std::fprintf(out, "{%ld, %ld}",
+ be.ops[0], be.ops[1]);
+
+ std::fprintf(out, " },\n");
+ }
+ std::fprintf(out, "}\n\n");
+
+ std::fprintf(out, "const BanksDump::Operator g_embeddedBanksOperators[] =\n"
+ "{\n");
+ for(const Operator &be : operators)
+ {
+ std::fprintf(out, " { %08lX, %02lX },\n",
+ be.d_E862,
+ be.d_40);
+ }
+ std::fprintf(out, "}\n\n");
+
+ std::fclose(out);
+}
diff --git a/utils/gen_adldata/progs_cache.h b/utils/gen_adldata/progs_cache.h
index a6614b3..d115ddc 100644
--- a/utils/gen_adldata/progs_cache.h
+++ b/utils/gen_adldata/progs_cache.h
@@ -12,6 +12,10 @@
#include <vector>
#include <limits>
#include <cmath>
+#include <cstdint>
+
+#include <cassert>
+
struct insdata
{
@@ -130,7 +134,7 @@ struct BanksDump
{
struct BankEntry
{
- uint_fast32_t bankId;
+ uint_fast32_t bankId = 0;
/* Global OPL flags */
typedef enum WOPLFileFlags
@@ -166,21 +170,68 @@ struct BanksDump
SETUP_CMF = 0x0201
};
- uint_fast16_t bankSetup; // 0xAABB, AA - OPL flags, BB - Volume model
+ uint_fast16_t bankSetup = SETUP_Generic; // 0xAABB, AA - OPL flags, BB - Volume model
std::vector<size_t> melodic;
std::vector<size_t> percussion;
+
+ explicit BankEntry() = default;
+
+ BankEntry(const BankEntry &o)
+ {
+ bankId = o.bankId;
+ bankSetup = o.bankSetup;
+ melodic = o.melodic;
+ percussion = o.percussion;
+ }
+
+ BankEntry(const BankEntry &&o)
+ {
+ bankId = std::move(o.bankId);
+ bankSetup = std::move(o.bankSetup);
+ melodic = std::move(o.melodic);
+ percussion = std::move(o.percussion);
+ }
};
struct MidiBank
{
- uint_fast32_t midiBankId;
- uint_fast8_t msb, lsb;
- int_fast32_t instruments[128];
+ uint_fast32_t midiBankId = 0;
+ uint_fast8_t msb = 0, lsb = 0;
+ int_fast32_t instruments[128];
+
+ MidiBank()
+ {
+ for(size_t i = 0; i < 128; i++)
+ instruments[i] = -1;
+ }
+
+ MidiBank(const MidiBank &o)
+ {
+ midiBankId = 0;
+ msb = 0;
+ lsb = 0;
+ std::memcpy(instruments, o.instruments, sizeof(int_fast32_t) * 128);
+ }
+
+ bool operator==(const MidiBank &o)
+ {
+ if(msb != o.msb)
+ return false;
+ if(lsb != o.lsb)
+ return false;
+ if(std::memcmp(instruments, o.instruments, sizeof(int_fast32_t) * 128) != 0)
+ return false;
+ return true;
+ }
+ bool operator!=(const MidiBank &o)
+ {
+ return !operator==(o);
+ }
};
struct InstrumentEntry
{
- uint_fast32_t instId;
+ uint_fast32_t instId = 0;
typedef enum WOPL_InstrumentFlags
{
@@ -214,34 +265,68 @@ struct BanksDump
WOPL_RM_HiHat = 0x28
} WOPL_RhythmMode;
- uint_fast8_t noteOffset1;
- uint_fast8_t noteOffset2;
- int_fast8_t midiVelocityOffset;
- uint_fast8_t percussionKeyNumber;
- uint_fast32_t instFlags;
- double secondVoiceDetune;
+ uint_fast8_t noteOffset1 = 0;
+ uint_fast8_t noteOffset2 = 0;
+ int_fast8_t midiVelocityOffset = 0;
+ uint_fast8_t percussionKeyNumber = 0;
+ uint_fast32_t instFlags = 0;
+ int_fast8_t secondVoiceDetune = 0;
/*
2op: modulator1, carrier1, feedback1
2vo: modulator1, carrier1, modulator2, carrier2, feedback(1+2)
4op: modulator1, carrier1, modulator2, carrier2, feedback1
*/
//! Contains FeedBack-Connection for both operators 0xBBAA - AA - first, BB - second
- int16_t fbConn;
- size_t ops[5] = {-1, -1, -1, -1, -1};
- int64_t delay_on_ms;
- int64_t delay_off_ms;
+ int_fast16_t fbConn = 0;
+ int_fast64_t delay_on_ms = 0;
+ int_fast64_t delay_off_ms = 0;
+ int_fast32_t ops[5] = {-1, -1, -1, -1, -1};
+
+ bool operator==(const InstrumentEntry &o)
+ {
+ return (
+ (noteOffset1 == o.noteOffset1) &&
+ (noteOffset2 == o.noteOffset2) &&
+ (midiVelocityOffset == o.midiVelocityOffset) &&
+ (percussionKeyNumber == o.percussionKeyNumber) &&
+ (instFlags == o.instFlags) &&
+ (secondVoiceDetune == o.secondVoiceDetune) &&
+ (fbConn == o.fbConn) &&
+ (delay_on_ms == o.delay_on_ms) &&
+ (delay_off_ms == o.delay_off_ms) &&
+ (std::memcmp(ops, o.ops, sizeof(int_fast32_t) * 5) == 0)
+ );
+ }
+ bool operator!=(const InstrumentEntry &o)
+ {
+ return !operator==(o);
+ }
};
struct Operator
{
- uint_fast32_t d_E862;
- uint_fast32_t d_40;
+ uint_fast32_t opId = 0;
+ uint_fast32_t d_E862 = 0;
+ uint_fast32_t d_40 = 0;
+ bool operator==(const Operator &o)
+ {
+ return ((d_E862 == o.d_E862) && (d_40 == o.d_40));
+ }
+ bool operator!=(const Operator &o)
+ {
+ return !operator==(o);
+ }
};
std::vector<BankEntry> banks;
std::vector<MidiBank> midiBanks;
std::vector<InstrumentEntry> instruments;
std::vector<Operator> operators;
+
+ size_t initBank(size_t bankId, uint_fast16_t bankSetup);
+ void addMidiBank(size_t bankId, bool percussion, MidiBank b);
+ void addInstrument(MidiBank &bank, size_t patchId, InstrumentEntry e, Operator *ops);
+ void exportBanks(const std::string &outPath, const std::string &headerName = "adlmidi_db.h");
};