std::unique_ptr<Music> MusicType_IBK::read(stream::input& content, SuppData& suppData) const { auto music = std::make_unique<Music>(); music->patches.reset(new PatchBank()); uint8_t names[IBK_INST_COUNT * IBK_NAME_LEN]; content.seekg(4 + IBK_INST_COUNT * IBK_INST_LEN, stream::start); content.read(names, IBK_INST_COUNT * IBK_NAME_LEN); // Read the instruments music->patches->reserve(IBK_INST_COUNT); content.seekg(4, stream::start); for (unsigned int i = 0; i < IBK_INST_COUNT; i++) { auto patch = std::make_shared<OPLPatch>(); uint8_t inst[IBK_INST_LEN]; content.read((char *)inst, IBK_INST_LEN); OPLOperator *o = &patch->m; for (int op = 0; op < 2; op++) { o->enableTremolo = (inst[0 + op] >> 7) & 1; o->enableVibrato = (inst[0 + op] >> 6) & 1; o->enableSustain = (inst[0 + op] >> 5) & 1; o->enableKSR = (inst[0 + op] >> 4) & 1; o->freqMult = inst[0 + op] & 0x0F; o->scaleLevel = inst[2 + op] >> 6; o->outputLevel = inst[2 + op] & 0x3F; o->attackRate = inst[4 + op] >> 4; o->decayRate = inst[4 + op] & 0x0F; o->sustainRate = inst[6 + op] >> 4; o->releaseRate = inst[6 + op] & 0x0F; o->waveSelect = inst[8 + op] & 0x07; o = &patch->c; } patch->feedback = (inst[10] >> 1) & 0x07; patch->connection = inst[10] & 1; patch->rhythm = OPLPatch::Rhythm::Melodic; uint8_t *name = &names[i * IBK_NAME_LEN]; unsigned int namelen = 9; for (int l = 0; l < 9; l++) { if (name[l] == 0) { namelen = l; break; } } patch->name = std::string((char *)name, namelen); music->patches->push_back(patch); } return music; }
MusicType::Certainty MusicType_IBK::isInstance(stream::input& content) const { // Make sure the signature matches // TESTED BY: mus_ibk_isinstance_c01 char sig[4]; content.seekg(0, stream::start); content.read(sig, 4); if (strncmp(sig, "IBK\x1A", 4) != 0) return Certainty::DefinitelyNo; // All files are the same size // TESTED BY: mus_ibk_isinstance_c02 if (content.size() != IBK_LENGTH) return Certainty::DefinitelyNo; // TESTED BY: mus_ibk_isinstance_c00 return Certainty::DefinitelyYes; }