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); }
//--------------- // 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); }
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); }