private void setGenhParameters(GenhCreationStruct genhStruct) { this.comboFormat.SelectedValue = genhStruct.Format; this.cbHeaderSkip.Text = genhStruct.HeaderSkip; this.cbInterleave.Text = genhStruct.Interleave; this.cbUseInterleaveOffset.Checked = genhStruct.UseInterleaveOffset; this.cbChannels.Text = genhStruct.Channels; this.cbUseChannelsOffset.Checked = genhStruct.UseChannelsOffset; this.cbFrequency.Text = genhStruct.Frequency; this.cbUseFrequencyOffset.Checked = genhStruct.UseFrequencyOffset; this.tbLoopStart.Text = genhStruct.LoopStart; this.cbLoopStartBytesToSamples.Checked = false; this.tbLoopEnd.Text = genhStruct.LoopEnd; this.cbLoopEndBytesToSamples.Checked = false; this.tbTotalSamples.Text = genhStruct.TotalSamples; this.cbTotalSamplesBytesToSamples.Checked = false; this.tbForceSkipSamplesNumber.Text = genhStruct.SkipSamples; this.cbForceSkipSamples.Checked = genhStruct.SkipSamplesMode == Genh.SKIP_SAMPLES_MODE_FORCE ? true : false; // @ TODO: Add ATRAC, XMA, and RAW DATA this.cbAtrac3StereoMode.SelectedIndex = genhStruct.Atrac3StereoMode; this.cbXmaStreamMode.SelectedIndex = genhStruct.XmaStreamMode; this.tbRawDataSize.Text = genhStruct.RawDataSize; this.tbRightCoef.Text = genhStruct.CoefRightChannel; this.tbLeftCoef.Text = genhStruct.CoefLeftChannel; this.cbCoefficientType.SelectedValue = genhStruct.CoefficientType.ToString(); }
public GenhCreationStruct ToGenhCreationStruct() { GenhCreationStruct genhCreationStruct = new GenhCreationStruct(); genhCreationStruct.Format = this.Format; genhCreationStruct.HeaderSkip = this.HeaderSkip; genhCreationStruct.Interleave = this.Interleave; genhCreationStruct.UseInterleaveOffset = this.UseInterleaveOffset; genhCreationStruct.InterleaveOffsetDescription = this.InterleaveOffsetDescription; genhCreationStruct.Channels = this.Channels; genhCreationStruct.UseChannelsOffset = this.UseChannelsOffset; genhCreationStruct.ChannelsOffsetDescription = this.ChannelsOffsetDescription; genhCreationStruct.Frequency = this.Frequency; genhCreationStruct.UseFrequencyOffset = this.UseFrequencyOffset; genhCreationStruct.FrequencyOffsetDescription = this.FrequencyOffsetDescription; genhCreationStruct.LoopStart = this.LoopStart; genhCreationStruct.UseLoopStartOffset = this.UseLoopStartOffset; genhCreationStruct.LoopStartOffsetDescription = this.LoopStartOffsetDescription; genhCreationStruct.DoLoopStartBytesToSamples = this.DoLoopStartBytesToSamples; genhCreationStruct.LoopEnd = this.LoopEnd; genhCreationStruct.UseLoopEndOffset = this.UseLoopEndOffset; genhCreationStruct.LoopEndOffsetDescription = this.LoopEndOffsetDescription; genhCreationStruct.DoLoopEndBytesToSamples = this.DoLoopEndBytesToSamples; genhCreationStruct.NoLoops = this.NoLoops; genhCreationStruct.UseFileEnd = this.UseFileEnd; genhCreationStruct.FindLoop = this.FindLoop; genhCreationStruct.TotalSamples = this.TotalSamples; genhCreationStruct.UseTotalSamplesOffset = this.UseTotalSamplesOffset; genhCreationStruct.TotalSamplesOffsetDescription = this.TotalSamplesOffsetDescription; genhCreationStruct.DoTotalSamplesBytesToSamples = this.DoTotalSamplesBytesToSamples; genhCreationStruct.SkipSamples = this.SkipSamples; genhCreationStruct.SkipSamplesMode = this.SkipSamplesMode; genhCreationStruct.Atrac3StereoMode = this.Atrac3StereoMode; genhCreationStruct.XmaStreamMode = this.XmaStreamMode; genhCreationStruct.RawDataSize = this.RawDataSize; genhCreationStruct.CoefRightChannel = this.CoefRightChannel; genhCreationStruct.CoefLeftChannel = this.CoefLeftChannel; genhCreationStruct.CoefficientType = this.CoefficientType; genhCreationStruct.OutputHeaderOnly = this.OutputHeaderOnly; genhCreationStruct.SourcePaths = this.SourcePaths; return(genhCreationStruct); }
private void loadGenhFileForEditing() { ListBoxFileInfoObject listBoxFile; if (lbFiles.SelectedIndices.Count == 1) { listBoxFile = (ListBoxFileInfoObject)this.lbFiles.SelectedItem; string editPath = listBoxFile.FilePath; if (GenhUtil.IsGenhFile(editPath)) { using (FileStream fs = File.OpenRead(editPath)) { Genh itemToEdit = new Genh(); itemToEdit.Initialize(fs, editPath); // Set initial values GenhCreationStruct gcStruct = GenhUtil.GetGenhCreationStruct(itemToEdit); this.setGenhParameters(gcStruct); // set loop radio button if ((String.IsNullOrEmpty(gcStruct.LoopStart)) || (gcStruct.LoopStart.Equals(Genh.EMPTY_SAMPLE_COUNT))) { if (this.cbNoLoops.Checked == true) { this.cbNoLoops.Checked = false; // do this to trigger event if already checked. } this.cbNoLoops.Checked = true; // for some formats (MPEG, XMA, FFMPEG) I cannot calculate the exact number of samples, // so copy current loop end to total samples. However, do not overwrite if it exists. if (String.IsNullOrWhiteSpace(this.tbTotalSamples.Text) || ByteConversion.GetLongValueFromString(this.tbTotalSamples.Text) == 0) { this.tbTotalSamples.Text = ByteConversion.GetLongValueFromString(gcStruct.LoopEnd) > 0 ? gcStruct.LoopEnd : "0"; } } else { this.cbManualEntry.Checked = true; } } } } }
protected virtual void DoFinalTasks(Dictionary <uint, FileStream> streamWriters, MpegStream.DemuxOptionsStruct demuxOptions) { GenhCreationStruct gcStruct; string sourceFile; string genhFile; foreach (uint key in streamWriters.Keys) { // create GENH since MIB support is spotty if (demuxOptions.AddHeader) { if (streamWriters[key].Name.EndsWith(this.FileExtensionAudio)) { sourceFile = streamWriters[key].Name; streamWriters[key].Close(); streamWriters[key].Dispose(); gcStruct = new GenhCreationStruct(); gcStruct.Format = "0x00"; gcStruct.HeaderSkip = "0"; gcStruct.Interleave = "0x100"; gcStruct.Channels = "2"; gcStruct.Frequency = "48000"; gcStruct.NoLoops = true; genhFile = GenhUtil.CreateGenhFile(sourceFile, gcStruct); // delete original file if (!String.IsNullOrEmpty(genhFile)) { File.Delete(sourceFile); } } } // close streams if open if (streamWriters[key] != null && streamWriters[key].CanRead) { streamWriters[key].Close(); streamWriters[key].Dispose(); } } }
public void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxStruct) { long fileSize; long currentOffset = 0; long blockStart = 0; long packetSize; long nextPacketSize = -1; long videoPacketSize; long[] audioStreamPacketSizes; Dictionary <string, FileStream> streamOutputWriters = new Dictionary <string, FileStream>(); long audioStreamOffset; long videoStreamOffset; GenhCreationStruct gcStruct; string genhFile; using (FileStream fs = File.Open(this.FilePath, FileMode.Open, FileAccess.Read)) { fileSize = fs.Length; while ((nextPacketSize != 0) && (currentOffset < fileSize)) { blockStart = currentOffset; if (currentOffset == 0) { // get main header this.FileHeader = new XmvVideoDataHeader(); this.FileHeader.MagicBytes = ParseFile.ParseSimpleOffset(fs, 0xC, 4); if (!ParseFile.CompareSegment(this.FileHeader.MagicBytes, 0, XmvMagicBytes)) { throw new FormatException(String.Format("XMV Magic Bytes: 'xobX' not found at offset 0xC{0}", Environment.NewLine)); } this.FileHeader.InitialPacketSize = ParseFile.ParseSimpleOffset(fs, 4, 4); this.FileHeader.VideoWidth = ParseFile.ParseSimpleOffset(fs, 0x14, 4); this.FileHeader.VideoHeight = ParseFile.ParseSimpleOffset(fs, 0x18, 4); // get audio subheaders this.FileHeader.AudioStreamCount = (UInt32)BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, 0x20, 2), 0); this.FileHeader.AudioHeaders = new XmvAudioDataHeader[this.FileHeader.AudioStreamCount]; for (uint i = 0; i < this.FileHeader.AudioStreamCount; i++) { this.FileHeader.AudioHeaders[i] = new XmvAudioDataHeader(); this.FileHeader.AudioHeaders[i].WaveFormat = ParseFile.ParseSimpleOffset(fs, 0x24 + (i * 0xC), 2); this.FileHeader.AudioHeaders[i].ChannelCount = ParseFile.ParseSimpleOffset(fs, 0x24 + (i * 0xC) + 2, 2); this.FileHeader.AudioHeaders[i].SamplesPerSecond = ParseFile.ParseSimpleOffset(fs, 0x24 + (i * 0xC) + 4, 4); this.FileHeader.AudioHeaders[i].BitsPerSample = ParseFile.ParseSimpleOffset(fs, 0x24 + (i * 0xC) + 8, 4); } // set next packet size nextPacketSize = (long)BitConverter.ToUInt32(this.FileHeader.InitialPacketSize, 0); currentOffset = 0x24 + (this.FileHeader.AudioStreamCount * 0xC); } // set packet size of current packet packetSize = nextPacketSize; // get size of next packet nextPacketSize = (long)BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, currentOffset, 4), 0); // get size of video data videoPacketSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, currentOffset + 4, 4), 0); videoPacketSize &= 0x000FFFFF; videoPacketSize -= (this.FileHeader.AudioStreamCount * 4); //------------------ // write video data //------------------ if (demuxStruct.ExtractVideo) { this.FileHeader.OutputPath = Path.Combine(Path.GetDirectoryName(this.FilePath), String.Format("{0}.xmv.raw", Path.GetFileNameWithoutExtension(this.FilePath))); // add output stream to Dictionary if (!streamOutputWriters.ContainsKey(this.FileHeader.OutputPath)) { streamOutputWriters.Add(this.FileHeader.OutputPath, new FileStream(this.FileHeader.OutputPath, FileMode.Create, FileAccess.ReadWrite)); } // write the video packet videoStreamOffset = currentOffset + 0xC + (this.FileHeader.AudioStreamCount * 4); streamOutputWriters[this.FileHeader.OutputPath].Write(ParseFile.ParseSimpleOffset(fs, videoStreamOffset, (int)videoPacketSize), 0, (int)videoPacketSize); } //------------------ // write audio data //------------------ if (demuxStruct.ExtractAudio) { // setup audio for writing audioStreamPacketSizes = new long[this.FileHeader.AudioStreamCount]; audioStreamOffset = currentOffset + 0xC + (this.FileHeader.AudioStreamCount * 4) + videoPacketSize; for (uint i = 0; i < this.FileHeader.AudioStreamCount; i++) { audioStreamPacketSizes[i] = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, currentOffset + 0xC + (i * 4), 4), 0); // write audio streams this.FileHeader.AudioHeaders[i].OutputPath = Path.Combine(Path.GetDirectoryName(this.FilePath), String.Format("{0}_{1}.raw", Path.GetFileNameWithoutExtension(this.FilePath), i.ToString("X2"))); // add output stream to Dictionary if (!streamOutputWriters.ContainsKey(this.FileHeader.AudioHeaders[i].OutputPath)) { streamOutputWriters.Add(this.FileHeader.AudioHeaders[i].OutputPath, new FileStream(this.FileHeader.AudioHeaders[i].OutputPath, FileMode.Create, FileAccess.ReadWrite)); } // write this audio packet streamOutputWriters[this.FileHeader.AudioHeaders[i].OutputPath].Write(ParseFile.ParseSimpleOffset(fs, audioStreamOffset, (int)audioStreamPacketSizes[i]), 0, (int)audioStreamPacketSizes[i]); // increase source offset to next packet audioStreamOffset += audioStreamPacketSizes[i]; } } currentOffset = blockStart + packetSize; } // (currentOffset < fileSize) //------------------- // close all writers //------------------- foreach (string k in streamOutputWriters.Keys) { if (streamOutputWriters[k].CanRead) { streamOutputWriters[k].Close(); streamOutputWriters[k].Dispose(); } } // interleave audio // is this needed at all, ONLY FOR MULTI-STREAM, SINGLE CHANNEL PER STREAM? //------------------ // add audio header //------------------ if (demuxStruct.ExtractAudio && demuxStruct.AddHeader) { for (int i = 0; i < this.FileHeader.AudioStreamCount; i++) { if (BitConverter.ToUInt16(this.FileHeader.AudioHeaders[i].WaveFormat, 0) == 0x69) { gcStruct = new GenhCreationStruct(); gcStruct.Format = "0x01"; gcStruct.HeaderSkip = "0"; gcStruct.Interleave = "0x1"; gcStruct.Channels = BitConverter.ToUInt16(this.FileHeader.AudioHeaders[i].ChannelCount, 0).ToString(); gcStruct.Frequency = BitConverter.ToUInt16(this.FileHeader.AudioHeaders[i].SamplesPerSecond, 0).ToString(); gcStruct.NoLoops = true; genhFile = GenhUtil.CreateGenhFile(this.FileHeader.AudioHeaders[i].OutputPath, gcStruct); // delete original file if (!String.IsNullOrEmpty(genhFile)) { File.Delete(this.FileHeader.AudioHeaders[i].OutputPath); } } } } //------------------ // add video header //------------------ } }
protected override void DoFinalTasks(FileStream sourceFileStream, Dictionary <uint, FileStream> outputFiles, bool addHeader) { byte[] headerBytes; byte[] aa3HeaderBytes; uint headerBlock; string sourceFile; long streamInfoOffset; byte streamIdByte; byte streamIdCheckByte; byte channelCount; GenhCreationStruct gcStruct; string genhFile; foreach (uint streamId in outputFiles.Keys) { if (this.IsThisAnAudioBlock(BitConverter.GetBytes(streamId))) { if (outputFiles[streamId].Name.EndsWith(Atrac3AudioExtension)) { headerBytes = ParseFile.ParseSimpleOffset(outputFiles[streamId], 0, 0x8); // remove all header chunks string cleanedFile = FileUtil.RemoveAllChunksFromFile(outputFiles[streamId], headerBytes); // close stream and rename file sourceFile = outputFiles[streamId].Name; outputFiles[streamId].Close(); outputFiles[streamId].Dispose(); File.Delete(sourceFile); File.Move(cleanedFile, sourceFile); // add header if (addHeader) { Array.Reverse(headerBytes); headerBlock = BitConverter.ToUInt32(headerBytes, 4); string headeredFile = Path.ChangeExtension(sourceFile, Atrac3Plus.FileExtension); aa3HeaderBytes = Atrac3Plus.GetAa3Header(headerBlock); FileUtil.AddHeaderToFile(aa3HeaderBytes, sourceFile, headeredFile); File.Delete(sourceFile); } } else if (addHeader && outputFiles[streamId].Name.EndsWith(LpcmAudioExtension)) { // get this block's stream id streamIdByte = BitConverter.GetBytes(streamId)[0]; // get location of first audio stream info block streamInfoOffset = ParseFile.GetNextOffset(sourceFileStream, 0, PamAudioStreamInfoStartBytes); // find matching info block while ((streamInfoOffset > -1)) { streamIdCheckByte = ParseFile.ParseSimpleOffset(sourceFileStream, streamInfoOffset + 0x4, 1)[0]; if (streamIdCheckByte == streamIdByte) { // get channel count channelCount = ParseFile.ParseSimpleOffset(sourceFileStream, streamInfoOffset + 0x11, 1)[0]; // close stream and build GENH file sourceFile = outputFiles[streamId].Name; outputFiles[streamId].Close(); outputFiles[streamId].Dispose(); gcStruct = new GenhCreationStruct(); gcStruct.Format = "0x03"; gcStruct.HeaderSkip = "0"; gcStruct.Interleave = "0x2"; gcStruct.Channels = channelCount.ToString(); gcStruct.Frequency = "48000"; gcStruct.NoLoops = true; genhFile = GenhUtil.CreateGenhFile(sourceFile, gcStruct); // delete original file if (!String.IsNullOrEmpty(genhFile)) { File.Delete(sourceFile); } break; } streamInfoOffset = ParseFile.GetNextOffset(sourceFileStream, streamInfoOffset + 1, PamAudioStreamInfoStartBytes); } } } } }
protected override void DoFinalTasks(Dictionary <uint, FileStream> streamWriters, MpegStream.DemuxOptionsStruct demuxOptions) { GenhCreationStruct gcStruct; ushort frequency; string sourceFile; string genhFile = null; string rawFile; foreach (uint key in streamWriters.Keys) { if (demuxOptions.AddHeader && (key != MobiclipWiiStream.VideoChunkId) && (this.AudioStreamFeatures[key].StreamType != null) && (this.AudioStreamFeatures[key].StreamType == AudioChunkSignaturePcm)) { if (streamWriters[key].Name.EndsWith(this.FileExtensionAudio)) { sourceFile = streamWriters[key].Name; streamWriters[key].Close(); streamWriters[key].Dispose(); gcStruct = new GenhCreationStruct(); switch (this.AudioStreamFeatures[key].StreamType) { case AudioChunkSignaturePcm: gcStruct.Format = "0x04"; gcStruct.HeaderSkip = "0"; gcStruct.Interleave = "0x2"; gcStruct.Channels = this.AudioStreamFeatures[key].Channels.ToString(); gcStruct.Frequency = this.AudioStreamFeatures[key].Frequency.ToString(); gcStruct.NoLoops = true; genhFile = GenhUtil.CreateGenhFile(sourceFile, gcStruct); break; default: break; } // delete original file if (!String.IsNullOrEmpty(genhFile)) { File.Delete(sourceFile); } } } else if (key != MobiclipWiiStream.VideoChunkId) { // update raw file extension if (this.AudioStreamFeatures[key].StreamType == AudioChunkSignatureA3) { rawFile = streamWriters[key].Name; streamWriters[key].Close(); streamWriters[key].Dispose(); File.Copy(rawFile, Path.ChangeExtension(rawFile, FileExtensionAudioA3)); File.Delete(rawFile); } } } base.DoFinalTasks(streamWriters, demuxOptions); }