diff options
author | Wohlstand <admin@wohlnet.ru> | 2017-10-20 04:28:53 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2017-10-20 04:28:53 +0300 |
commit | eb45a7913d83fe2a3dc03033230950e78fb9755d (patch) | |
tree | d7318e79b08404f293fb99bb22e0ed202e07d890 /utils/dumpbank | |
parent | e95cde9fea4f9daf3e19492021b8a153acae0404 (diff) | |
download | libADLMIDI-eb45a7913d83fe2a3dc03033230950e78fb9755d.tar.gz libADLMIDI-eb45a7913d83fe2a3dc03033230950e78fb9755d.tar.bz2 libADLMIDI-eb45a7913d83fe2a3dc03033230950e78fb9755d.zip |
Added CMake support
Diffstat (limited to 'utils/dumpbank')
-rw-r--r-- | utils/dumpbank/dumpbank.cpp | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/utils/dumpbank/dumpbank.cpp b/utils/dumpbank/dumpbank.cpp new file mode 100644 index 0000000..6996681 --- /dev/null +++ b/utils/dumpbank/dumpbank.cpp @@ -0,0 +1,179 @@ +//#ifdef __MINGW32__ +//typedef struct vswprintf {} swprintf; +//#endif +#include <cstdio> +#include <vector> +#include <cstring> + +struct BNK1_header +{ + char maj_vers, min_vers; + char signature[6]; // "ADLIB-" + unsigned short ins_used, ins_entries; + unsigned name_list, inst_data; +} __attribute__((packed)); +struct BNK1_record +{ + unsigned short index; + unsigned char used; + char name[9]; +} __attribute__((packed)); +struct OPL2_op +{ + unsigned char key_scale_lvl; + unsigned char freq_mult; + unsigned char feedback; + unsigned char attack; + unsigned char sustain_lvl; + unsigned char sustain_sound; + unsigned char decay; + unsigned char release; + unsigned char out_lvl; + unsigned char amp_vib; + unsigned char pitch_vib; + unsigned char env_scaling; + unsigned char connection; +} __attribute__((packed)); +struct BNK1_instrument +{ + unsigned char sound_mode; + unsigned char voice_num; + OPL2_op ops[2]; + unsigned char waveforms[2]; +} __attribute__((packed)); // conventional Ad Lib instrument maker bankfile patch + +struct BNK2_header +{ + char signature[28]; // "Accomp. Bank, (C) AdLib Inc" + unsigned short file_ver; + char filler[10]; + unsigned short ins_entries, ins_used; + int lostSpace; +} __attribute__((packed)); +struct BNK2_record +{ + char O3_sig[3]; + char key[12]; + char used; + int attrib, dataOffset; + unsigned short blockSize, allocBSize; +} __attribute__((packed)); +struct OPL3_op +{ + unsigned char AVEKMMMM, KKLLLLLL; + unsigned char AAAADDDD, SSSSRRRR; + unsigned char DxxxxWWW, xxxxxxxx; +} __attribute__((packed)); +struct BNK2_instrument +{ + OPL3_op ops[4]; + unsigned char C4xxxFFFC; + unsigned char xxP24NNN; + unsigned char TTTTTTTT; + unsigned char xxxxxxxx; +} __attribute__((packed)); // Ad Lib Gold instrument maker bankfile patch + +static void LoadBNK1(const std::vector<unsigned char>& data) +{ + const BNK1_header& bnk1 = *(const BNK1_header*) &data[0]; + const BNK1_record* names = (const BNK1_record*) &data[ bnk1.name_list ]; + const BNK1_instrument* ins = (const BNK1_instrument*) &data[ bnk1.inst_data ]; + std::printf("BNK1 version: %d.%d\n", bnk1.maj_vers, bnk1.min_vers); + for(unsigned a=0; a<bnk1.ins_entries; ++a) + { + std::printf("%04X %02X %-9.9s: ", + names[a].index, names[a].used, names[a].name); + + const BNK1_instrument& i = ins[ names[a].index ]; + std::printf("%02X %02X %X %X", + i.sound_mode, i.voice_num, i.waveforms[0], i.waveforms[1]); + for(unsigned b=0; b<2; ++b) + { + std::printf(" | "); + std::printf("%X %X %X %X %X %X %X %X %02X %X %X %X %X", + i.ops[b].key_scale_lvl, + i.ops[b].freq_mult, + b==1 ? 0 : i.ops[b].feedback, + i.ops[b].attack, + i.ops[b].sustain_lvl, + i.ops[b].sustain_sound, + i.ops[b].decay, + i.ops[b].release, + i.ops[b].out_lvl, + i.ops[b].amp_vib, + i.ops[b].pitch_vib, + i.ops[b].env_scaling, + b==1 ? 0 : i.ops[b].connection); + } + std::printf("\n"); + } +} +static void LoadBNK2(const std::vector<unsigned char>& data) +{ + const BNK2_header& bnk2 = *(const BNK2_header*) &data[0]; + const BNK2_record* names = (const BNK2_record*) &data[ sizeof(bnk2) ]; + std::printf("BNK2 version: %d, lost space %d\n", bnk2.file_ver, bnk2.lostSpace); + for(unsigned a=0; a<bnk2.ins_entries; ++a) + { + std::printf("%3.3s %-12.12s %02X %08X %04X %04X: ", + names[a].O3_sig, + names[a].key, + names[a].used, + names[a].attrib, + names[a].blockSize, + names[a].allocBSize); + + const BNK2_instrument& i = *(const BNK2_instrument*) &data[ names[a].dataOffset ]; + std::printf("%02X %02X %02X %02X", + i.C4xxxFFFC, i.xxP24NNN, i.TTTTTTTT, i.xxxxxxxx); + for(unsigned b=0; b<4; ++b) + { + std::printf(" | "); + std::printf("%02X %02X %02X %02X %02X %02X", + i.ops[b].AVEKMMMM, + i.ops[b].KKLLLLLL, + i.ops[b].AAAADDDD, + i.ops[b].SSSSRRRR, + i.ops[b].DxxxxWWW, + i.ops[b].xxxxxxxx); + } + std::printf("\n"); + } +} + +static void LoadBNK(const char* fn) +{ + FILE* fp = fopen(fn, "rb"); + if(!fp) + { + std::fprintf(stderr, "ERROR: Can't open %s file!", fn); + return; + } + + std::fseek(fp, 0, SEEK_END); + std::vector<unsigned char> data(ftell(fp)); + std::rewind(fp); + size_t got = std::fread(&data[0], 1, data.size(), fp); + std::fclose(fp); + + if(got == 0) + { + std::fprintf(stderr, "ERROR: Can't read %s file!", fn); + return; + } + + const BNK1_header& bnk1 = *(const BNK1_header*) &data[0]; + const BNK2_header& bnk2 = *(const BNK2_header*) &data[0]; + + if(std::memcmp(bnk1.signature, "ADLIB-", 6) == 0) + LoadBNK1(data); + else if(std::memcmp(bnk2.signature, "Accomp. Bank, (C) AdLib Inc", 28) == 0) + LoadBNK2(data); + else + std::fprintf(stderr, "%s: Unknown format\n", fn); +} + +int main(int argc, const char* const* argv) +{ + LoadBNK(argv[1]); +} |