Beispiel #1
0
        public static string GetTotalSamples(string pSourcePath, GenhCreationStruct pGenhCreationStruct)
        {
            int formatId   = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Format);
            int headerSkip = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.HeaderSkip);
            int channels   = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Channels);
            int interleave = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Interleave);
            int loopEnd    = -1;

            FileInfo fi         = new FileInfo(Path.GetFullPath(pSourcePath));
            int      fileLength = (int)fi.Length;

            loopEnd = BytesToSamples(formatId, (fileLength - headerSkip), channels, interleave);

            return(loopEnd.ToString());
        }
Beispiel #2
0
        public static GenhCreationStruct GetGenhCreationStruct(Genh genhItem)
        {
            GenhCreationStruct gcStruct = new GenhCreationStruct();

            int formatValue = BitConverter.ToInt32(genhItem.Identifier, 0);

            gcStruct.Format       = formatValue.ToString();
            gcStruct.HeaderSkip   = "0x" + ((BitConverter.ToInt32(genhItem.AudioStart, 0) - BitConverter.ToInt32(genhItem.HeaderLength, 0))).ToString("X4");
            gcStruct.Interleave   = "0x" + BitConverter.ToInt32(genhItem.Interleave, 0).ToString("X4");
            gcStruct.Channels     = BitConverter.ToInt32(genhItem.Channels, 0).ToString();
            gcStruct.Frequency    = BitConverter.ToInt32(genhItem.Frequency, 0).ToString();
            gcStruct.TotalSamples = BitConverter.ToInt32(genhItem.TotalSamples, 0).ToString();

            gcStruct.SkipSamplesMode = genhItem.SkipSamplesMode;
            gcStruct.SkipSamples     = BitConverter.ToInt32(genhItem.SkipSamples, 0).ToString();

            gcStruct.Atrac3StereoMode = genhItem.Atrac3StereoMode;
            gcStruct.XmaStreamMode    = genhItem.XmaStreamMode;
            gcStruct.RawDataSize      = BitConverter.ToInt32(genhItem.RawStreamSize, 0).ToString();

            int loopStartValue = BitConverter.ToInt32(genhItem.LoopStart, 0);

            if (loopStartValue > -1)
            {
                gcStruct.LoopStart = loopStartValue.ToString();
            }
            else
            {
                gcStruct.LoopStart = String.Empty;
            }

            int loopEndValue = BitConverter.ToInt32(genhItem.LoopEnd, 0);

            if (loopEndValue > 0)
            {
                gcStruct.LoopEnd          = loopEndValue.ToString();
                gcStruct.UseLoopEndOffset = true;
            }
            else
            {
                gcStruct.LoopEnd          = String.Empty;
                gcStruct.UseLoopEndOffset = false;
            }

            if (formatValue == 12)
            {
                gcStruct.CoefficientType = genhItem.CoefficientType[0];

                if (gcStruct.CoefficientType == 1 || gcStruct.CoefficientType == 3) // Split Coefficients (aka Capcom Hack)
                {
                    gcStruct.CoefRightChannel = "0x" + (BitConverter.ToUInt32(genhItem.RightCoef, 0) - Genh.GENH_HEADER_SIZE - 0x10).ToString("X4");
                    gcStruct.CoefLeftChannel  = "0x" + (BitConverter.ToUInt32(genhItem.LeftCoef, 0) - Genh.GENH_HEADER_SIZE - 0x10).ToString("X4");
                }
                else
                {
                    gcStruct.CoefRightChannel = "0x" + (BitConverter.ToUInt32(genhItem.RightCoef, 0) - Genh.GENH_HEADER_SIZE).ToString("X4");
                    gcStruct.CoefLeftChannel  = "0x" + (BitConverter.ToUInt32(genhItem.LeftCoef, 0) - Genh.GENH_HEADER_SIZE).ToString("X4");
                }
            }

            return(gcStruct);
        }
Beispiel #3
0
        public static bool GetPsAdpcmLoop(string pSourcePath,
                                          GenhCreationStruct pGenhCreationStruct, out string pLoopStart, out string pLoopEnd)
        {
            bool ret = false;

            pLoopStart = Genh.EMPTY_SAMPLE_COUNT;
            pLoopEnd   = Genh.EMPTY_SAMPLE_COUNT;

            long loopStart = -1;
            long loopEnd   = -1;

            long loopCheckBytesOffset;

            byte[] possibleLoopBytes;

            long   headerSkip       = VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.HeaderSkip);
            int    channels         = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Channels);
            int    interleave       = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Interleave);
            string fullIncomingPath = Path.GetFullPath(pSourcePath);

            byte[] checkByte = new byte[1];

            FileInfo fi = new FileInfo(Path.GetFullPath(fullIncomingPath));

            if ((fi.Length - headerSkip) % 0x10 != 0)
            {
                throw new Exception(String.Format("Error processing <{0}> Length of file minus the header skip value is not divisible by 0x10.  This is not a proper PS ADPCM rip.", fullIncomingPath));
            }

            using (BinaryReader br = new BinaryReader(File.OpenRead(fullIncomingPath)))
            {
                // Loop Start
                br.BaseStream.Position = headerSkip + 0x01;

                while (br.BaseStream.Position < fi.Length)
                {
                    br.Read(checkByte, 0, checkByte.Length);

                    if (checkByte[0] == 0x06)
                    {
                        loopStart = br.BaseStream.Position - 2 - headerSkip;

                        break;
                    }
                    else
                    {
                        br.BaseStream.Position += 0x10 - 0x01;
                    }
                }

                // Loop End
                br.BaseStream.Position = fi.Length - 0x0F;

                while (br.BaseStream.Position > headerSkip)
                {
                    br.Read(checkByte, 0, checkByte.Length);

                    if (checkByte[0] == 0x03)
                    {
                        loopEnd = br.BaseStream.Position + 0x0E - headerSkip;

                        //if (channels > 1)
                        //{
                        //    loopEnd -= interleave;
                        //}

                        break;
                    }
                    else if (br.BaseStream.Position >= 0x11)
                    {
                        br.BaseStream.Position -= 0x11;
                    }
                    else
                    {
                        br.BaseStream.Position = headerSkip;
                    }
                }

                // if loop end found but start not found, try alternate method
                if ((loopEnd >= 0) && (loopStart < 0))
                {
                    loopCheckBytesOffset = loopEnd + headerSkip - SONY_ADPCM_LOOP_HACK_BYTE_COUNT;
                    possibleLoopBytes    = ParseFile.ParseSimpleOffset(
                        br.BaseStream,
                        loopCheckBytesOffset,
                        SONY_ADPCM_LOOP_HACK_BYTE_COUNT - 0x10);
                    loopStart = ParseFile.GetNextOffset(br.BaseStream, 0, possibleLoopBytes, true);

                    if ((loopStart > 0) && (loopStart < loopCheckBytesOffset))
                    {
                        loopStart += SONY_ADPCM_LOOP_HACK_BYTE_COUNT - headerSkip;
                    }
                }
            }

            if (loopStart >= 0)
            {
                pLoopStart = (loopStart / 16 / channels * 28).ToString();
                ret        = true;
            }

            if (loopEnd >= 0)
            {
                pLoopEnd = (loopEnd / 16 / channels * 28).ToString();
                ret      = true;
            }

            return(ret);
        }
Beispiel #4
0
        public static string CreateGenhFile(string pSourcePath, GenhCreationStruct pGenhCreationStruct)
        {
            string ret = String.Empty;

            System.Text.Encoding enc = System.Text.Encoding.ASCII;
            long testCoefficient;

            int dspInterleaveType =
                GetDspInterleave(pGenhCreationStruct.Interleave, pGenhCreationStruct.Channels);

            //--------------
            // looping info
            //--------------
            if (pGenhCreationStruct.NoLoops)
            {
                pGenhCreationStruct.LoopStart = Genh.EMPTY_SAMPLE_COUNT;
                pGenhCreationStruct.LoopEnd   = Genh.EMPTY_SAMPLE_COUNT;
            }
            else if (pGenhCreationStruct.UseFileEnd)
            {
                pGenhCreationStruct.LoopEnd = GetTotalSamples(pSourcePath, pGenhCreationStruct);
            }
            else if (pGenhCreationStruct.FindLoop)
            {
                string loopStartFound;
                string loopEndFound;

                if (((pGenhCreationStruct.Format.Equals("0")) || (pGenhCreationStruct.Format.Equals("14"))) &&
                    (GetPsAdpcmLoop(pSourcePath, pGenhCreationStruct, out loopStartFound,
                                    out loopEndFound)))
                {
                    pGenhCreationStruct.LoopStart = loopStartFound;
                    pGenhCreationStruct.LoopEnd   = loopEndFound;
                }
                else
                {
                    pGenhCreationStruct.LoopStart = Genh.EMPTY_SAMPLE_COUNT;
                    pGenhCreationStruct.LoopEnd   = GetTotalSamples(pSourcePath, pGenhCreationStruct);
                }
            }

            // set total samples if no loop end found
            if (pGenhCreationStruct.LoopEnd == Genh.EMPTY_SAMPLE_COUNT)
            {
                pGenhCreationStruct.TotalSamples = GetTotalSamples(pSourcePath, pGenhCreationStruct);
            }

            //---------------------
            // offset based values
            //---------------------
            if (pGenhCreationStruct.UseLoopStartOffset ||
                pGenhCreationStruct.UseLoopEndOffset ||
                pGenhCreationStruct.UseInterleaveOffset ||
                pGenhCreationStruct.UseChannelsOffset ||
                pGenhCreationStruct.UseFrequencyOffset ||
                pGenhCreationStruct.UseTotalSamplesOffset)
            {
                int  formatId   = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Format);
                long interleave = VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Interleave);
                long channels   = VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Channels);

                using (FileStream inputFs = File.Open(pSourcePath, FileMode.Open, FileAccess.Read))
                {
                    //------------
                    // Interleave
                    //------------
                    if (pGenhCreationStruct.UseInterleaveOffset)
                    {
                        interleave = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.InterleaveOffsetDescription);
                        pGenhCreationStruct.Interleave = ((int)interleave).ToString();
                    }

                    //----------
                    // Channels
                    //----------
                    if (pGenhCreationStruct.UseChannelsOffset)
                    {
                        channels = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.ChannelsOffsetDescription);
                        pGenhCreationStruct.Channels = ((int)channels).ToString();
                    }

                    //-----------
                    // Frequency
                    //-----------
                    if (pGenhCreationStruct.UseFrequencyOffset)
                    {
                        long frequency = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.FrequencyOffsetDescription);
                        pGenhCreationStruct.Frequency = ((int)frequency).ToString();
                    }

                    //------------
                    // Loop Start
                    //------------
                    if (pGenhCreationStruct.UseLoopStartOffset)
                    {
                        long loopStart = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.LoopStartOffsetDescription);

                        if (pGenhCreationStruct.DoLoopStartBytesToSamples)
                        {
                            loopStart = BytesToSamples(formatId, (int)loopStart, (int)channels, (int)interleave);
                        }

                        pGenhCreationStruct.LoopStart = ((int)loopStart).ToString();
                    }

                    //----------
                    // Loop End
                    //----------
                    if (pGenhCreationStruct.UseLoopEndOffset)
                    {
                        long loopEnd = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.LoopEndOffsetDescription);

                        if (pGenhCreationStruct.DoLoopEndBytesToSamples)
                        {
                            loopEnd = BytesToSamples(formatId, (int)loopEnd, (int)channels, (int)interleave);
                        }

                        pGenhCreationStruct.LoopEnd = ((int)loopEnd).ToString();
                    }

                    //---------------
                    // Total Samples
                    //---------------
                    if (pGenhCreationStruct.UseTotalSamplesOffset)
                    {
                        long totalSamples = ParseFile.GetVaryingByteValueAtAbsoluteOffset(inputFs, pGenhCreationStruct.TotalSamplesOffsetDescription);

                        if (pGenhCreationStruct.DoTotalSamplesBytesToSamples)
                        {
                            totalSamples = BytesToSamples(formatId, (int)totalSamples, (int)channels, (int)interleave);
                        }

                        pGenhCreationStruct.TotalSamples = ((int)totalSamples).ToString();
                    }
                }
            }

            FileInfo fi         = new FileInfo(Path.GetFullPath(pSourcePath));
            UInt32   fileLength = (UInt32)fi.Length;
            string   outputFilePath;

            if (pGenhCreationStruct.OutputHeaderOnly)
            {
                outputFilePath = Path.ChangeExtension(pSourcePath, Genh.FILE_EXTENSION_HEADER);
            }
            else
            {
                outputFilePath = Path.ChangeExtension(pSourcePath, Genh.FILE_EXTENSION);
            }

            // write the file
            using (FileStream outputFs = File.Open(outputFilePath, FileMode.Create, FileAccess.Write))
            {
                using (BinaryWriter bw = new BinaryWriter(outputFs))
                {
                    bw.Write(Genh.ASCII_SIGNATURE);
                    bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Channels));
                    bw.Write((Int32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Interleave));
                    bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Frequency));
                    bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.LoopStart));

                    if (!String.IsNullOrEmpty(pGenhCreationStruct.LoopEnd))
                    {
                        bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.LoopEnd));
                    }
                    else
                    {
                        bw.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                    }

                    bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Format));
                    bw.Write((UInt32)(VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.HeaderSkip) + Genh.GENH_HEADER_SIZE));
                    bw.Write((UInt32)Genh.GENH_HEADER_SIZE);

                    if (VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Format) == 12)
                    {
                        //testCoefficient = VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.CoefLeftChannel) + Genh.GENH_HEADER_SIZE;

                        bw.Write((UInt32)(VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.CoefLeftChannel) + Genh.GENH_HEADER_SIZE));
                        bw.Write((UInt32)(VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.CoefRightChannel) + Genh.GENH_HEADER_SIZE));
                        bw.Write((UInt32)dspInterleaveType);
                        bw.Write((UInt32)pGenhCreationStruct.CoefficientType);

                        if (pGenhCreationStruct.CoefficientType == 1 || pGenhCreationStruct.CoefficientType == 3) // split coefficients (aka Capcom Hack)
                        {
                            bw.Write((UInt32)(VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.CoefLeftChannel) + Genh.GENH_HEADER_SIZE + 0x10));
                            bw.Write((UInt32)(VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.CoefRightChannel) + Genh.GENH_HEADER_SIZE + 0x10));
                        }
                        else
                        {
                            bw.Write(new byte[] { 0x00 });
                        }
                    }

                    // Total Samples
                    if (!String.IsNullOrWhiteSpace(pGenhCreationStruct.TotalSamples))
                    {
                        bw.BaseStream.Position = Genh.TOTAL_SAMPLES_OFFSET;
                        bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.TotalSamples));
                    }

                    // Skip Samples
                    if ((pGenhCreationStruct.SkipSamplesMode != Genh.SKIP_SAMPLES_MODE_AUTODETECT) &&
                        !String.IsNullOrWhiteSpace(pGenhCreationStruct.SkipSamples))
                    {
                        bw.BaseStream.Position = Genh.SKIP_SAMPLES_OFFSET;
                        bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.SkipSamples));

                        // Skip Samples Mode
                        bw.BaseStream.Position = Genh.SKIP_SAMPLES_MODE_OFFSET;
                        bw.Write((byte)pGenhCreationStruct.SkipSamplesMode);
                    }

                    // ATRAC3 Stereo Mode
                    bw.BaseStream.Position = Genh.ATRAC3_STEREO_MODE_OFFSET;
                    bw.Write((byte)pGenhCreationStruct.Atrac3StereoMode);

                    // XMA Stream Mode
                    bw.BaseStream.Position = Genh.XMA_STREAM_MODE_OFFSET;
                    bw.Write((byte)pGenhCreationStruct.XmaStreamMode);

                    // RAW DATA SIZE
                    bw.BaseStream.Position = Genh.RAW_DATA_SIZE_OFFSET;
                    bw.Write((UInt32)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.RawDataSize == null ? "0" : pGenhCreationStruct.RawDataSize));

                    // Original File Size
                    bw.BaseStream.Position = Genh.ORIG_FILENAME_OFFSET;
                    bw.Write(enc.GetBytes(Path.GetFileName(pSourcePath).Trim()));

                    bw.BaseStream.Position = Genh.ORIG_FILESIZE_OFFSET;
                    bw.Write(fileLength);

                    // GENH Version
                    bw.BaseStream.Position = Genh.GENH_VERSION_OFFSET;
                    bw.Write(Genh.CURRENT_VERSION);

                    bw.BaseStream.Position = 0xFFC;
                    bw.Write(0x0);

                    // create batch script or add input file
                    if (pGenhCreationStruct.OutputHeaderOnly)
                    {
                        AddCopyItemToBatchFile(Path.GetDirectoryName(pSourcePath), pSourcePath, outputFilePath);
                    }
                    else
                    {
                        using (FileStream inputFs = File.Open(pSourcePath, FileMode.Open, FileAccess.Read))
                        {
                            using (BinaryReader br = new BinaryReader(inputFs))
                            {
                                byte[] data      = new byte[Constants.FileReadChunkSize];
                                int    bytesRead = 0;

                                while ((bytesRead = br.Read(data, 0, data.Length)) > 0)
                                {
                                    bw.Write(data, 0, bytesRead);
                                }
                            }
                        }
                    }
                }

                ret = outputFilePath;
            }

            return(ret);
        }