Ejemplo n.º 1
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pXmaConverterStruct,
                                              DoWorkEventArgs e)
        {
            XmaConverterStruct taskStruct = (XmaConverterStruct)pXmaConverterStruct;
            string             workingFolder;
            string             workingFile;
            string             workingSourceFile;

            string consoleOutput = String.Empty;
            string consoleError  = String.Empty;

            uint riffFrequency;
            uint riffChannelCount;
            uint riffFileSize;

            string riffHeaderedFile;

            byte[] riffHeaderBytes;

            uint loopStart;
            uint loopLength;
            uint loopEnd;

            byte[] posBytes;

            //------------------
            // output file name
            //------------------
            this.ShowOutput(pPath, String.Format("[{0}]", Path.GetFileName(pPath)), false);

            //----------------------
            // build working folder
            //----------------------
            workingFolder = this.createWorkingFolder(pPath, taskStruct);

            //------------------------------------
            // copy source file to working folder
            //------------------------------------
            workingSourceFile = Path.Combine(workingFolder, Path.GetFileName(pPath));
            File.Copy(pPath, workingSourceFile, true);

            taskStruct.NumberOfStreams = 1;

            for (int i = 0; i < taskStruct.NumberOfStreams; i++)
            {
                // set working file
                workingFile = workingSourceFile;

                #region XMAPARSE
                //---------------------------
                // xma_parse.exe
                //---------------------------
                if (taskStruct.DoXmaParse)
                {
                    this.ShowOutput(pPath, "---- calling xma_parse.exe", false);

                    // call xma_parse and set output as working_file for next step
                    workingFile = this.callXmaParse(workingFolder, workingFile, taskStruct, out consoleOutput, out consoleError);

                    // show output
                    if (taskStruct.ShowExeOutput && !String.IsNullOrEmpty(consoleOutput))
                    {
                        this.ShowOutput(pPath, consoleOutput, false);
                    }

                    // clear errors if ignore is selected, but only if a file was created
                    if (taskStruct.XmaParseIgnoreErrors && (File.Exists(workingFile)))
                    {
                        consoleError = String.Empty;
                    }
                } //
                #endregion

                #region RIFF HEADER
                if ((taskStruct.DoRiffHeader) && (String.IsNullOrEmpty(consoleError)))
                {
                    //-----------------
                    // get RIFF header
                    //-----------------
                    this.ShowOutput(pPath, "---- adding RIFF header.", false);

                    // frequency
                    if (taskStruct.GetFrequencyFromRiffHeader)
                    {
                        riffFrequency = (uint)RiffUtil.GetFrequencyFromRiffHeader(workingSourceFile);
                    }
                    else if (taskStruct.GetFrequencyFromOffset)
                    {
                        using (FileStream fs = File.OpenRead(workingSourceFile))
                        {
                            riffFrequency = (uint)ParseFile.GetVaryingByteValueAtAbsoluteOffset(fs, taskStruct.RiffHeaderFrequencyOffsetInfo, true);
                        }
                    }
                    else
                    {
                        riffFrequency = (uint)ByteConversion.GetLongValueFromString(taskStruct.RiffFrequency);
                    }

                    // channels
                    if (taskStruct.GetChannelsFromRiffHeader)
                    {
                        riffChannelCount = RiffUtil.GetChannelsFromRiffHeader(workingSourceFile);
                    }
                    else if (taskStruct.GetChannelsFromOffset)
                    {
                        using (FileStream fs = File.OpenRead(workingSourceFile))
                        {
                            riffChannelCount = (uint)ParseFile.GetVaryingByteValueAtAbsoluteOffset(fs, taskStruct.RiffHeaderChannelOffsetInfo, true);

                            if (riffChannelCount > 2)
                            {
                                riffChannelCount = 2;
                            }
                        }
                    }
                    else
                    {
                        riffChannelCount = (uint)ByteConversion.GetLongValueFromString(taskStruct.RiffChannelCount);
                    }

                    riffFileSize = (uint)new FileInfo(workingFile).Length;

                    riffHeaderBytes = this.getRiffHeader(riffFrequency, riffChannelCount, riffFileSize);

                    //-------------------------
                    // add RIFF header to file
                    //-------------------------
                    riffHeaderedFile = Path.ChangeExtension(workingFile, RIFF_COPY_OUTPUT_EXTENSION);
                    FileUtil.AddHeaderToFile(riffHeaderBytes, workingFile, riffHeaderedFile);

                    // set working file for next
                    workingFile = riffHeaderedFile;
                }
                else if (!String.IsNullOrEmpty(consoleError))
                {
                    // dispay xma_parse.exe error
                    this.ShowOutput(pPath, consoleError, true);
                }
                #endregion

                #region POS CREATOR
                //-----------
                // POS Maker
                //-----------
                if ((taskStruct.DoPosMaker) && (String.IsNullOrEmpty(consoleError)))
                {
                    this.ShowOutput(pPath, "---- creating POS file", false);

                    // loop start
                    if (taskStruct.PosLoopStartIsStatic)
                    {
                        loopStart = (uint)ByteConversion.GetLongValueFromString(taskStruct.PosLoopStartStaticValue);
                    }
                    else
                    {
                        using (FileStream fs = File.OpenRead(workingSourceFile))
                        {
                            loopStart = (uint)ParseFile.GetVaryingByteValueAtAbsoluteOffset(fs, taskStruct.PosLoopStartOffsetInfo, true);

                            if (!String.IsNullOrEmpty(taskStruct.PosLoopStartOffsetInfo.CalculationString))
                            {
                                string calculationString =
                                    taskStruct.PosLoopStartOffsetInfo.CalculationString.Replace(CalculatingOffsetDescription.OFFSET_VARIABLE_STRING, loopStart.ToString());

                                loopStart = (uint)ByteConversion.GetLongValueFromString(MathUtil.Evaluate(calculationString));
                            }
                        }
                    }

                    // loop length
                    if (taskStruct.PosLoopEndIsStatic)
                    {
                        loopLength = (uint)ByteConversion.GetLongValueFromString(taskStruct.PosLoopEndStaticValue);
                    }
                    else
                    {
                        using (FileStream fs = File.OpenRead(workingSourceFile))
                        {
                            loopLength = (uint)ParseFile.GetVaryingByteValueAtAbsoluteOffset(fs, taskStruct.PosLoopEndOffsetInfo, true);

                            if (!String.IsNullOrEmpty(taskStruct.PosLoopEndOffsetInfo.CalculationString))
                            {
                                string calculationString =
                                    taskStruct.PosLoopEndOffsetInfo.CalculationString.Replace(CalculatingOffsetDescription.OFFSET_VARIABLE_STRING, loopLength.ToString());

                                loopLength = (uint)ByteConversion.GetLongValueFromString(MathUtil.Evaluate(calculationString));
                            }
                        }
                    }

                    if (loopLength > 0)
                    {
                        loopEnd = loopStart + loopLength;

                        // build .pos array and write to file
                        posBytes = new byte[8];
                        Array.Copy(BitConverter.GetBytes(loopStart), 0, posBytes, 0, 4);
                        Array.Copy(BitConverter.GetBytes(loopEnd), 0, posBytes, 4, 4);

                        using (FileStream fs = File.Open(Path.ChangeExtension(workingSourceFile, ".pos"), FileMode.Create, FileAccess.Write))
                        {
                            fs.Write(posBytes, 0, posBytes.Length);
                        }
                    }
                }
                #endregion

                #region TOWAV
                //-----------
                // ToWav.exe
                //-----------
                if ((taskStruct.DoToWav) && (String.IsNullOrEmpty(consoleError)))
                {
                    this.ShowOutput(pPath, "---- calling ToWav.exe", false);

                    // call ToWav.exe and set working file for next step (if ever needed)
                    workingFile = this.callToWav(workingFolder, workingFile, taskStruct, out consoleOutput, out consoleError);

                    // show output
                    if (taskStruct.ShowExeOutput && !String.IsNullOrEmpty(consoleOutput))
                    {
                        this.ShowOutput(pPath, consoleOutput, false);
                    }

                    // dispay ToWav.exe error
                    if (!String.IsNullOrEmpty(consoleError))
                    {
                        this.ShowOutput(pPath, consoleError, true);
                    }
                }
                #endregion

                #region XMAENCODE
                //---------------
                // XmaEncode.exe
                //---------------
                else if ((taskStruct.DoXmaEncode) && (String.IsNullOrEmpty(consoleError)))
                {
                    this.ShowOutput(pPath, "---- calling xmaencode.exe", false);

                    // call xmaencode.exe and set working file for next step (if ever needed)
                    workingFile = this.callXmaEncode(workingFolder, workingFile, taskStruct, out consoleOutput, out consoleError);

                    // show output
                    if (taskStruct.ShowExeOutput && !String.IsNullOrEmpty(consoleOutput))
                    {
                        this.ShowOutput(pPath, consoleOutput, false);
                    }

                    // dispay xmaencode.exe error
                    if (!String.IsNullOrEmpty(consoleError))
                    {
                        this.ShowOutput(pPath, consoleError, true);
                    }
                }
                #endregion
            } // for (int i = 0; i < taskStruct.NumberOfStreams; i++)


            //----------------------
            // clean working folder
            //----------------------
            this.cleanWorkingFolder(pPath, workingSourceFile, taskStruct);
        }
Ejemplo n.º 2
0
        //---------------
        // External Apps
        //---------------
        private string callXmaParse(
            string workingFolder,
            string workingFile,
            XmaConverterStruct taskStruct,
            out string consoleOutput,
            out string consoleError)
        {
            string        xmaParseWorkingPath;
            string        xmaParseOutputFilePath;
            Process       xmaParseProcess;
            StringBuilder parameters = new StringBuilder();

            // copy to working folder
            xmaParseWorkingPath = Path.Combine(workingFolder, Path.GetFileName(XMAPARSE_FULL_PATH));
            File.Copy(XMAPARSE_FULL_PATH, xmaParseWorkingPath, true);

            // build parameters
            parameters.AppendFormat(" \"{0}\"", Path.GetFileName(workingFile)); // Filename
            parameters.AppendFormat(" -{0}", taskStruct.XmaParseXmaType);       // Input File Type

            using (FileStream workingFileStream = File.OpenRead(workingFile))
            {
                // offset
                if (taskStruct.StartOffsetAfterRiffHeader)
                {
                    uint riffHeaderSize = RiffUtil.GetRiffHeaderSize(workingFile);
                    parameters.AppendFormat(" -o {0}", riffHeaderSize.ToString("X"));
                }
                else if ((taskStruct.XmaParseStartOffsetIsStatic) && (!String.IsNullOrEmpty(taskStruct.XmaParseStartOffset)))
                {
                    // allow decimal or hex input, convert to hex for xma_parse.exe
                    parameters.AppendFormat(" -o {0}", ByteConversion.GetLongValueFromString(taskStruct.XmaParseStartOffset).ToString("X"));
                }
                else if (!String.IsNullOrEmpty(taskStruct.XmaParseStartOffsetOffsetInfo.OffsetValue))
                {
                    long offsetValue = ParseFile.GetVaryingByteValueAtAbsoluteOffset(workingFileStream, taskStruct.XmaParseStartOffsetOffsetInfo, true);
                    parameters.AppendFormat(" -o {0}", offsetValue.ToString("X"));
                }

                // block size
                if ((taskStruct.XmaParseBlockSizeIsStatic) && (!String.IsNullOrEmpty(taskStruct.XmaParseBlockSize)))
                {
                    // allow decimal or hex input, convert to hex for xma_parse.exe
                    parameters.AppendFormat(" -b {0}", ByteConversion.GetLongValueFromString(taskStruct.XmaParseBlockSize).ToString("X"));
                }
                else if (!String.IsNullOrEmpty(taskStruct.XmaParseBlockSizeOffsetInfo.OffsetValue))
                {
                    long blockSizeValue = ParseFile.GetVaryingByteValueAtAbsoluteOffset(workingFileStream, taskStruct.XmaParseBlockSizeOffsetInfo, true);
                    parameters.AppendFormat(" -b {0}", blockSizeValue.ToString("X"));
                }

                // data size
                if (taskStruct.GetDataSizeFromRiffHeader)
                {
                    uint riffDataSize = RiffUtil.GetDataSizeFromRiffHeader(workingFile);
                    parameters.AppendFormat(" -d {0}", riffDataSize.ToString("X"));
                }
                else if ((taskStruct.XmaParseDataSizeIsStatic) && (!String.IsNullOrEmpty(taskStruct.XmaParseDataSize)))
                {
                    // allow decimal or hex input, convert to hex for xma_parse.exe
                    parameters.AppendFormat(" -d {0}", ByteConversion.GetLongValueFromString(taskStruct.XmaParseDataSize).ToString("X"));
                }
                else if (!String.IsNullOrEmpty(taskStruct.XmaParseDataSizeOffsetInfo.OffsetValue))
                {
                    long dataSizeValue = ParseFile.GetVaryingByteValueAtAbsoluteOffset(workingFileStream, taskStruct.XmaParseDataSizeOffsetInfo, true);
                    parameters.AppendFormat(" -d {0}", dataSizeValue.ToString("X"));
                }
            }

            // output name
            xmaParseOutputFilePath = String.Format("{0}{1}", Path.GetFileNameWithoutExtension(workingFile), XMAPARSE_OUTPUT_EXTENSION);

            if (taskStruct.XmaParseDoRebuildMode)
            {
                parameters.AppendFormat(" -r \"{0}\"", xmaParseOutputFilePath);
            }
            else
            {
                parameters.AppendFormat(" -x \"{0}\"", xmaParseOutputFilePath);
            }

            // call function
            xmaParseProcess           = new Process();
            xmaParseProcess.StartInfo = new ProcessStartInfo(xmaParseWorkingPath);
            xmaParseProcess.StartInfo.WorkingDirectory = workingFolder;
            xmaParseProcess.StartInfo.Arguments        = parameters.ToString();
            xmaParseProcess.StartInfo.UseShellExecute  = false;
            xmaParseProcess.StartInfo.CreateNoWindow   = true;

            xmaParseProcess.StartInfo.RedirectStandardError  = true;
            xmaParseProcess.StartInfo.RedirectStandardOutput = true;

            bool isSuccess = xmaParseProcess.Start();

            consoleOutput = xmaParseProcess.StandardOutput.ReadToEnd();
            consoleError  = xmaParseProcess.StandardError.ReadToEnd();

            xmaParseProcess.WaitForExit();
            xmaParseProcess.Close();
            xmaParseProcess.Dispose();

            xmaParseOutputFilePath = xmaParseWorkingPath = Path.Combine(workingFolder, xmaParseOutputFilePath);

            return(xmaParseOutputFilePath);
        }
Ejemplo n.º 3
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);
        }