Exemplo n.º 1
0
        protected void ExtractAllUsingCueList(string destinationFolder)
        {
            CriUtfTable waveformTableUtf;
            ushort      waveformIndex;
            byte        encodeType;
            string      rawFileName;
            string      rawFileFormat = "{0}.{1}{2}";

            FileStream internalFs = null;
            FileStream externalFs = null;

            ArrayList internalIdsExtracted = new ArrayList();
            ArrayList externalIdsExtracted = new ArrayList();

            string acbAwbDestinationFolder = Path.Combine(destinationFolder, ACB_AWB_EXTRACTION_FOLDER);
            string extAwbDestinationFolder = Path.Combine(destinationFolder, EXT_AWB_EXTRACTION_FOLDER);
            string acbCpkDestinationFolder = Path.Combine(destinationFolder, ACB_CPK_EXTRACTION_FOLDER);
            string extCpkDestinationFolder = Path.Combine(destinationFolder, EXT_CPK_EXTRACTION_FOLDER);

            try
            {
                // open streams
                if (this.InternalAwb != null)
                {
                    internalFs = File.Open(this.InternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                else if (this.InternalCpk != null)
                {
                    internalFs = File.Open(this.InternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                }

                if (this.ExternalAwb != null)
                {
                    externalFs = File.Open(this.ExternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                else if (this.ExternalCpk != null)
                {
                    externalFs = File.Open(this.ExternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                }

                // loop through cues and extract
                for (int i = 0; i < CueList.Length; i++)
                {
                    CriAcbCueRecord cue = CueList[i];

                    if (cue.IsWaveformIdentified)
                    {
                        if (cue.IsStreaming) // external AWB file
                        {
                            if (this.ExternalAwb != null)
                            {
                                ParseFile.ExtractChunkToFile64(externalFs,
                                                               (ulong)this.ExternalAwb.Files[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.ExternalAwb.Files[cue.WaveformId].FileLength,
                                                               Path.Combine(extAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }
                            else if (this.ExternalCpk != null)
                            {
                                ParseFile.ExtractChunkToFile64(externalFs,
                                                               (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileLength,
                                                               Path.Combine(extCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }

                            externalIdsExtracted.Add(cue.WaveformId);
                        }
                        else // internal AWB file (inside ACB)
                        {
                            if (this.InternalAwb != null)
                            {
                                ParseFile.ExtractChunkToFile64(internalFs,
                                                               (ulong)this.InternalAwb.Files[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.InternalAwb.Files[cue.WaveformId].FileLength,
                                                               Path.Combine(acbAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }
                            else if (this.InternalCpk != null)
                            {
                                ParseFile.ExtractChunkToFile64(internalFs,
                                                               (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileLength,
                                                               Path.Combine(acbCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }

                            internalIdsExtracted.Add(cue.WaveformId);
                        }
                    } // if (cue.IsWaveformIdentified)
                }

                // extract leftovers
                using (FileStream acbStream = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    waveformTableUtf = new CriUtfTable();
                    waveformTableUtf.Initialize(acbStream, (long)this.WaveformTableOffset);
                }

                if (this.ExternalAwb != null)
                {
                    var unextractedExternalFiles = this.ExternalAwb.Files.Keys.Where(x => !externalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedExternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.ExternalAwb.SourceFile), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(externalFs,
                                                       (ulong)this.ExternalAwb.Files[key].FileOffsetByteAligned,
                                                       (ulong)this.ExternalAwb.Files[key].FileLength,
                                                       Path.Combine(extAwbDestinationFolder, rawFileName), false, false);
                    }
                }
                else if (this.ExternalCpk != null)
                {
                    var unextractedExternalFiles = this.ExternalCpk.ItocFiles.Keys.Where(x => !externalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedExternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.ExternalCpk.SourceFileName), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(externalFs,
                                                       (ulong)this.ExternalCpk.ItocFiles[key].FileOffsetByteAligned,
                                                       (ulong)this.ExternalCpk.ItocFiles[key].FileLength,
                                                       Path.Combine(extCpkDestinationFolder, rawFileName), false, false);
                    }
                }

                if (this.InternalAwb != null)
                {
                    var unextractedInternalFiles = this.InternalAwb.Files.Keys.Where(x => !internalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedInternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.InternalAwb.SourceFile), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(internalFs,
                                                       (ulong)this.InternalAwb.Files[key].FileOffsetByteAligned,
                                                       (ulong)this.InternalAwb.Files[key].FileLength,
                                                       Path.Combine(acbAwbDestinationFolder, rawFileName), false, false);
                    }
                }
                else if (this.InternalCpk != null)
                {
                    var unextractedInternalFiles = this.InternalCpk.ItocFiles.Keys.Where(x => !internalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedInternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.InternalCpk.SourceFileName), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(internalFs,
                                                       (ulong)this.InternalCpk.ItocFiles[key].FileOffsetByteAligned,
                                                       (ulong)this.InternalCpk.ItocFiles[key].FileLength,
                                                       Path.Combine(acbCpkDestinationFolder, rawFileName), false, false);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (internalFs != null)
                {
                    internalFs.Close();
                    internalFs.Dispose();
                }

                if (externalFs != null)
                {
                    externalFs.Close();
                    externalFs.Dispose();
                }
            }
        }
Exemplo n.º 2
0
        protected void InitializeCueList(FileStream fs)
        {
            CueNamesToWaveforms = new Dictionary <string, ushort>();

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

            object dummy;
            byte   isStreaming = 0;

            var cueTableUtf = new CriUtfTable();

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

            var waveformTableUtf = new CriUtfTable();

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

            var synthTableUtf = new CriUtfTable();

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

            CueList = new CriAcbCueRecord[cueTableUtf.NumberOfRows];

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

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

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

                case 3:
                case 8:
                    if (i == 0)
                    {
                        referenceItemsOffset =
                            (ulong)GetOffsetForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceItemsSize  = 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.",
                                                  CueList[i].ReferenceType.ToString("D"), i.ToString("D")));
                }

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

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

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

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

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

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


                        // update flag
                        CueList[i].IsWaveformIdentified = true;
                    } // if (dummy != null)
                }
            }
        }