diff options
Diffstat (limited to 'src/gen_adldata/file_formats')
-rw-r--r-- | src/gen_adldata/file_formats/common.h | 28 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_ail.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_bisqwit.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_bnk.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_bnk2.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_ibk.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_jv.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_op2.h | 8 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_tmb.h | 2 | ||||
-rw-r--r-- | src/gen_adldata/file_formats/load_wopl.h | 248 |
10 files changed, 287 insertions, 11 deletions
diff --git a/src/gen_adldata/file_formats/common.h b/src/gen_adldata/file_formats/common.h new file mode 100644 index 0000000..d06059e --- /dev/null +++ b/src/gen_adldata/file_formats/common.h @@ -0,0 +1,28 @@ +#ifndef COMMON_H +#define COMMON_H + +#include <stdint.h> + +inline uint16_t toUint16BE(const uint8_t *arr) +{ + uint16_t num = arr[1]; + num |= ((arr[0] << 8) & 0xFF00); + return num; +} + +inline int16_t toSint16BE(const uint8_t *arr) +{ + int16_t num = *reinterpret_cast<const int8_t *>(&arr[0]); + num *= 1 << 8; + num |= arr[1]; + return num; +} + +inline uint16_t toUint16LE(const uint8_t *arr) +{ + uint16_t num = arr[0]; + num |= ((arr[1] << 8) & 0xFF00); + return num; +} + +#endif // COMMON_H diff --git a/src/gen_adldata/file_formats/load_ail.h b/src/gen_adldata/file_formats/load_ail.h index 3a0e975..4c6c482 100644 --- a/src/gen_adldata/file_formats/load_ail.h +++ b/src/gen_adldata/file_formats/load_ail.h @@ -89,7 +89,7 @@ static bool LoadMiles(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = gmno < 128 ? 0 : (unsigned char)notenum; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; std::string name; if(midi_index >= 0) name = std::string(1, '\377') + MidiInsName[midi_index]; size_t resno = InsertIns(tmp[0], tmp[1], tmp2, name, name2); diff --git a/src/gen_adldata/file_formats/load_bisqwit.h b/src/gen_adldata/file_formats/load_bisqwit.h index 98fcd83..4928efa 100644 --- a/src/gen_adldata/file_formats/load_bisqwit.h +++ b/src/gen_adldata/file_formats/load_bisqwit.h @@ -25,7 +25,7 @@ static bool LoadBisqwit(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = (uint8_t)std::fgetc(fp); tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; insdata tmp[2]; for(int side = 0; side < 2; ++side) diff --git a/src/gen_adldata/file_formats/load_bnk.h b/src/gen_adldata/file_formats/load_bnk.h index 2b6e1c4..79ce5f5 100644 --- a/src/gen_adldata/file_formats/load_bnk.h +++ b/src/gen_adldata/file_formats/load_bnk.h @@ -107,7 +107,7 @@ static bool LoadBNK(const char *fn, unsigned bank, const char *prefix, bool is_f ins tmp2; tmp2.notenum = is_fat ? voice_num : (percussive ? usage_flag : 0); tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; if(is_fat) tmp.data[10] ^= 1; diff --git a/src/gen_adldata/file_formats/load_bnk2.h b/src/gen_adldata/file_formats/load_bnk2.h index 84ba06c..202402c 100644 --- a/src/gen_adldata/file_formats/load_bnk2.h +++ b/src/gen_adldata/file_formats/load_bnk2.h @@ -81,7 +81,7 @@ static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix, ins tmp2; tmp2.notenum = (gmno & 128) ? 35 : 0; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; if(xxP24NNN & 8) { diff --git a/src/gen_adldata/file_formats/load_ibk.h b/src/gen_adldata/file_formats/load_ibk.h index cb5505e..6370ad0 100644 --- a/src/gen_adldata/file_formats/load_ibk.h +++ b/src/gen_adldata/file_formats/load_ibk.h @@ -61,7 +61,7 @@ static bool LoadIBK(const char *fn, unsigned bank, const char *prefix, bool perc struct ins tmp2; tmp2.notenum = gmno < 128 ? 0 : 35; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; size_t resno = InsertIns(tmp, tmp, tmp2, std::string(1, '\377') + name, name2); SetBank(bank, (unsigned int)gmno, resno); diff --git a/src/gen_adldata/file_formats/load_jv.h b/src/gen_adldata/file_formats/load_jv.h index b48013b..f35de03 100644 --- a/src/gen_adldata/file_formats/load_jv.h +++ b/src/gen_adldata/file_formats/load_jv.h @@ -71,7 +71,7 @@ static bool LoadJunglevision(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = data[offset + 1]; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; while(tmp2.notenum && tmp2.notenum < 20) { diff --git a/src/gen_adldata/file_formats/load_op2.h b/src/gen_adldata/file_formats/load_op2.h index 0d95f59..30a118f 100644 --- a/src/gen_adldata/file_formats/load_op2.h +++ b/src/gen_adldata/file_formats/load_op2.h @@ -96,7 +96,7 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = ins.note; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; while(tmp2.notenum && tmp2.notenum < 20) { tmp2.notenum += 12; @@ -112,11 +112,11 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix) else // Double instrument { tmp2.pseudo4op = true; - tmp2.fine_tune = (((double)ins.finetune - 128.0) * 15.625) / 1000.0; + tmp2.voice2_fine_tune = (((double)ins.finetune - 128.0) * 15.625) / 1000.0; if(ins.finetune == 129) - tmp2.fine_tune = 0.000025; + tmp2.voice2_fine_tune = 0.000025; else if(ins.finetune == 127) - tmp2.fine_tune = -0.000025; + tmp2.voice2_fine_tune = -0.000025; //printf("/*DOOM FINE TUNE (flags %000X instrument is %d) IS %d -> %lf*/\n", ins.flags, a, ins.finetune, tmp2.fine_tune); size_t resno = InsertIns(tmp[0], tmp[1], tmp2, std::string(1, '\377') + name, name2); SetBank(bank, (unsigned int)gmno, resno); diff --git a/src/gen_adldata/file_formats/load_tmb.h b/src/gen_adldata/file_formats/load_tmb.h index 2b07c65..c5a3f60 100644 --- a/src/gen_adldata/file_formats/load_tmb.h +++ b/src/gen_adldata/file_formats/load_tmb.h @@ -50,7 +50,7 @@ static bool LoadTMB(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = data[offset + 11]; tmp2.pseudo4op = false; - tmp2.fine_tune = 0.0; + tmp2.voice2_fine_tune = 0.0; std::string name; if(midi_index >= 0) name = std::string(1, '\377') + MidiInsName[midi_index]; diff --git a/src/gen_adldata/file_formats/load_wopl.h b/src/gen_adldata/file_formats/load_wopl.h new file mode 100644 index 0000000..66eed1e --- /dev/null +++ b/src/gen_adldata/file_formats/load_wopl.h @@ -0,0 +1,248 @@ +#ifndef LOAD_WOPL_H +#define LOAD_WOPL_H + +#include "../progs_cache.h" +#include "../midi_inst_list.h" +#include "common.h" + +static uint8_t wopl_latest_version = 2; + +static bool LoadWopl(const char *fn, unsigned bank, const char *prefix) +{ + FILE *fp = std::fopen(fn, "rb"); + if(!fp) + { + std::fprintf(stderr, "WOPL: CAN'T OPEN FILE %s\n", fn); + std::fflush(stderr); + return false; + } + std::fseek(fp, 0, SEEK_END); + std::vector<unsigned char> data(size_t(std::ftell(fp))); + std::rewind(fp); + if(std::fread(&data[0], 1, data.size(), fp) != data.size()) + { + std::fclose(fp); + std::fprintf(stderr, "WOPL: CAN'T READ FILE %s\n", fn); + std::fflush(stderr); + return false; + } + std::fclose(fp); + + if(data.size() < 19) // Smaller than header size + { + std::fprintf(stderr, "WOPL: Too small header %s\n", fn); + std::fflush(stderr); + return false; + } + + uint16_t version = toUint16LE((const uint8_t *)data.data() + 11); + if(version > wopl_latest_version) + { + std::fprintf(stderr, "WOPL: Version %d is not supported (latest %d) %s\n", version, wopl_latest_version, fn); + std::fflush(stderr); + return false; + } + + uint16_t mbanks_count = toUint16BE((const uint8_t *)data.data() + 0x0d); + uint16_t pbanks_count = toUint16BE((const uint8_t *)data.data() + 0x0f); + + // Validate file format by size calculation + if(version == 1) + { + //Header size + melodic banks + percussion banks + if(data.size() < size_t(19 + (62 * 128 * mbanks_count) + (62 * 128 * pbanks_count))) + { + std::fprintf(stderr, "WOPL: Version 1 size calculation failed %s\n", fn); + std::fflush(stderr); + return false; + } + } + else if(version >= 2) + { + //Header size + melodic bank meta data + percussion bank meta data + melodic banks + percussion banks + if(data.size() < size_t(19 + (34 * mbanks_count) + (34 * pbanks_count) + (62 * 128 * mbanks_count) + (62 * 128 * pbanks_count))) + { + std::fprintf(stderr, "WOPL: Version %d size calculation failed %s\n", version, fn); + std::fflush(stderr); + return false; + } + } + + uint32_t melodic_offset = 0; + uint32_t percussion_offset = 0; + if(version < 2) + melodic_offset = 0x13; + else + melodic_offset = 0x13 + 34 * mbanks_count + 34 * pbanks_count; + + percussion_offset = melodic_offset + (62 * 128 * mbanks_count); + + for(uint32_t mbank = 0; mbank < 1; mbank++) // only first melodic bank (Until multi-banks support will be implemented) + { + uint32_t bank_offset = melodic_offset + (mbank * 62 * 128); + + for(unsigned i = 0; i < 128; i++) + { + uint32_t offset = bank_offset + uint32_t(i * 62); + std::string name; + insdata tmp[2]; + + name.resize(32); + std::memcpy(&name[0], data.data() + offset, 32); + name.resize(std::strlen(&name[0])); + + tmp[0].data[0] = data[offset + 42 + 5]; + tmp[0].data[1] = data[offset + 42 + 0]; + tmp[0].data[2] = data[offset + 42 + 7]; + tmp[0].data[3] = data[offset + 42 + 2]; + tmp[0].data[4] = data[offset + 42 + 8]; + tmp[0].data[5] = data[offset + 42 + 3]; + tmp[0].data[6] = data[offset + 42 + 9]; + tmp[0].data[7] = data[offset + 42 + 4]; + tmp[0].data[8] = data[offset + 42 + 6]; + tmp[0].data[9] = data[offset + 42 + 1]; + tmp[0].data[10] = data[offset + 40]; + + tmp[1].data[0] = data[offset + 52 + 5]; + tmp[1].data[1] = data[offset + 52 + 0]; + tmp[1].data[2] = data[offset + 52 + 7]; + tmp[1].data[3] = data[offset + 52 + 2]; + tmp[1].data[4] = data[offset + 52 + 8]; + tmp[1].data[5] = data[offset + 52 + 3]; + tmp[1].data[6] = data[offset + 52 + 9]; + tmp[1].data[7] = data[offset + 52 + 4]; + tmp[1].data[8] = data[offset + 52 + 6]; + tmp[1].data[9] = data[offset + 52 + 1]; + tmp[1].data[10] = data[offset + 41]; + + tmp[0].finetune = int8_t(toSint16BE((const uint8_t *)data.data() + offset + 32)); + tmp[1].finetune = int8_t(toSint16BE((const uint8_t *)data.data() + offset + 34)); + + uint8_t flags = data[offset + 39]; + + struct ins tmp2; + tmp2.notenum = 0; + tmp2.pseudo4op = (flags & 0x02) != 0; + tmp2.voice2_fine_tune = 0; + + int8_t fine_tune = (int8_t)data[offset + 37]; + if(fine_tune != 0) + { + if(fine_tune == 1) + tmp2.voice2_fine_tune = 0.000025; + else if(fine_tune == -1) + tmp2.voice2_fine_tune = -0.000025; + else + tmp2.voice2_fine_tune = ((fine_tune * 15.625) / 1000.0); + } + + if(name.empty()) + name = std::string(1, '\377') + MidiInsName[i]; + else + name.insert(0, 1, '\377'); + + char name2[512]; + sprintf(name2, "%sM%u", prefix, i); + + if(!flags) + { + size_t resno = InsertIns(tmp[0], tmp[0], tmp2, name, name2); + SetBank(bank, i, resno); + } + else + { + size_t resno = InsertIns(tmp[0], tmp[1], tmp2, name, name2); + SetBank(bank, i, resno); + } + } + } + + for(uint32_t pbank = 0; pbank < 1; pbank++) // only first percussion bank (Until multi-banks support will be implemented) + { + uint32_t bank_offset = percussion_offset + (pbank * 62 * 128); + + for(uint32_t i = 0; i < 128; i++) + { + uint32_t offset = bank_offset + (i * 62); + std::string name; + insdata tmp[2]; + + name.resize(32); + std::memcpy(&name[0], data.data() + offset, 32); + name.resize(std::strlen(&name[0])); + + tmp[0].data[0] = data[offset + 42 + 5]; + tmp[0].data[1] = data[offset + 42 + 0]; + tmp[0].data[2] = data[offset + 42 + 7]; + tmp[0].data[3] = data[offset + 42 + 2]; + tmp[0].data[4] = data[offset + 42 + 8]; + tmp[0].data[5] = data[offset + 42 + 3]; + tmp[0].data[6] = data[offset + 42 + 9]; + tmp[0].data[7] = data[offset + 42 + 4]; + tmp[0].data[8] = data[offset + 42 + 6]; + tmp[0].data[9] = data[offset + 42 + 1]; + tmp[0].data[10] = data[offset + 40]; + + tmp[1].data[0] = data[offset + 52 + 5]; + tmp[1].data[1] = data[offset + 52 + 0]; + tmp[1].data[2] = data[offset + 52 + 7]; + tmp[1].data[3] = data[offset + 52 + 2]; + tmp[1].data[4] = data[offset + 52 + 8]; + tmp[1].data[5] = data[offset + 52 + 3]; + tmp[1].data[6] = data[offset + 52 + 9]; + tmp[1].data[7] = data[offset + 52 + 4]; + tmp[1].data[8] = data[offset + 52 + 6]; + tmp[1].data[9] = data[offset + 52 + 1]; + tmp[1].data[10] = data[offset + 41]; + + tmp[0].finetune = int8_t(toSint16BE((const uint8_t *)data.data() + offset + 32)); + tmp[1].finetune = int8_t(toSint16BE((const uint8_t *)data.data() + offset + 34)); + + uint8_t flags = data[offset + 39]; + + struct ins tmp2; + tmp2.notenum = data[offset + 38]; + tmp2.pseudo4op = (flags & 0x02) != 0; + tmp2.voice2_fine_tune = 0; + + int8_t fine_tune = (int8_t)data[offset + 37]; + if(fine_tune != 0) + { + if(fine_tune == 1) + tmp2.voice2_fine_tune = 0.000025; + else if(fine_tune == -1) + tmp2.voice2_fine_tune = -0.000025; + else + tmp2.voice2_fine_tune = ((fine_tune * 15.625) / 1000.0); + } + + uint32_t gmno = i + 128; + int midi_index = (gmno < (128 + 35)) ? -1 + : (gmno < (128 + 88)) ? int(gmno) - 35 + : -1; + + if(name.empty() && (midi_index >= 0)) + name = std::string(1, '\377') + MidiInsName[midi_index]; + if(!name.empty()) + name.insert(0, 1, '\377'); + + char name2[512]; + sprintf(name2, "%sP%u", prefix, gmno & 127); + + if(!flags) + { + size_t resno = InsertIns(tmp[0], tmp[0], tmp2, name, name2); + SetBank(bank, gmno, resno); + } + else + { + size_t resno = InsertIns(tmp[0], tmp[1], tmp2, name, name2); + SetBank(bank, gmno, resno); + } + } + } + return true; +} + + +#endif // LOAD_WOPL_H |