public static PphdStruct GetPphdData(FileStream fs, long offset) { PphdStruct phdObject = new PphdStruct(); // save off info phdObject.startingOffset = offset; phdObject.progSectionOffset = offset + BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0x10, 4), 0); phdObject.toneSectionOffset = offset + BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0x14, 4), 0); phdObject.vagSectionOffset = offset + BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0x18, 4), 0); phdObject.maxVagInfoNumber = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, phdObject.vagSectionOffset + 0x14, 4), 0); phdObject.vagInfoSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, phdObject.vagSectionOffset + 8, 4), 0); phdObject.vagOffsets = new long[phdObject.maxVagInfoNumber + 1]; phdObject.vagLengths = new long[phdObject.maxVagInfoNumber + 1]; phdObject.expectedPbdLength = 0; phdObject.IsSmallSamplePresent = false; for (int i = 0; i <= phdObject.maxVagInfoNumber; i++) { phdObject.vagOffsets[i] = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, phdObject.vagSectionOffset + 0x20 + (i * phdObject.vagInfoSize) + 0, 4), 0); phdObject.vagLengths[i] = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, phdObject.vagSectionOffset + 0x20 + (i * phdObject.vagInfoSize) + 8, 4), 0); phdObject.expectedPbdLength += phdObject.vagLengths[i]; if (phdObject.vagLengths[i] < Psf.MIN_ADPCM_ROW_SIZE) { phdObject.IsSmallSamplePresent = true; } } phdObject.length = phdObject.vagSectionOffset - offset + 0x20 + ((phdObject.maxVagInfoNumber + 1) * phdObject.vagInfoSize); return(phdObject); }
private PphdStruct PopulatePbdOffsetLength(Stream searchStream, Psf.ProbableItemStruct[] potentialPbdList, int potentialPbdStartIndex, PphdStruct phdObject) { PphdStruct ret = phdObject; long totalLength = 0; byte[] lastLine = new byte[Psf.SONY_ADPCM_ROW_SIZE]; string errorMessage; for (int i = 0; i < phdObject.vagLengths.Length; i++) { if ((potentialPbdStartIndex + i) >= potentialPbdList.Length) { errorMessage = String.Format(" Warning, a potential PBD match for {0} found at 0x{1}, " + "but index would exceed array bounds. It is suggested that you check manually if a match " + "is not found at completion.{2}", phdObject.FileName, potentialPbdList[potentialPbdStartIndex].offset.ToString("X8"), Environment.NewLine); throw new IndexOutOfRangeException(errorMessage); } else { totalLength += phdObject.vagLengths[i]; if (i == (phdObject.vagLengths.Length - 1)) { // check last value searchStream.Position = potentialPbdList[potentialPbdStartIndex + i].offset + phdObject.vagLengths[i] + (phdObject.expectedPbdLength - totalLength) - lastLine.Length; searchStream.Read(lastLine, 0, lastLine.Length); if (lastLine[1] == 3 || ParseFile.CompareSegment(lastLine, 0, Psf.VB_END_BYTES_1) || ParseFile.CompareSegment(lastLine, 0, Psf.VB_END_BYTES_2)) { ret.pbdStartingOffset = potentialPbdList[potentialPbdStartIndex].offset; ret.pbdLength = phdObject.expectedPbdLength; } else // reset in case a match has already been found for this HD { ret.pbdStartingOffset = 0; ret.pbdLength = 0; } } else if (phdObject.vagLengths[i] != potentialPbdList[potentialPbdStartIndex + i].length) { // if we have a small sample, and a minimum number of matches, check the expected length if (phdObject.IsSmallSamplePresent) { double matchPercentage = (double)i / (double)phdObject.vagLengths.Length; if (matchPercentage >= Psf.MIN_SAMPLE_MATCH_PERCENTAGE) { // check last row for expected length searchStream.Position = potentialPbdList[potentialPbdStartIndex].offset + phdObject.expectedPbdLength - lastLine.Length; searchStream.Read(lastLine, 0, lastLine.Length); if (lastLine[1] == 3 || ParseFile.CompareSegment(lastLine, 0, Psf2.VB_END_BYTES_1) || ParseFile.CompareSegment(lastLine, 0, Psf2.VB_END_BYTES_2)) { ret.pbdStartingOffset = potentialPbdList[potentialPbdStartIndex].offset; ret.pbdLength = phdObject.expectedPbdLength; this.progressStruct.Clear(); this.progressStruct.GenericMessage = String.Format(" PHD <{0}> contains a sample smaller than 0x{1}, partial matching will be used. Be sure to thoroughly listen to assembled files.{2}", ret.FileName, Psf2.MIN_ADPCM_ROW_SIZE.ToString("X8"), Environment.NewLine); this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct); } else // reset in case a match has already been found for this HD { ret.pbdStartingOffset = 0; ret.pbdLength = 0; } } else // reset in case a match has already been found for this HD { ret.pbdStartingOffset = 0; ret.pbdLength = 0; } } else { ret.pbdStartingOffset = -1; ret.pbdLength = -1; } break; } } } return(ret); }