Example #1
0
        protected void InitializeCueList(FileStream fs)
        {
            this.CueNamesToWaveforms = new Dictionary <string, ushort>();

            ulong referenceItemsOffset = 0;
            ulong referenceItemsSize   = 0;
            ulong referenceCorrection  = 0;

            object dummy;
            byte   isStreaming = 0;

            CriUtfTable cueTableUtf = new CriUtfTable();

            cueTableUtf.Initialize(fs, (long)this.CueTableOffset);

            CriUtfTable waveformTableUtf = new CriUtfTable();

            waveformTableUtf.Initialize(fs, (long)this.WaveformTableOffset);

            CriUtfTable synthTableUtf = new CriUtfTable();

            synthTableUtf.Initialize(fs, (long)this.SynthTableOffset);

            this.CueList = new CriAcbCueRecord[cueTableUtf.NumberOfRows];

            for (int i = 0; i < cueTableUtf.NumberOfRows; i++)
            {
                this.CueList[i] = new CriAcbCueRecord();
                this.CueList[i].IsWaveformIdentified = false;

                this.CueList[i].CueId          = (uint)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "CueId");
                this.CueList[i].ReferenceType  = (byte)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceType");
                this.CueList[i].ReferenceIndex = (ushort)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceIndex");

                switch (this.CueList[i].ReferenceType)
                {
                case 2:
                    referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceCorrection  = referenceItemsSize + 2;
                    break;

                case 3:
                case 8:
                    if (i == 0)
                    {
                        referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceCorrection  = referenceItemsSize - 2;    // samples found have only had a '01 00' record => Always Waveform[0]?.
                    }
                    else
                    {
                        referenceCorrection += 4;     // relative to previous offset, do not lookup
                                                      // @TODO: Should this do a referenceItemsSize - 2 for the ReferenceIndex?  Need to find
                                                      //    one where size > 4.
                        //referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceItemsSize = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceCorrection = referenceItemsSize - 2;
                    }
                    break;

                default:
                    throw new FormatException(String.Format("  Unexpected ReferenceType: '{0}' for CueIndex: '{1}.'  Please report to VGMToolbox thread at hcs64.com forums, see link in 'Other' menu item.", this.CueList[i].ReferenceType.ToString("D"), i.ToString("D")));
                }

                if (referenceItemsSize != 0)
                {
                    // get wave form info
                    this.CueList[i].WaveformIndex = ParseFile.ReadUshortBE(fs, (long)(referenceItemsOffset + referenceCorrection));

                    // get Streaming flag, 0 = in ACB files, 1 = in AWB file
                    dummy = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Streaming");

                    if (dummy != null) // check to see if this Id actually exists in the WaveformIndex
                    {
                        isStreaming = (byte)dummy;
                        this.CueList[i].IsStreaming = isStreaming == 0 ? false : true;

                        // get waveform id and encode type from corresponding waveform
                        var waveformId = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Id");

                        if (waveformId != null)
                        {
                            // early revisions of ACB spec used "Id"
                            this.CueList[i].WaveformId = (ushort)waveformId;
                        }
                        else
                        {
                            // later versions using "MemoryAwbId" and  "StreamingAwbId"
                            if (this.CueList[i].IsStreaming)
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "StreamAwbId");
                            }
                            else
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "MemoryAwbId");
                            }
                        }

                        this.CueList[i].EncodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "EncodeType");


                        // update flag
                        this.CueList[i].IsWaveformIdentified = true;
                    } // if (dummy != null)
                }
            }
        }
Example #2
0
        public CriCpkDirectory GetDirectoryForItoc(FileStream fs, CriUtfTable cpkUtf, string BaseDirectoryName, long volumeBaseOffset)
        {
            ulong             currentOffset = 0;
            CriUtfTocFileInfo fileInfo      = new CriUtfTocFileInfo();
            CriAfs2File       afs2File      = new CriAfs2File();

            // get content offset and align
            ulong  contentOffset = (ulong)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "ContentOffset");
            ushort align         = (ushort)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "Align");

            // build direcory path
            CriCpkDirectory baseDirectory = new CriCpkDirectory(this.SourceFileName, BaseDirectoryName, String.Empty);
            CriCpkFile      tempFile;

            // read file groups
            uint   filesH    = 0;
            uint   filesL    = 0;
            object filesHObj = CriUtfTable.GetUtfFieldForRow(this.ItocUtf, 0, "FilesH"); //count of files in DataH
            object filesLObj = CriUtfTable.GetUtfFieldForRow(this.ItocUtf, 0, "FilesL"); // count of files in DataL

            if (filesHObj != null)
            {
                filesH = (uint)filesHObj;
            }

            if (filesHObj != null)
            {
                filesL = (uint)filesLObj;
            }

            if ((filesH > 0) || (filesL > 0))
            {
                Dictionary <string, CriUtfTocFileInfo> fileList = new Dictionary <string, CriUtfTocFileInfo>();

                if (filesH > 0)
                {
                    // read DataH group
                    CriUtfTable dataH = new CriUtfTable();
                    dataH.Initialize(fs, (long)CriUtfTable.GetOffsetForUtfFieldForRow(this.ItocUtf, 0, "DataH"));

                    for (int i = 0; i < dataH.Rows.GetLength(0); i++)
                    {
                        fileInfo = GetUtfItocFileInfo(dataH, i);
                        fileList.Add(fileInfo.FileName, fileInfo);
                    }
                }

                if (filesL > 0)
                {
                    // read DataL group
                    CriUtfTable dataL = new CriUtfTable();
                    dataL.Initialize(fs, (long)CriUtfTable.GetOffsetForUtfFieldForRow(this.ItocUtf, 0, "DataL"));

                    for (int i = 0; i < dataL.Rows.GetLength(0); i++)
                    {
                        fileInfo = GetUtfItocFileInfo(dataL, i);
                        fileList.Add(fileInfo.FileName, fileInfo);
                    }
                }

                // initialize current offset
                currentOffset = contentOffset;

                // populate offsets for files
                var keys = fileList.Keys.ToList();
                keys.Sort();

                foreach (string key in keys)
                {
                    // afs2 file for ACB extraction
                    afs2File               = new CriAfs2File();
                    afs2File.CueId         = Convert.ToUInt16(fileList[key].FileName); // ??? @TODO maybe key is enough?  need to check.
                    afs2File.FileOffsetRaw = volumeBaseOffset + (long)currentOffset;

                    // align offset
                    if (currentOffset % align != 0)
                    {
                        currentOffset = MathUtil.RoundUpToByteAlignment(currentOffset, align);
                    }

                    // update file info
                    fileList[key].FileOffset = (ulong)volumeBaseOffset + currentOffset;
                    fileList[key].FileName  += ".bin";

                    // afs2 file for ACB extraction
                    afs2File.FileOffsetByteAligned = (long)fileList[key].FileOffset;
                    afs2File.FileLength            = fileList[key].FileSize;

                    // increment current offset
                    currentOffset += fileList[key].FileSize;

                    // create file and add to base directory
                    tempFile = new CriCpkFile(BaseDirectoryName, this.SourceFileName, fileList[key].FileName,
                                              (long)fileList[key].FileOffset, this.VolumeBaseOffset, (long)fileList[key].FileOffset,
                                              fileList[key].FileSize, fileList[key].ExtractSize);

                    baseDirectory.FileArray.Add(tempFile);

                    // add afs2 file to ItocFiles for ACB extraction
                    this.ItocFiles.Add(afs2File.CueId, afs2File);
                } // foreach (string key in keys)
            }     // if ((filesH > 0) || (filesL > 0))


            return(baseDirectory);
        }