@@ -664,41 +664,54 @@ class JaiSeqInstrBNK : public VGMInstr {
664664
665665 uint32_t osciIndex = GetWordBE (dwOffset + 0x08 );
666666 assert (osciIndex < osctCount);
667- uint32_t envpOffs = GetWordBE (osctBase + 0x08 + (osciIndex * 0x1C ) + 0x10 );
668- uint32_t envpBase = envtBase + envpOffs;
669- uint32_t attack = GetWordBE (envpBase + 0x00 );
670- uint32_t release = GetWordBE (envpBase + 0x08 );
671-
672- uint32_t numRegions = GetWordBE (dwOffset + 0x10 );
673- uint32_t regionTableIdx = dwOffset + 0x14 ;
674- uint32_t keyLow = 0 ;
675- for (uint32_t i = 0 ; i < numRegions; i++) {
667+ uint32_t envpOffs = GetWordBE (osctBase + 0x0C + (osciIndex * 0x1C ) + 0x10 );
668+ uint32_t envpBase = envtBase + 0x08 + envpOffs;
669+ uint16_t attack = GetShortBE (envpBase + 0x00 );
670+ uint16_t decay = GetShortBE (envpBase + 0x02 );
671+ uint16_t sustain = GetShortBE (envpBase + 0x04 );
672+ uint16_t release = GetShortBE (envpBase + 0x06 );
673+
674+ uint32_t instIdx = dwOffset + 0x0C ;
675+ if (GetWordBE (instIdx) == 0x02 )
676+ instIdx += 0x08 ;
677+ else if (GetWordBE (instIdx) != 0 )
678+ instIdx += 0x04 ;
679+ instIdx += 0x04 ;
680+
681+ uint32_t keyRgnCount = GetWordBE (instIdx + 0x00 );
682+ uint32_t regionTableIdx = instIdx + 0x04 ;
683+ uint8_t keyLow = 0 ;
684+ for (uint32_t i = 0 ; i < keyRgnCount; i++) {
676685 uint8_t keyHigh = GetByte (regionTableIdx);
677686 regionTableIdx += 0x04 ;
678- /* This is probably velocity regions... */
679- uint32_t numSamples = GetWordBE (regionTableIdx);
680- uint32_t sampleNum;
681- VGMRgn *rgn;
682687
688+ uint32_t velRgnCount = GetWordBE (regionTableIdx);
683689 regionTableIdx += 0x04 ;
684- if (numSamples == 0x00 )
685- goto next;
686690
687- assert (numSamples == 0x01 );
691+ uint8_t velLow = 0 ;
692+ for (uint32_t j = 0 ; j < velRgnCount; j++) {
693+ uint8_t velHigh = GetByte (regionTableIdx);
694+ uint32_t regStart = regionTableIdx;
695+ regionTableIdx += 0x04 ;
688696
689- regionTableIdx += 0x04 ; /* unknown */
690- regionTableIdx += 0x02 ; /* unknown as well */
691- sampleNum = GetShortBE (regionTableIdx);
692- regionTableIdx += 0x02 ;
693- regionTableIdx += 0x04 ; /* unknown */
694- regionTableIdx += 0x04 ; /* frequency multiplier */
697+ uint32_t sampleNum;
698+ VGMRgn *rgn;
695699
696- rgn = AddRgn (regionTableIdx, 0x18 , sampleNum, keyLow, keyHigh);
700+ regionTableIdx += 0x02 ; /* unknown */
701+ sampleNum = GetShortBE (regionTableIdx);
702+ regionTableIdx += 0x02 ;
703+ regionTableIdx += 0x04 ; /* unknown */
704+ regionTableIdx += 0x04 ; /* frequency multiplier */
705+
706+ rgn = AddRgn (regStart, regionTableIdx - regStart, sampleNum, keyLow, keyHigh, velLow, velHigh);
707+
708+ /* Fake ADSR for now. */
709+ rgn->attack_time = 0.0 ;
710+ rgn->release_time = 0.2 ;
711+
712+ velLow = velHigh + 1 ;
713+ }
697714
698- /* Fake ADSR for now. */
699- rgn->attack_time = ((double )attack) / 0x3FFF ;
700- rgn->release_time = ((double )release) / 0x0C ;
701- next:
702715 keyLow = keyHigh + 1 ;
703716 }
704717 }
@@ -770,12 +783,7 @@ class JaiSeqInstrSetBNK : public VGMInstrSet {
770783 name = buf;
771784
772785 osctBase = FindChunk (" OSCT" );
773- /* Skip past chunk, size, length */
774- osctBase += 0x0C ;
775-
776786 envtBase = FindChunk (" ENVT" );
777- /* Skip past chunk */
778- envtBase += 0x04 ;
779787
780788 /* We should have found LIST */
781789 uint32_t listBase = FindChunk (" LIST" ) + 0x08 ;
@@ -871,39 +879,73 @@ class JaiSeqInstrAAF : public VGMInstr {
871879
872880private:
873881 virtual bool LoadInstr () override {
874- if (!MatchMagic (vgmfile->rawfile , dwOffset, " INST" ))
875- return false ;
882+ if (MatchMagic (vgmfile->rawfile , dwOffset, " INST" )) {
883+ uint32_t keyRgnCount = GetWordBE (dwOffset + 0x28 );
884+ uint32_t keyRgnIdx = dwOffset + 0x2C ;
885+ uint8_t keyLow = 0 ;
886+ for (uint32_t i = 0 ; i < keyRgnCount; i++) {
887+ uint32_t keyRgnBase = parInstrSet->dwOffset + GetWordBE (keyRgnIdx);
888+ keyRgnIdx += 0x04 ;
889+
890+ uint8_t keyHigh = GetByte (keyRgnBase);
891+
892+ uint32_t velRgnCount = GetWordBE (keyRgnBase + 0x04 );
893+ uint32_t velRgnIdx = keyRgnBase + 0x08 ;
894+ uint8_t velLow = 0 ;
895+ for (uint32_t j = 0 ; j < velRgnCount; j++) {
896+ uint32_t velRgnBase = parInstrSet->dwOffset + GetWordBE (velRgnIdx);
897+ uint8_t velHigh = GetByte (velRgnBase);
898+
899+ /* 0x04 is some sort of bank identifier? Doesn't seem to match the WSYS ID... */
900+ uint32_t sampleNum = GetShortBE (velRgnBase + 0x06 );
901+ /* 0x08 = unknown float */
902+ uint32_t freqMultBits = GetWordBE (velRgnBase + 0x0C );
903+ float freqMult = *((float *)&freqMultBits);
904+
905+ VGMRgn *rgn = AddRgn (keyRgnBase, 0 , sampleNum, keyLow, keyHigh, velLow, velHigh);
906+ rgn->SetFineTune (FrequencyRatioToCents (freqMult));
907+ velLow = velHigh + 1 ;
908+ velRgnIdx += 0x04 ;
909+ }
876910
877- uint32_t keyRgnCount = GetWordBE (dwOffset + 0x28 );
878- uint32_t keyRgnIdx = dwOffset + 0x2C ;
879- uint8_t keyLow = 0 ;
880- for (uint32_t i = 0 ; i < keyRgnCount; i++) {
881- uint32_t keyRgnBase = parInstrSet->dwOffset + GetWordBE (keyRgnIdx);
882- keyRgnIdx += 0x04 ;
883-
884- uint8_t keyHigh = GetByte (keyRgnBase);
885-
886- uint32_t velRgnCount = GetWordBE (keyRgnBase + 0x04 );
887- uint32_t velRgnIdx = keyRgnBase + 0x08 ;
888- uint8_t velLow = 0 ;
889- for (uint32_t j = 0 ; j < velRgnCount; j++) {
890- uint32_t velRgnBase = parInstrSet->dwOffset + GetWordBE (velRgnIdx);
891- uint8_t velHigh = GetByte (velRgnBase);
892-
893- /* 0x04 is some sort of bank identifier? Doesn't seem to match the WSYS ID... */
894- uint32_t sampleNum = GetShortBE (velRgnBase + 0x06 );
895- /* 0x08 = unknown float */
896- uint32_t freqMultBits = GetWordBE (velRgnBase + 0x0C );
897- float freqMult = *((float *) &freqMultBits);
898-
899- VGMRgn *rgn = AddRgn (keyRgnBase, 0 , sampleNum, keyLow, keyHigh, velLow, velHigh);
900- rgn->SetFineTune (FrequencyRatioToCents (freqMult));
901- velLow = velHigh + 1 ;
902- velRgnIdx += 0x04 ;
911+ keyLow = keyHigh + 1 ;
903912 }
913+ return true ;
914+ } else if (MatchMagic (vgmfile->rawfile , dwOffset, " PER2" )) {
915+ uint32_t keyRgnIdx = dwOffset + 0x88 ;
916+ for (uint32_t i = 0 ; i < 100 ; i++) {
917+ uint32_t keyRgnOffs = GetWordBE (keyRgnIdx);
918+ keyRgnIdx += 0x04 ;
919+ if (keyRgnOffs == 0 )
920+ continue ;
904921
905- keyLow = keyHigh + 1 ;
922+ uint32_t keyRgnBase = parInstrSet->dwOffset + keyRgnOffs;
923+ uint32_t keyRgnFreqMultBits = GetWordBE (keyRgnBase + 0x04 );
924+ float keyRgnFreqMult = *((float *)&keyRgnFreqMultBits);
925+
926+ uint32_t velRgnCount = GetWordBE (keyRgnBase + 0x10 );
927+ uint32_t velRgnIdx = keyRgnBase + 0x14 ;
928+ uint8_t velLow = 0 ;
929+ for (uint32_t j = 0 ; j < velRgnCount; j++) {
930+ uint32_t velRgnBase = parInstrSet->dwOffset + GetWordBE (velRgnIdx);
931+ uint8_t velHigh = GetByte (velRgnBase);
932+
933+ /* 0x04 is some sort of bank identifier? Doesn't seem to match the WSYS ID... */
934+ uint32_t sampleNum = GetShortBE (velRgnBase + 0x06 );
935+ /* 0x08 = unknown float */
936+ uint32_t velRgnFreqMultBits = GetWordBE (velRgnBase + 0x0C );
937+ float velRgnFreqMult = *((float *)&velRgnFreqMultBits);
938+
939+ VGMRgn *rgn = AddRgn (keyRgnBase, 0 , sampleNum, i, i, velLow, velHigh);
940+ rgn->SetFineTune (FrequencyRatioToCents (velRgnFreqMult * keyRgnFreqMult));
941+ rgn->SetUnityKey (i);
942+ velLow = velHigh + 1 ;
943+ velRgnIdx += 0x04 ;
944+ }
945+ }
946+ return true ;
906947 }
948+ return false ;
907949 }
908950};
909951
@@ -937,14 +979,13 @@ class JaiSeqInstrSetAAF : public VGMInstrSet {
937979 return false ;
938980
939981 uint32_t listIdx = bankOffs + 0x04 ;
940- uint32_t instrNum = 0 ;
941- while (true ) {
982+ for (uint32_t instrNum = 0 ; instrNum < 245 ; instrNum++) {
942983 uint32_t instrOffs = GetWordBE (listIdx);
984+ listIdx += 0x04 ;
943985 if (instrOffs == 0x00 )
944- break ;
986+ continue ;
945987 uint32_t instrBase = dwOffset + instrOffs;
946- aInstrs.push_back (new JaiSeqInstrAAF (this , instrBase, 0 , instrNum++));
947- listIdx += 0x04 ;
988+ aInstrs.push_back (new JaiSeqInstrAAF (this , instrBase, 0 , instrNum & 0x7F ));
948989 }
949990
950991 return true ;
0 commit comments