public static float[] ReadFloats(string filePath, string headerExpected) { BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian); string header = binFile.ReadString(4); if (header == headerExpected) // "FPQr", "FQ2p" or "FQ3p" { int version = binFile.ReadInt32(); int parameterCount = binFile.ReadInt32(); var floatArray = new float[parameterCount]; int i = 0; try { for (i = 0; i < parameterCount; i++) { floatArray[i] = binFile.ReadSingle(); } } catch (System.Exception e) { Log.Error("Failed reading floats: {0}", e); } binFile.Close(); return(floatArray); } else { binFile.Close(); return(null); } }
/** * Reads the header and channel data from given .wav file. * * Data are read into a temporary buffer and then converted to * channel sample vectors. If source is a mono recording, samples * are written to left channel. * * To improve performance, no format checking is performed. * * @param file full path to .wav file */ public void Load(string file) { filename = file; LChTab.Clear(); RChTab.Clear(); if (frameLength != 0) { ClearFrames(); } // first we read header from the stream // then as we know now the data size, we create a temporary // buffer and read raw data into that buffer BinaryFile fs = new BinaryFile(filename); LoadHeader(ref fs); short[] data = new short[hdr.WaveSize / 2]; LoadRawData(ref fs, data, hdr.WaveSize / 2); fs.Close(); // initialize data channels (using right channel only in stereo mode) uint channelSize = hdr.WaveSize / hdr.BytesPerSamp; //LChTab.resize(channelSize); //if (2 == hdr.Channels) //RChTab.resize(channelSize); // most important conversion happens right here if (16 == hdr.BitsPerSamp) { if (2 == hdr.Channels) { Convert16Stereo(data, channelSize); } else { Convert16Mono(data, channelSize); } } else { if (2 == hdr.Channels) { Convert8Stereo(data, channelSize); } else { Convert8Mono(data, channelSize); } } // clear the buffer data = null; // when we have the data, it is possible to create frames if (frameLength != 0) { DivideFrames(LChTab); } }
public static void WriteWaveFile(BinaryFile wavfile, double[][] sound, int channels, int samplecount, int samplerate, int format_param) { int i = 0; int[] tag = { 1179011410, 0, 1163280727, 544501094, 16, 1, 1, 0, 0, 0, 0, 1635017060, 0, 0 }; #if DEBUG Console.Write("WriteWaveFile...\n"); #endif //********WAV tags generation******** tag[12] = samplecount * (format_param / 8) * channels; tag[1] = tag[12] + 36; tag[7] = samplerate; tag[8] = samplerate * format_param / 8; tag[9] = format_param / 8; tag[6] = channels; tag[10] = format_param; if ((format_param == 8) || (format_param == 16)) { tag[5] = 1; } if (format_param == 32) { tag[5] = 3; } //--------WAV tags generation-------- // tag writing for (i = 0; i < 13; i++) { if ((i == 5) || (i == 6) || (i == 9) || (i == 10)) { GlobalMembersUtil.WriteUInt16((ushort)tag[i], wavfile); } else { GlobalMembersUtil.WriteUInt32((uint)tag[i], wavfile); } } if (format_param == 8) { Write8Bit(wavfile, sound, samplecount, channels); } if (format_param == 16) { Write16Bit(wavfile, sound, samplecount, channels); } if (format_param == 32) { Write32BitFloat(wavfile, sound, samplecount, channels); } wavfile.Close(); }
public static void WriteWaveFile(string path, byte[] soundData, bool isFloatingPoint, int channelCount, int sampleRate, int bitDepth) { var bf = new BinaryFile(path, BinaryFile.ByteOrder.LittleEndian, true); int totalSampleCount = soundData.Length; // RIFF header. // Chunk ID. bf.Write(Encoding.ASCII.GetBytes("RIFF")); // Chunk size. bf.Write(BitConverter.GetBytes(totalSampleCount + 36)); // Format. bf.Write(Encoding.ASCII.GetBytes("WAVE")); // Sub-chunk 1. // Sub-chunk 1 ID. bf.Write(Encoding.ASCII.GetBytes("fmt ")); // Sub-chunk 1 size. bf.Write(BitConverter.GetBytes(16)); // Audio format (floating point (3) or PCM (1)). Any other format indicates compression. bf.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1))); // Channels. bf.Write(BitConverter.GetBytes((ushort)channelCount)); // Sample rate. bf.Write(BitConverter.GetBytes(sampleRate)); // Average bytes per second bf.Write(BitConverter.GetBytes(sampleRate * channelCount * (bitDepth / 8))); // Block align. bf.Write(BitConverter.GetBytes((ushort)(channelCount * (bitDepth / 8)))); // Bits per sample. bf.Write(BitConverter.GetBytes((ushort)bitDepth)); // Sub-chunk 2. // Sub-chunk 2 ID. bf.Write(Encoding.ASCII.GetBytes("data")); // Sub-chunk 2 size. bf.Write(BitConverter.GetBytes(totalSampleCount)); bf.Write(soundData); bf.Close(); }
public static float ReadWaveDurationInSeconds(BinaryFile waveFile) { int channels = -1; int sampleCount = -1; int sampleRate = -1; float lengthInSeconds = -1; int audioFormat = -1; int bitsPerSample = -1; int bytesPerSec = -1; ReadWaveFileHeader(waveFile, ref channels, ref sampleCount, ref sampleRate, ref lengthInSeconds, ref audioFormat, ref bitsPerSample, ref bytesPerSec); waveFile.Close(); return(lengthInSeconds); }
/* Function: Save * Saves the current state into <Files.nd>. Throws an exception if unsuccessful. All <Files> in the structure should have * their last modification time set to tick count zero before calling this function. */ public void Save(Path filename, IDObjects.Manager <File> files) { BinaryFile binaryFile = new BinaryFile(); binaryFile.OpenForWriting(filename); try { foreach (File file in files) { // [Int32: ID] // [String: Path] // [Byte: Type] // [Int64: Last Modification in Ticks or 0] // (if image) // [UInt32: Width in Pixels or 0 if unknown] // [UInt32: Height in Pixels or 0 if unknown] binaryFile.WriteInt32(file.ID); binaryFile.WriteString(file.FileName); binaryFile.WriteByte((byte)file.Type); binaryFile.WriteInt64(file.LastModified.Ticks); if (file.Type == FileType.Image) { ImageFile imageFile = (ImageFile)file; if (imageFile.DimensionsKnown) { binaryFile.WriteUInt32(imageFile.Width); binaryFile.WriteUInt32(imageFile.Height); } else { binaryFile.WriteUInt32(0); binaryFile.WriteUInt32(0); } } } // [Int32: 0] binaryFile.WriteInt32(0); } finally { binaryFile.Close(); } }
public static float[][] ReadWaveFile(BinaryFile waveFile, ref int channels, ref int sampleCount, ref int sampleRate, ref float lengthInSeconds) { int audioFormat = -1; int bitsPerSample = 1; int bytesPerSec = -1; ReadWaveFileHeader(waveFile, ref channels, ref sampleCount, ref sampleRate, ref lengthInSeconds, ref audioFormat, ref bitsPerSample, ref bytesPerSec); float[][] sound = new float[channels][]; for (int ic = 0; ic < channels; ic++) { sound[ic] = new float[sampleCount]; } #region Data loading if (bitsPerSample == 8) { Read8Bit(waveFile, sound, sampleCount, channels); } else if (bitsPerSample == 16) { Read16Bit(waveFile, sound, sampleCount, channels); } else if (bitsPerSample == 24) { Read24Bit(waveFile, sound, sampleCount, channels); } else if (bitsPerSample == 32) { if (audioFormat == WAVE_FORMAT_PCM) { Read32Bit(waveFile, sound, sampleCount, channels); } else if (audioFormat == WAVE_FORMAT_IEEE_FLOAT) { Read32BitFloat(waveFile, sound, sampleCount, channels); } } #endregion Data loading waveFile.Close(); return(sound); }
public bool ReadFFP(string filePath) { BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian); try { string header = binFile.ReadString(4); if (header != "FQ3p") { return(false); } return(ReadFFP(binFile)); } finally { binFile.Close(); } }
/// <summary> /// Initialize the class specific variables using parameters /// </summary> public void InitFromParameters() { if (HasFXP) { var fxp = FXP; var byteArray = new byte[0]; if (fxp.Content is FXP.FxProgramSet) { byteArray = ((FXP.FxProgramSet)fxp.Content).ChunkData; } else if (fxp.Content is FXP.FxChunkSet) { byteArray = ((FXP.FxChunkSet)fxp.Content).ChunkData; } var binFile = new BinaryFile(byteArray, BinaryFile.ByteOrder.LittleEndian, Encoding.ASCII); try { string header = binFile.ReadString(4); if (header != "FFBS") { return; } ReadFFP(binFile); } finally { binFile.Close(); } } else { // init preset parameters // Note that the floats are not stored as IEEE (meaning between 0.0 - 1.0) but as floats representing the real values var fabFilterProQ3Floats = Parameters .Where(v => v.Value.Type == Parameter.ParameterType.Number) .Select(v => (float)v.Value.Number.Value).ToArray(); InitFromParameters(fabFilterProQ3Floats, false); } }
public static void Main(string[] args) { string inLeft = @"F:\SAMPLES\IMPULSE RESPONSES\PER IVAR IR SAMPLES\ALTIVERB-QUAD-IMPULSE-RESPONSES\Scoring Stages (Orchestral Studios)_Todd-AO - California US_st to st wide mics at 18m90_L.wav"; string inRight = @"F:\SAMPLES\IMPULSE RESPONSES\PER IVAR IR SAMPLES\ALTIVERB-QUAD-IMPULSE-RESPONSES\Scoring Stages (Orchestral Studios)_Todd-AO - California US_st to st wide mics at 18m90_R.wav"; float[] channel1; float[] channel2; float[] channel3; float[] channel4; AudioUtilsNAudio.SplitStereoWaveFileToMono(inLeft, out channel1, out channel2); AudioUtilsNAudio.SplitStereoWaveFileToMono(inRight, out channel3, out channel4); // find out what channel is longest int maxLength = Math.Max(channel1.Length, channel3.Length); string outputFile = @"Scoring Stages (Orchestral Studios)_Todd-AO - California US_st to st wide mics at 18m90V2.sir"; //string cfh_data = @"abe6f4214362.34U4T9yaBCCDEuyH0uCm7T6Pf.z+PqR.kBAoHEfz3DlPB4lX.K4XirMP+3WCzJZ6RYE0ka38ty94e5j858dEG1RUZlT3iZV2EATQgrjIV5ixyF5zA0qasZdXlJpZ8FtlNjwomlnU8lHn+JhPP48khE9n1HPSpVyoJhg5itqiqqKp600.vKJEevIQJ4fXS0aTksgilV6fMkL4wNFPLDn33w5irgZ7lpiNZaJe791OXu1ATcghs1bHHwzElL49JBlnXKYBBeeT8QCedFNXTRbHdVznj7XbHjFhSlLFaURBSgnoA1RJ7UWAwYQSCSew407fANeNiyoYvERkkO.1PVR0vMSTEqnZihvsR6eC5ammIKKcBl.NPeBmsPpDLBjimqMfQB15NVIEpXEZfXflcpdxcd77xh56HaQM9Shz7rIRJa4p+EHo0YfjCv3BeKI87QR6yGIW1qI+hIdM99OMVIuF+7+KqzUe.bo2V9C"; string cfh_data = @"abe6f42143 "; BinaryFile binaryFile = new BinaryFile(outputFile, BinaryFile.ByteOrder.LittleEndian, true); binaryFile.Write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); binaryFile.Write("\n\n"); binaryFile.Write("<SirImpulseFile version=\"2.1\" cfh_data=\""); binaryFile.Write(cfh_data); binaryFile.Write("\"/>"); binaryFile.Write("\r\n"); binaryFile.Write((byte)0); WriteAudioBlock(binaryFile, channel1, maxLength, "0"); WriteAudioBlock(binaryFile, channel2, maxLength, "1"); WriteAudioBlock(binaryFile, channel3, maxLength, "2"); WriteAudioBlock(binaryFile, channel4, maxLength, "3"); binaryFile.Close(); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); }
/// <summary> /// Extract NI Massive's tables.dat file into a specified output directory /// </summary> /// <param name="tablesDatFilePath">path to tables.dat</param> /// <param name="outputDirPath">path to output directory</param> /// <returns></returns> public static bool Extract(string tablesDatFilePath, string outputDirPath) { if (File.Exists(tablesDatFilePath)) { string fileName = Path.GetFileNameWithoutExtension(tablesDatFilePath); // read in the map to save as NI Massive's GUI filenames var map = MassiveMapping.ReadMassiveMapping("massive_map.csv"); var bFile = new BinaryFile(tablesDatFilePath, BinaryFile.ByteOrder.LittleEndian); Entry nimd = parse_nimd_file(bFile); extract_nimd_entry(bFile, nimd, outputDirPath, outputDirPath, map); bFile.Close(); return(true); } else { return(false); } }
public bool ReadFFP(string filePath) { BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian); string header = binFile.ReadString(4); if (header != "FQ2p") { return(false); } Version = binFile.ReadInt32(); ParameterCount = binFile.ReadInt32(); Bands = new List <ProQ2Band>(); for (int i = 0; i < 24; i++) { var band = new ProQ2Band(); // 1 = Enabled, 2 = Disabled band.Enabled = binFile.ReadSingle() == 1 ? true : false; band.Frequency = FreqConvertBack(binFile.ReadSingle()); band.Gain = binFile.ReadSingle(); // actual gain in dB band.Q = QConvertBack(binFile.ReadSingle()); // 0 - 7 var filterType = binFile.ReadSingle(); switch (filterType) { case (float)ProQ2Shape.Bell: band.Shape = ProQ2Shape.Bell; break; case (float)ProQ2Shape.LowShelf: band.Shape = ProQ2Shape.LowShelf; break; case (float)ProQ2Shape.LowCut: band.Shape = ProQ2Shape.LowCut; break; case (float)ProQ2Shape.HighShelf: band.Shape = ProQ2Shape.HighShelf; break; case (float)ProQ2Shape.HighCut: band.Shape = ProQ2Shape.HighCut; break; case (float)ProQ2Shape.Notch: band.Shape = ProQ2Shape.Notch; break; case (float)ProQ2Shape.BandPass: band.Shape = ProQ2Shape.BandPass; break; case (float)ProQ2Shape.TiltShelf: band.Shape = ProQ2Shape.TiltShelf; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter type is outside range: {0}", filterType)); } // 0 - 8 var filterSlope = binFile.ReadSingle(); switch (filterSlope) { case (float)ProQSlope.Slope6dB_oct: band.Slope = ProQSlope.Slope6dB_oct; break; case (float)ProQSlope.Slope12dB_oct: band.Slope = ProQSlope.Slope12dB_oct; break; case (float)ProQSlope.Slope18dB_oct: band.Slope = ProQSlope.Slope18dB_oct; break; case (float)ProQSlope.Slope24dB_oct: band.Slope = ProQSlope.Slope24dB_oct; break; case (float)ProQSlope.Slope30dB_oct: band.Slope = ProQSlope.Slope30dB_oct; break; case (float)ProQSlope.Slope36dB_oct: band.Slope = ProQSlope.Slope36dB_oct; break; case (float)ProQSlope.Slope48dB_oct: band.Slope = ProQSlope.Slope48dB_oct; break; case (float)ProQSlope.Slope72dB_oct: band.Slope = ProQSlope.Slope72dB_oct; break; case (float)ProQSlope.Slope96dB_oct: band.Slope = ProQSlope.Slope96dB_oct; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter slope is outside range: {0}", filterSlope)); } // 0 = Left, 1 = Right, 2 = Stereo var filterStereoPlacement = binFile.ReadSingle(); switch (filterStereoPlacement) { case (float)ProQ2StereoPlacement.LeftOrMid: band.StereoPlacement = ProQ2StereoPlacement.LeftOrMid; break; case (float)ProQ2StereoPlacement.RightOrSide: band.StereoPlacement = ProQ2StereoPlacement.RightOrSide; break; case (float)ProQ2StereoPlacement.Stereo: band.StereoPlacement = ProQ2StereoPlacement.Stereo; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter stereo placement is outside range: {0}", filterStereoPlacement)); } Bands.Add(band); } // read the remaining floats // int remainingParameterCount = ParameterCount - 7 * Bands.Count; try { ProcessingMode = binFile.ReadSingle(); // Zero Latency: 0.0, Natural Phase: 1.0, Linear Phase: 2.0 ProcessingResolution = binFile.ReadSingle(); // 0 - 4, Medium ChannelMode = binFile.ReadSingle(); // 0 = Left/Right, 1 = Mid/Side GainScale = binFile.ReadSingle(); // 100% OutputLevel = binFile.ReadSingle(); // 0.0 dB, -1 to 1 (- Infinity to +36 dB , 0 = 0 dB) OutputPan = binFile.ReadSingle(); // Left 0 dB, Right: 0 dB, -1 to 1 (0 = middle) ByPass = binFile.ReadSingle(); // Not Bypassed OutputInvertPhase = binFile.ReadSingle(); // Normal AutoGain = binFile.ReadSingle(); // Off AnalyzerShowPreProcessing = binFile.ReadSingle(); // Disabled - 0: Off, 1: On AnalyzerShowPostProcessing = binFile.ReadSingle(); // Disabled - 0: Off, 1: On AnalyzerShowSidechain = binFile.ReadSingle(); // Disabled - 0: Off, 1: On AnalyzerRange = binFile.ReadSingle(); // Analyzer Range in dB. 0.0: 60dB, 1.0: 90dB, 2.0: 120dB AnalyzerResolution = binFile.ReadSingle(); // Analyzer Resolution. 0.0: Low, 1.0: Medium, 2.0: High, 3.00: Maximum AnalyzerSpeed = binFile.ReadSingle(); // Analyzer Speed. 0.0: Very Slow, 1.0: Slow, 2.0: Medium, 3.0 Fast, 4.0: Very Fast AnalyzerTilt = binFile.ReadSingle(); // Analyzer Tilt in dB/oct. 0.0: 0.0, 1.0: 1.5, 2.0: 3.0, 3.0: 4.5, 4.0: 6.0 AnalyzerFreeze = binFile.ReadSingle(); // 0: Off, 1: On SpectrumGrab = binFile.ReadSingle(); // Enabled DisplayRange = binFile.ReadSingle(); // 12dB ReceiveMidi = binFile.ReadSingle(); // Enabled SoloBand = binFile.ReadSingle(); // -1 SoloGain = binFile.ReadSingle(); // 0.00 } catch { } // check if mid/side if (ChannelMode == 1) { Bands.ForEach(b => b.ChannelMode = ProQ2ChannelMode.MidSide); } binFile.Close(); return(true); }
/* Function: Load * Loads the information in <Comments.nd> into a <Config> object, returning whether it was successful. If it was not * config will be null. */ public bool Load(Path filename, out Config config) { BinaryFile file = new BinaryFile(); try { if (file.OpenForReading(filename, "2.2") == false) { config = null; return(false); } else { config = new Config(); // [String: Tag Name] // [Int32: ID] // ... // [String: null] string tagName = file.ReadString(); while (tagName != null) { Tag tag = new Tag(tagName); tag.ID = file.ReadInt32(); config.AddTag(tag); tagName = file.ReadString(); } // [String: Comment Type Name] // [Int32: ID] // [String: Display Name] // [String: Plural Display Name] // [String: Simple Identifier] // [Byte: Scope] // [Byte: Flags] // ... // [String: null] string commentTypeName = file.ReadString(); while (commentTypeName != null) { CommentType commentType = new CommentType(commentTypeName); commentType.ID = file.ReadInt32(); commentType.DisplayName = file.ReadString(); commentType.PluralDisplayName = file.ReadString(); commentType.SimpleIdentifier = file.ReadString(); // We don't have to validate the scope and flag values because they're only used to compare to the text file // versions, which are validated. If these are invalid they'll just show up as changed. commentType.Scope = (CommentType.ScopeValue)file.ReadByte(); commentType.Flags = (CommentType.FlagValue)file.ReadByte(); config.AddCommentType(commentType); commentTypeName = file.ReadString(); } // [String: Keyword] // [Byte: Plural (0 or 1)] // [Int32: Comment Type ID] // [Int32: Language ID or 0 if agnostic] // ... // [String: null] string keywordName = file.ReadString(); while (keywordName != null) { var keywordDefinition = new KeywordDefinition(keywordName); keywordDefinition.Plural = (file.ReadByte() != 0); keywordDefinition.CommentTypeID = file.ReadInt32(); int languageID = file.ReadInt32(); if (languageID != 0) { keywordDefinition.LanguageID = languageID; } config.AddKeywordDefinition(keywordDefinition); keywordName = file.ReadString(); } } } catch { config = null; return(false); } finally { file.Close(); } return(true); }
/* Function: Save * Saves the passed <Config> into <Comments.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, Config config) { BinaryFile file = new BinaryFile(); file.OpenForWriting(filename); try { // [String: Tag Name] // [Int32: ID] // ... // [String: null] foreach (var tag in config.Tags) { file.WriteString(tag.Name); file.WriteInt32(tag.ID); } file.WriteString(null); // [String: Comment Type Name] // [Int32: ID] // [String: Display Name] // [String: Plural Display Name] // [String: Simple Identifier] // [Byte: Scope] // [Byte: Flags] // ... // [String: null] foreach (var commentType in config.CommentTypes) { file.WriteString(commentType.Name); file.WriteInt32(commentType.ID); file.WriteString(commentType.DisplayName); file.WriteString(commentType.PluralDisplayName); file.WriteString(commentType.SimpleIdentifier); file.WriteByte((byte)commentType.Scope); file.WriteByte((byte)commentType.Flags); } file.WriteString(null); // [String: Keyword] // [Byte: Plural (0 or 1)] // [Int32: Comment Type ID] // [Int32: Language ID or 0 if agnostic] // ... // [String: null] foreach (var keywordDefinition in config.KeywordDefinitions) { file.WriteString(keywordDefinition.Keyword); file.WriteByte((byte)(keywordDefinition.Plural ? 1 : 0)); file.WriteInt32(keywordDefinition.CommentTypeID); file.WriteInt32((keywordDefinition.IsLanguageSpecific ? keywordDefinition.LanguageID : 0)); } file.WriteString(null); } finally { file.Close(); } }
public static double[][] ReadWaveFile(BinaryFile wavfile, ref int channels, ref int samplecount, ref int samplerate) { double[][] sound; int i = 0; int ic = 0; var tag = new int[13]; // integers int RIFF = BinaryFile.StringToInt32("RIFF"); // 1179011410 int WAVE = BinaryFile.StringToInt32("WAVE"); // 1163280727 int FMT = BinaryFile.StringToInt32("fmt "); // 544501094 int DATA = BinaryFile.StringToInt32("data"); // 1635017060 // Size Description Value // tag[0] 4 RIFF Header RIFF (1179011410) // tag[1] 4 RIFF data size // tag[2] 4 form-type (WAVE etc) (1163280727) // tag[3] 4 Chunk ID "fmt " (0x666D7420) = 544501094 // tag[4] 4 Chunk Data Size 16 + extra format bytes // long chunkSize; // tag[5] 2 Compression code 1 - 65,535 // short wFormatTag; // tag[6] 2 Number of channels 1 - 65,535 // tag[7] 4 Sample rate 1 - 0xFFFFFFFF // tag[8] 4 Average bytes per second 1 - 0xFFFFFFFF // tag[9] 2 Block align 1 - 65,535 (4) // tag[10] 2 Significant bits per sample 2 - 65,535 (32) // tag[11] 4 IEEE = 1952670054 (0x74636166) = fact chunk // PCM = 1635017060 (0x61746164) (datachunk = 1635017060) // tag[12] 4 IEEE = 4 , PCM = 5292000 (0x0050BFE0) #if DEBUG Console.Write("ReadWaveFile...\n"); #endif // tag reading for (i = 0; i < 13; i++) { tag[i] = 0; if ((i == 5) || (i == 6) || (i == 9) || (i == 10)) { tag[i] = Util.ReadUInt16(wavfile); } else { tag[i] = (int)Util.ReadUInt32(wavfile); } } #region File format checking if (tag[0] != RIFF || tag[2] != WAVE) { Console.Error.WriteLine("This file is not in WAVE format\n"); Util.ReadUserReturn(); Environment.Exit(1); } // fmt tag, chunkSize and data tag if (tag[3] != FMT || tag[4] != 16 || tag[11] != DATA) { Console.Error.WriteLine("This WAVE file format is not currently supported\n"); Util.ReadUserReturn(); Environment.Exit(1); } // bits per sample if (tag[10] == 24) { Console.Error.WriteLine("24 bit PCM WAVE files are not currently supported\n"); Util.ReadUserReturn(); Environment.Exit(1); } // wFormatTag if (tag[5] != WAVE_FORMAT_PCM && tag[5] != WAVE_FORMAT_IEEE_FLOAT) { Console.Error.WriteLine("Non PCM WAVE files are not currently supported\n"); Util.ReadUserReturn(); Environment.Exit(1); } #endregion File format checking channels = tag[6]; samplecount = tag[12] / (tag[10] / 8) / channels; samplerate = tag[7]; sound = new double[channels][]; for (ic = 0; ic < channels; ic++) { sound[ic] = new double[samplecount]; } #region Data loading if (tag[10] == 8) { Read8Bit(wavfile, sound, samplecount, channels); } if (tag[10] == 16) { Read16Bit(wavfile, sound, samplecount, channels); } if (tag[10] == 32) { if (tag[5] == WAVE_FORMAT_PCM) { Read32Bit(wavfile, sound, samplecount, channels); } else if (tag[5] == WAVE_FORMAT_IEEE_FLOAT) { Read32BitFloat(wavfile, sound, samplecount, channels); } } #endregion Data loading wavfile.Close(); return(sound); }
/* Function: Load * Loads the information in <Comments.nd>, which is the computed comment settings from the last time Natural Docs was run. * Returns whether it was successful. If not all the out parameters will still return objects, they will just be empty. */ public bool Load(Path filename, out List <CommentType> binaryCommentTypes, out List <Tag> binaryTags, out List <KeyValuePair <string, int> > binarySingularKeywords, out List <KeyValuePair <string, int> > binaryPluralKeywords, out List <string> binaryIgnoredKeywords) { binaryCommentTypes = new List <CommentType>(); binaryTags = new List <Tag>(); binarySingularKeywords = new List <KeyValuePair <string, int> >(); binaryPluralKeywords = new List <KeyValuePair <string, int> >(); binaryIgnoredKeywords = new List <string>(); BinaryFile file = new BinaryFile(); bool result = true; try { if (file.OpenForReading(filename, "2.0") == false) { result = false; } else { // [String: Tag Name] // [Int32: ID] // ... // [String: null] string tagName = file.ReadString(); while (tagName != null) { Tag tag = new Tag(tagName); tag.ID = file.ReadInt32(); binaryTags.Add(tag); tagName = file.ReadString(); } // [String: Comment Type Name] // [Int32: ID] // [String: Display Name] // [String: Plural Display Name] // [String: Simple Identifier] // [Byte: Index] // [Int32: Index With ID]? // [Byte: Scope] // [Byte: Break Lists] // [UInt16: Flags] // ... // [String: null] string commentTypeName = file.ReadString(); IDObjects.NumberSet commentTypeIDs = new IDObjects.NumberSet(); while (commentTypeName != null) { CommentType commentType = new CommentType(commentTypeName); commentType.ID = file.ReadInt32(); commentType.DisplayName = file.ReadString(); commentType.PluralDisplayName = file.ReadString(); commentType.SimpleIdentifier = file.ReadString(); // We don't have to validate the enum and flag values because they're only used to compare to the config file // versions, which are validated. If these are invalid they'll just show up as changed. commentType.Index = (CommentType.IndexValue)file.ReadByte(); if (commentType.Index == CommentType.IndexValue.IndexWith) { commentType.IndexWith = file.ReadInt32(); } commentType.Scope = (CommentType.ScopeValue)file.ReadByte(); commentType.BreakLists = (file.ReadByte() != 0); commentType.Flags.AllConfigurationProperties = (CommentTypeFlags.FlagValues)file.ReadUInt16(); binaryCommentTypes.Add(commentType); commentTypeIDs.Add(commentType.ID); commentTypeName = file.ReadString(); } // Check the Index With values after they're all entered in. foreach (CommentType commentType in binaryCommentTypes) { if (commentType.Index == CommentType.IndexValue.IndexWith && !commentTypeIDs.Contains(commentType.IndexWith)) { result = false; } } // [String: Singular Keyword] // [Int32: Comment Type ID] // ... // [String: null] string keyword = file.ReadString(); while (keyword != null) { int id = file.ReadInt32(); binarySingularKeywords.Add(new KeyValuePair <string, int>(keyword, id)); if (!commentTypeIDs.Contains(id)) { result = false; } keyword = file.ReadString(); } // [String: Plural Keyword] // [Int32: Comment Type ID] // ... // [String: null] keyword = file.ReadString(); while (keyword != null) { int id = file.ReadInt32(); binaryPluralKeywords.Add(new KeyValuePair <string, int>(keyword, id)); if (!commentTypeIDs.Contains(id)) { result = false; } keyword = file.ReadString(); } // [String: Ignored Keyword] // ... // [String: null] keyword = file.ReadString(); while (keyword != null) { binaryIgnoredKeywords.Add(keyword); keyword = file.ReadString(); } } } catch { result = false; } finally { file.Close(); } if (result == false) { // Reset all the objects to empty versions. binaryCommentTypes.Clear(); binarySingularKeywords.Clear(); binaryPluralKeywords.Clear(); binaryIgnoredKeywords.Clear(); } return(result); }
// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Loads the information in <Languages.nd> into a <Config> object, returning whether it was successful. If it was not * config will be null. */ public bool Load(Path filename, out Config config) { BinaryFile file = new BinaryFile(); try { if (file.OpenForReading(filename, "2.2") == false) { config = null; return(false); } else { config = new Config(); // [String: Language Name] // [[Language Attributes]] // ... // [String: null] string languageName = file.ReadString(); while (languageName != null) { Language language = new Language(languageName); // [Int32: ID] // [Byte: Type] // [String: Simple Identifier] // [Byte: Enum Values] // [Byte: Case Sensitive (1 or 0)] // [String: Member Operator Symbol] // [String: Line Extender Symbol] language.ID = file.ReadInt32(); byte type = file.ReadByte(); if (Enum.IsDefined(typeof(Language.LanguageType), type)) { language.Type = (Language.LanguageType)type; } else { config = null; return(false); } language.SimpleIdentifier = file.ReadString(); byte enumValues = file.ReadByte(); if (Enum.IsDefined(typeof(Language.EnumValues), enumValues)) { language.EnumValue = (Language.EnumValues)enumValues; } else { config = null; return(false); } language.CaseSensitive = (file.ReadByte() == 1); language.MemberOperator = file.ReadString(); language.LineExtender = file.ReadString(); // [String: Line Comment Symbol] [] ... [String: null] // [String: Opening Block Comment Symbol] [String: Closing Block Comment Symbol] [] [] ... [String: null] // [String: Javadoc First Line Comment Symbol] [String: Javadoc Following Lines Comment Symbol [] [] ... [String: null] // [String: Javadoc Opening Block Comment Symbol] [String: Javadoc Closing Block Comment Symbol] [] [] ... [String: null] // [String: XML Line Comment Symbol] [] ... [String: null] var lineCommentSymbols = ReadSymbolList(file); if (lineCommentSymbols != null) { language.LineCommentSymbols = lineCommentSymbols; } var blockCommentSymbols = ReadBlockCommentSymbolsList(file); if (blockCommentSymbols != null) { language.BlockCommentSymbols = blockCommentSymbols; } var javadocLineCommentSymbols = ReadLineCommentSymbolsList(file); if (javadocLineCommentSymbols != null) { language.JavadocLineCommentSymbols = javadocLineCommentSymbols; } var javadocBlockCommentSymbols = ReadBlockCommentSymbolsList(file); if (javadocBlockCommentSymbols != null) { language.JavadocBlockCommentSymbols = javadocBlockCommentSymbols; } var xmlLineCommentSymbols = ReadSymbolList(file); if (xmlLineCommentSymbols != null) { language.XMLLineCommentSymbols = xmlLineCommentSymbols; } // Prototype Enders: // [Int32: Comment Type ID] // [Byte: Include Line Breaks (1 or 0)] // [String: Prototype Ender Symbol] [] ... [String: null] // ... // [Int32: 0] int commentTypeID = file.ReadInt32(); while (commentTypeID != 0) { bool includeLineBreaks = (file.ReadByte() == 1); var enderSymbols = ReadSymbolList(file); language.AddPrototypeEnders(new PrototypeEnders(commentTypeID, enderSymbols, includeLineBreaks)); commentTypeID = file.ReadInt32(); } config.AddLanguage(language); languageName = file.ReadString(); } // [String: Alias] [Int32: Language ID] [] [] ... [String: Null] string alias = file.ReadString(); while (alias != null) { int languageID = file.ReadInt32(); config.AddAlias(alias, languageID); alias = file.ReadString(); } // [String: File Extension] [Int32: Language ID] [] [] ... [String: Null] string fileExtension = file.ReadString(); while (fileExtension != null) { int languageID = file.ReadInt32(); config.AddFileExtension(fileExtension, languageID); fileExtension = file.ReadString(); } // [String: Shebang String] [Int32: Language ID] [] [] ... [String: Null] string shebangString = file.ReadString(); while (shebangString != null) { int languageID = file.ReadInt32(); config.AddShebangString(shebangString, languageID); shebangString = file.ReadString(); } } } catch { config = null; return(false); } finally { file.Close(); } return(true); }
public bool ReadFFP(string filePath) { BinaryFile binFile = new BinaryFile(filePath, BinaryFile.ByteOrder.LittleEndian); string header = binFile.ReadString(4); if (header != "FPQr") { return(false); } Version = binFile.ReadInt32(); ParameterCount = binFile.ReadInt32(); // Read in how many bands are enabled var numActiveBands = binFile.ReadSingle(); Bands = new List <ProQBand>(); for (int i = 0; i < 24; i++) { var band = new ProQBand(); band.Frequency = FreqConvertBack(binFile.ReadSingle()); band.Gain = binFile.ReadSingle(); // actual gain in dB band.Q = QConvertBack(binFile.ReadSingle()); // 0 - 5 var filterType = binFile.ReadSingle(); switch (filterType) { case (float)ProQShape.Bell: band.Shape = ProQShape.Bell; break; case (float)ProQShape.LowShelf: band.Shape = ProQShape.LowShelf; break; case (float)ProQShape.LowCut: band.Shape = ProQShape.LowCut; break; case (float)ProQShape.HighShelf: band.Shape = ProQShape.HighShelf; break; case (float)ProQShape.HighCut: band.Shape = ProQShape.HighCut; break; case (float)ProQShape.Notch: band.Shape = ProQShape.Notch; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter type is outside range: {0}", filterType)); } // 0 = 6 dB/oct, 1 = 12 dB/oct, 2 = 24 dB/oct, 3 = 48 dB/oct var filterSlope = binFile.ReadSingle(); switch (filterSlope) { case (float)ProQLPHPSlope.Slope6dB_oct: band.LPHPSlope = ProQLPHPSlope.Slope6dB_oct; break; case (float)ProQLPHPSlope.Slope12dB_oct: band.LPHPSlope = ProQLPHPSlope.Slope12dB_oct; break; case (float)ProQLPHPSlope.Slope24dB_oct: band.LPHPSlope = ProQLPHPSlope.Slope24dB_oct; break; case (float)ProQLPHPSlope.Slope48dB_oct: band.LPHPSlope = ProQLPHPSlope.Slope48dB_oct; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter slope is outside range: {0}", filterSlope)); } // 0 = Left, 1 = Right, 2 = Stereo var filterStereoPlacement = binFile.ReadSingle(); switch (filterStereoPlacement) { case (float)ProQStereoPlacement.LeftOrMid: band.StereoPlacement = ProQStereoPlacement.LeftOrMid; break; case (float)ProQStereoPlacement.RightOrSide: band.StereoPlacement = ProQStereoPlacement.RightOrSide; break; case (float)ProQStereoPlacement.Stereo: band.StereoPlacement = ProQStereoPlacement.Stereo; break; default: throw new ArgumentOutOfRangeException(string.Format("Filter stereo placement is outside range: {0}", filterStereoPlacement)); } // always 1.0 ? var unknown = binFile.ReadSingle(); // check if band is enabled if (numActiveBands > 0 && numActiveBands > i) { band.Enabled = true; } Bands.Add(band); } // read the remaining floats try { OutputGain = binFile.ReadSingle(); // -1 to 1 (- Infinity to +36 dB , 0 = 0 dB) OutputPan = binFile.ReadSingle(); // -1 to 1 (0 = middle) DisplayRange = binFile.ReadSingle(); // 0 = 6dB, 1 = 12dB, 2 = 30dB, 3 = 3dB ProcessMode = binFile.ReadSingle(); // 0 = zero latency, 1 = lin.phase.low - medium - high - maximum ChannelMode = binFile.ReadSingle(); // 0 = Left/Right, 1 = Mid/Side Bypass = binFile.ReadSingle(); // 0 = No bypass ReceiveMidi = binFile.ReadSingle(); // 0 = Enabled? Analyzer = binFile.ReadSingle(); // 0 = Off, 1 = Pre, 2 = Post, 3 = Pre+Post AnalyzerResolution = binFile.ReadSingle(); // 0 - 3 : low - medium[x] - high - maximum AnalyzerSpeed = binFile.ReadSingle(); // 0 - 3 : very slow, slow, medium[x], fast SoloBand = binFile.ReadSingle(); // -1 } catch { } // check if mid/side if (ChannelMode == 1) { Bands.ForEach(b => b.ChannelMode = ProQChannelMode.MidSide); } binFile.Close(); return(true); }
// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Loads the information in <Languages.nd>, which is the computed language settings from the last time Natural Docs * was run. Returns whether it was successful. If not all the out parameters will still return objects, they will just be * empty. */ public bool Load(Path filename, out List <Language> languages, out List <KeyValuePair <string, int> > aliases, out List <KeyValuePair <string, int> > extensions, out List <KeyValuePair <string, int> > shebangStrings, out List <string> ignoredExtensions) { languages = new List <Language>(); aliases = new List <KeyValuePair <string, int> >(); extensions = new List <KeyValuePair <string, int> >(); shebangStrings = new List <KeyValuePair <string, int> >(); ignoredExtensions = new List <string>(); BinaryFile file = new BinaryFile(); bool result = true; IDObjects.NumberSet usedLanguageIDs = new IDObjects.NumberSet(); try { if (file.OpenForReading(filename, "2.0") == false) { result = false; } else { // [String: Language Name] // [Int32: ID] // [Byte: Type] // [String: Simple Identifier] // [Byte: Enum Values] // [Byte: Case Sensitive (1 or 0)] // [String: Member Operator Symbol] // [String: Line Extender Symbol] // [String: Line Comment Symbol] [] ... [String: null] // [String: Opening Block Comment Symbol] [String: Closing Block Comment Symbo] [] [] ... [String: null] // [String: Opening Javadoc Line Comment Symbol] [String: Remainder Javadoc Line Comment Symbol [] ... [String: null] // [String: Opening Javadoc Block Comment Symbol] [String: Closing Javadoc Block Comment Symbol] [] [] ... [String: null] // [String: XML Line Comment Symbol] [] ... [String: null] // [Int32: Comment Type ID] // [Byte: Include Line Breaks (1 or 0)] // [String: Prototype Ender Symbol] [] ... [String: null] // ... // [Int32: 0] // ... // [String: null] for (string languageName = file.ReadString(); languageName != null; languageName = file.ReadString()) { Language language = new Language(languageManager, languageName); language.ID = file.ReadInt32(); byte rawTypeValue = file.ReadByte(); if (Enum.IsDefined(typeof(Language.LanguageType), rawTypeValue)) { language.Type = (Language.LanguageType)rawTypeValue; } else { result = false; } language.SimpleIdentifier = file.ReadString(); byte rawEnumValue = file.ReadByte(); if (Enum.IsDefined(typeof(Language.EnumValues), rawEnumValue)) { language.EnumValue = (Language.EnumValues)rawEnumValue; } else { result = false; } language.CaseSensitive = (file.ReadByte() == 1); language.MemberOperator = file.ReadString(); language.LineExtender = file.ReadString(); language.LineCommentStrings = ReadStringArray(file); language.BlockCommentStringPairs = ReadStringArray(file); language.JavadocLineCommentStringPairs = ReadStringArray(file); language.JavadocBlockCommentStringPairs = ReadStringArray(file); language.XMLLineCommentStrings = ReadStringArray(file); for (int commentTypeID = file.ReadInt32(); commentTypeID != 0; commentTypeID = file.ReadInt32()) { bool includeLineBreaks = (file.ReadByte() == 1); string[] enderSymbols = ReadStringArray(file); language.SetPrototypeEnders(commentTypeID, new PrototypeEnders(enderSymbols, includeLineBreaks)); } languages.Add(language); usedLanguageIDs.Add(language.ID); } // [String: Alias] [Int32: Language ID] [] [] ... [String: Null] for (string alias = file.ReadString(); alias != null; alias = file.ReadString()) { int languageID = file.ReadInt32(); if (usedLanguageIDs.Contains(languageID) == true) { aliases.Add(new KeyValuePair <string, int>(alias, languageID)); } else { result = false; } } // [String: Extension] [Int32: Language ID] [] [] ... [String: Null] for (string extension = file.ReadString(); extension != null; extension = file.ReadString()) { int languageID = file.ReadInt32(); if (usedLanguageIDs.Contains(languageID) == true) { extensions.Add(new KeyValuePair <string, int>(extension, languageID)); } else { result = false; } } // [String: Shebang String] [Int32: Language ID] [] [] ... [String: Null] for (string shebangString = file.ReadString(); shebangString != null; shebangString = file.ReadString()) { int languageID = file.ReadInt32(); if (usedLanguageIDs.Contains(languageID) == true) { shebangStrings.Add(new KeyValuePair <string, int>(shebangString, languageID)); } else { result = false; } } // [String: Ignored Extension] [] ... [String: Null] for (string ignoredExtension = file.ReadString(); ignoredExtension != null; ignoredExtension = file.ReadString()) { ignoredExtensions.Add(ignoredExtension); } } } catch { result = false; } finally { file.Close(); } if (result == false) { // Reset all the objects to empty versions. languages.Clear(); extensions.Clear(); shebangStrings.Clear(); ignoredExtensions.Clear(); } return(result); }
public static void Unpack(string file, string outputDirectoryPath, bool doList, bool doVerbose) { using (BinaryFile bf = new BinaryFile(file, BinaryFile.ByteOrder.LittleEndian, false)) { UInt32 fileSize = bf.ReadUInt32(); Log.Debug("fileSize: " + fileSize); bf.Seek(350, SeekOrigin.Begin); int snpidCount = bf.ReadInt32(); string snpid = bf.ReadString(snpidCount * 2, Encoding.Unicode); // snpid cannot have more than 4 characters (?!) if (snpidCount > 4) { snpidCount = 0; snpid = ""; bf.Seek(355, SeekOrigin.Begin); } else { bf.ReadBytes(25); } Log.Debug("snpid: " + snpid); int versionCount = bf.ReadInt32(); string version = bf.ReadString(versionCount * 2, Encoding.Unicode); Log.Debug("version: " + version); bf.ReadBytes(122); int presetNameCount = bf.ReadInt32(); string presetName = bf.ReadString(presetNameCount * 2, Encoding.Unicode); int presetNameRest = bf.ReadInt32(); Log.Debug("presetName: " + presetName); int companyNameCount = bf.ReadInt32(); string companyName = bf.ReadString(companyNameCount * 2, Encoding.Unicode); int companyNameRest = bf.ReadInt32(); Log.Debug("companyName: " + companyName); bf.ReadBytes(40); int libraryNameCount = bf.ReadInt32(); string libraryName = bf.ReadString(libraryNameCount * 2, Encoding.Unicode); int libraryNameRest = bf.ReadInt32(); Log.Debug("libraryName: " + libraryName); int typeCount = bf.ReadInt32(); if (typeCount != 0) { string type = bf.ReadString(typeCount * 2, Encoding.Unicode); int typeRest = bf.ReadInt32(); Log.Debug("type: " + type); } int number = bf.ReadInt32(); for (int i = 0; i < number * 2; i++) { int sCount = bf.ReadInt32(); string s = bf.ReadString(sCount * 2, Encoding.Unicode); Log.Debug(s); } bf.ReadBytes(249); UInt32 chunkSize = bf.ReadUInt32(); Log.Debug("chunkSize: " + chunkSize); string outputFileName = Path.GetFileNameWithoutExtension(file); string outputFilePath = Path.Combine(outputDirectoryPath, "NKI_CONTENT", outputFileName + ".bin"); IOUtils.CreateDirectoryIfNotExist(Path.Combine(outputDirectoryPath, "NKI_CONTENT")); var nks = new Nks(); nks.BinaryFile = bf; nks.SetKeys = new Dictionary <String, NksSetKey>(); NksEncryptedFileHeader header = new NksEncryptedFileHeader(); header.SetId = snpid.ToUpper(); header.KeyIndex = 0x100; header.Size = chunkSize; BinaryFile outBinaryFile = new BinaryFile(outputFilePath, BinaryFile.ByteOrder.LittleEndian, true); if (snpid == "") { if (!doList) { NKS.ExtractFileEntryToBf(nks, header, outBinaryFile); } } else { if (!doList) { NKS.ExtractEncryptedFileEntryToBf(nks, header, outBinaryFile); } } outBinaryFile.Close(); } }
// Group: Saving Functions // __________________________________________________________________________ /* Function: Save * Saves the passed <ProjectConfig> into <Project.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, ProjectConfig projectConfig) { var output = new BinaryFile(); output.OpenForWriting(filename); try { // [Int32: Tab Width] // [Byte: Documented Only (0 or 1)] // [Byte: Auto Group (0 or 1)] // [Byte: Shrink Files (0 or 1)] output.WriteInt32(projectConfig.TabWidth); output.WriteByte((byte)((bool)projectConfig.DocumentedOnly == false ? 0 : 1)); output.WriteByte((byte)((bool)projectConfig.AutoGroup == false ? 0 : 1)); output.WriteByte((byte)((bool)projectConfig.ShrinkFiles == false ? 0 : 1)); // [String: Identifier] // [[Properties]] // ... // [String: null] foreach (var target in projectConfig.InputTargets) { if (target is Targets.SourceFolder) { SaveSourceFolder((Targets.SourceFolder)target, output); } else if (target is Targets.ImageFolder) { SaveImageFolder((Targets.ImageFolder)target, output); } else { throw new NotImplementedException(); } } // We don't save filter targets foreach (var target in projectConfig.OutputTargets) { if (target is Targets.HTMLOutputFolder) { SaveHTMLOutputFolder((Targets.HTMLOutputFolder)target, output); } else { throw new NotImplementedException(); } } output.WriteString(null); } finally { output.Close(); } }
// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Loads the information in <Project.nd>, returning whether it was successful. */ public bool Load(Path filename, out ProjectConfig projectConfig) { projectConfig = new ProjectConfig(PropertySource.PreviousRun); this.projectConfig = projectConfig; binaryFile = new BinaryFile(); bool result = true; try { // There were no file format changes between 2.0 and 2.0.2 but there were parsing changes and // bug fixes that require a full rebuild. if (binaryFile.OpenForReading(filename, "2.0.2") == false) { result = false; } else { // [Int32: Tab Width] // [Byte: Documented Only (0 or 1)] // [Byte: Auto Group (0 or 1)] // [Byte: Shrink Files (0 or 1)] projectConfig.TabWidth = binaryFile.ReadInt32(); projectConfig.TabWidthPropertyLocation = PropertySource.PreviousRun; projectConfig.DocumentedOnly = (binaryFile.ReadByte() == 1); projectConfig.DocumentedOnlyPropertyLocation = PropertySource.PreviousRun; projectConfig.AutoGroup = (binaryFile.ReadByte() == 1); projectConfig.AutoGroupPropertyLocation = PropertySource.PreviousRun; projectConfig.ShrinkFiles = (binaryFile.ReadByte() == 1); projectConfig.ShrinkFilesPropertyLocation = PropertySource.PreviousRun; // [String: Identifier] // [[Properties]] // ... // [String: null] string identifier = binaryFile.ReadString(); while (identifier != null) { LoadTarget(identifier); identifier = binaryFile.ReadString(); } } } catch { result = false; // Reset everything. projectConfig = new ProjectConfig(PropertySource.PreviousRun); } finally { binaryFile.Close(); } return(result); }
// Group: Saving Functions // __________________________________________________________________________ /* Function: Save * Saves the current computed languages into <Languages.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, IDObjects.Manager <Language> languages, StringTable <Language> aliases, StringTable <Language> extensions, SortedStringTable <Language> shebangStrings, StringSet ignoredExtensions) { BinaryFile file = new BinaryFile(); file.OpenForWriting(filename); try { // [String: Language Name] // [Int32: ID] // [Byte: Type] // [String: Simple Identifier] // [Byte: Enum Values] // [Byte: Case Sensitive (1 or 0)] // [String: Member Operator Symbol] // [String: Line Extender Symbol] // [String: Line Comment Symbol] [] ... [String: null] // [String: Opening Block Comment Symbol] [String: Closing Block Comment Symbo] [] [] ... [String: null] // [String: Opening Javadoc Line Comment Symbol] [String: Remainder Javadoc Line Comment Symbol [] ... [String: null] // [String: Opening Javadoc Block Comment Symbol] [String: Closing Javadoc Block Comment Symbol] [] [] ... [String: null] // [String: XML Line Comment Symbol] [] ... [String: null] // [Int32: Comment Type ID] // [Byte: Include Line Breaks (0 or 1)] // [String: Prototype Ender Symbol] [] ... [String: null] // ... // [Int32: 0] // ... // [String: null] foreach (Language language in languages) { file.WriteString(language.Name); file.WriteInt32(language.ID); file.WriteByte((byte)language.Type); file.WriteString(language.SimpleIdentifier); file.WriteByte((byte)language.EnumValue); file.WriteByte((byte)(language.CaseSensitive ? 1 : 0)); file.WriteString(language.MemberOperator); file.WriteString(language.LineExtender); WriteStringArray(file, language.LineCommentStrings); WriteStringArray(file, language.BlockCommentStringPairs); WriteStringArray(file, language.JavadocLineCommentStringPairs); WriteStringArray(file, language.JavadocBlockCommentStringPairs); WriteStringArray(file, language.XMLLineCommentStrings); int[] commentTypes = language.GetCommentTypesWithPrototypeEnders(); if (commentTypes != null) { foreach (int commentType in commentTypes) { PrototypeEnders prototypeEnders = language.GetPrototypeEnders(commentType); file.WriteInt32(commentType); file.WriteByte((byte)(prototypeEnders.IncludeLineBreaks ? 1 : 0)); WriteStringArray(file, prototypeEnders.Symbols); } } file.WriteInt32(0); } file.WriteString(null); // [String: Alias] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in aliases) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Extension] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in extensions) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Shebang String] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in shebangStrings) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Ignored Extension] [] ... [String: Null] foreach (string ignoredExtension in ignoredExtensions) { file.WriteString(ignoredExtension); } file.WriteString(null); } finally { file.Close(); } }
// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Loads the information in <Project.nd>, returning whether it was successful. */ public bool Load(Path filename, out ProjectConfig projectConfig) { projectConfig = new ProjectConfig(Source.PreviousRun); this.projectConfig = projectConfig; binaryFile = new BinaryFile(); bool result = true; try { if (binaryFile.OpenForReading(filename, "2.0") == false) { result = false; } else { // [Int32: Tab Width] // [Byte: Documented Only (0 or 1)] // [Byte: Auto Group (0 or 1)] // [Byte: Shrink Files (0 or 1)] projectConfig.TabWidth = binaryFile.ReadInt32(); projectConfig.TabWidthPropertyLocation = Source.PreviousRun; projectConfig.DocumentedOnly = (binaryFile.ReadByte() == 1); projectConfig.DocumentedOnlyPropertyLocation = Source.PreviousRun; projectConfig.AutoGroup = (binaryFile.ReadByte() == 1); projectConfig.AutoGroupPropertyLocation = Source.PreviousRun; projectConfig.ShrinkFiles = (binaryFile.ReadByte() == 1); projectConfig.ShrinkFilesPropertyLocation = Source.PreviousRun; // [String: Identifier] // [[Properties]] // ... // [String: null] string identifier = binaryFile.ReadString(); while (identifier != null) { LoadTarget(identifier); identifier = binaryFile.ReadString(); } } } catch { result = false; // Reset everything. projectConfig = new ProjectConfig(Source.PreviousRun); } finally { binaryFile.Close(); } return(result); }
// Group: Saving Functions // __________________________________________________________________________ /* Function: Save * Saves the current computed languages into <Languages.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, Config config) { BinaryFile file = new BinaryFile(); file.OpenForWriting(filename); try { // [String: Language Name] // [[Language Attributes]] // ... // [String: null] foreach (var language in config.Languages) { file.WriteString(language.Name); // [Int32: ID] // [Byte: Type] // [String: Simple Identifier] // [Byte: Enum Values] // [Byte: Case Sensitive (1 or 0)] // [String: Member Operator Symbol] // [String: Line Extender Symbol] file.WriteInt32(language.ID); file.WriteByte((byte)language.Type); file.WriteString(language.SimpleIdentifier); file.WriteByte((byte)language.EnumValue); file.WriteByte((byte)(language.CaseSensitive ? 1 : 0)); file.WriteString(language.MemberOperator); file.WriteString(language.LineExtender); // [String: Line Comment Symbol] [] ... [String: null] // [String: Opening Block Comment Symbol] [String: Closing Block Comment Symbo] [] [] ... [String: null] // [String: Javadoc First Line Comment Symbol] [String: Javadoc Following Lines Comment Symbol [] ... [String: null] // [String: Javadoc Opening Block Comment Symbol] [String: Javadoc Closing Block Comment Symbol] [] [] ... [String: null] // [String: XML Line Comment Symbol] [] ... [String: null] WriteSymbolList(file, language.LineCommentSymbols); WriteBlockCommentSymbolsList(file, language.BlockCommentSymbols); WriteLineCommentSymbolsList(file, language.JavadocLineCommentSymbols); WriteBlockCommentSymbolsList(file, language.JavadocBlockCommentSymbols); WriteSymbolList(file, language.XMLLineCommentSymbols); // Prototype Enders: // [Int32: Comment Type ID] // [Byte: Include Line Breaks (0 or 1)] // [String: Prototype Ender Symbol] [] ... [String: null] // ... // [Int32: 0] if (language.HasPrototypeEnders) { foreach (var prototypeEnders in language.PrototypeEnders) { file.WriteInt32(prototypeEnders.CommentTypeID); file.WriteByte((byte)(prototypeEnders.IncludeLineBreaks ? 1 : 0)); WriteSymbolList(file, prototypeEnders.Symbols); } } file.WriteInt32(0); } file.WriteString(null); // [String: Alias] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, int> aliasKVP in config.Aliases) { file.WriteString(aliasKVP.Key); file.WriteInt32(aliasKVP.Value); } file.WriteString(null); // [String: File Extension] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, int> fileExtensionKVP in config.FileExtensions) { file.WriteString(fileExtensionKVP.Key); file.WriteInt32(fileExtensionKVP.Value); } file.WriteString(null); // [String: Shebang String] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, int> shebangStringKVP in config.ShebangStrings) { file.WriteString(shebangStringKVP.Key); file.WriteInt32(shebangStringKVP.Value); } file.WriteString(null); } finally { file.Close(); } }
public bool Read(string filePath) { if (File.Exists(filePath)) { string fileName = Path.GetFileNameWithoutExtension(filePath); PresetName = fileName; BinaryFile bFile = new BinaryFile(filePath, BinaryFile.ByteOrder.BigEndian); string firstChunkID = bFile.ReadString(4); // chunk ID = "FORM" int ckSize = bFile.ReadInt32(); string formType = bFile.ReadString(4); // read first data chunk string chunkID = bFile.ReadString(4); // if chunkID == "COMT" then CommentsChunk if (chunkID.Equals("COMT")) { long curposTmpComt = bFile.GetPosition(); bFile.Seek(curposTmpComt - 4); // CommentsChunk string chunkIDComt = bFile.ReadString(4); // chunk ID = "COMT" int chunkSizeComt = bFile.ReadInt32(); int numComments = bFile.ReadUInt16(); long curposTmpComt2 = bFile.GetPosition(); for (int i = 0; i < numComments; i++) { int commentTimestamp = (int)bFile.ReadUInt32(); string marker = bFile.ReadString(4); int count = (int)bFile.ReadByte(); comments.Add(bFile.ReadString(count)); } bFile.Seek(curposTmpComt2 + chunkSizeComt - 2); } string chunkID2 = bFile.ReadString(4); // if chunkID2 == "COMM" then CommonChunk if (chunkID2.Equals("COMM")) { long curposTmpComm = bFile.GetPosition(); bFile.Seek(curposTmpComm - 4); // CommonChunk string chunkIDComm = bFile.ReadString(4); // chunk ID = "COMM" int chunkSizeComm = bFile.ReadInt32(); channels = bFile.ReadInt16(); numSampleFrames = (int)bFile.ReadUInt32(); bitsPerSample = bFile.ReadInt16(); // read IEEE 80-bit extended double precision byte[] sampleRateBytes = bFile.ReadBytes(0, 10, BinaryFile.ByteOrder.LittleEndian); double sampleRateDouble = IEEE.ConvertFromIeeeExtended(sampleRateBytes); sampleRate = (int)sampleRateDouble; } string chunkID3 = bFile.ReadString(4); // if chunkID3 == "SSND" then SoundDataChunk if (chunkID3.Equals("SSND")) { long curposTmpSsnd = bFile.GetPosition(); bFile.Seek(curposTmpSsnd - 4); // SoundDataChunk string chunkIDSsnd = bFile.ReadString(4); // chunk ID = "SSND" int chunkSizeSsnd = bFile.ReadInt32(); int offset = (int)bFile.ReadUInt32(); int blocksize = (int)bFile.ReadUInt32(); byte[] data = bFile.ReadBytes(offset, chunkSizeSsnd - 8, BinaryFile.ByteOrder.LittleEndian); // swap waveform data WaveformData = SwapAiffEndian(data); } bFile.Close(); return(true); } else { return(false); } }
static readonly byte[] NKS_NICNT_TOC = new byte[] { 0x2F, 0x5C, 0x20, 0x4E, 0x49, 0x20, 0x46, 0x43, 0x20, 0x54, 0x4F, 0x43, 0x20, 0x20, 0x2F, 0x5C }; // /\ NI FC TOC /\ public static void Unpack(string inputFilePath, string outputDirectoryPath, bool doList, bool doVerbose) { using (BinaryFile bf = new BinaryFile(inputFilePath, BinaryFile.ByteOrder.LittleEndian, false)) { var header = bf.ReadBytes(16); if (header.SequenceEqual(NKS_NICNT_MTD)) // 2F 5C 20 4E 49 20 46 43 20 4D 54 44 20 20 2F 5C /\ NI FC MTD /\ { bf.Seek(66, SeekOrigin.Begin); string version = bf.ReadString(66, Encoding.Unicode).TrimEnd('\0'); Log.Information("Version: " + version); string outputFileName = Path.GetFileNameWithoutExtension(inputFilePath); if (!doList) { IOUtils.CreateDirectoryIfNotExist(Path.Combine(outputDirectoryPath, outputFileName)); } // Save version in ContentVersion.txt if (!doList) { IOUtils.WriteTextToFile(Path.Combine(outputDirectoryPath, outputFileName, "ContentVersion.txt"), version); } int unknown1 = bf.ReadInt32(); if (doVerbose) { Log.Debug("Unknown1: " + unknown1); } bf.Seek(144, SeekOrigin.Begin); int startOffset = bf.ReadInt32(); Log.Information("Start Offset: " + startOffset); int unknown3 = bf.ReadInt32(); if (doVerbose) { Log.Debug("Unknown3: " + unknown3); } bf.Seek(256, SeekOrigin.Begin); string productHintsXml = bf.ReadStringNull(); Log.Information(string.Format("Read ProductHints Xml with length {0} characters.", productHintsXml.Length)); if (doVerbose) { Log.Debug("ProductHints Xml:\n" + productHintsXml); } // Save productHints as xml if (!doList) { IOUtils.WriteTextToFile(Path.Combine(outputDirectoryPath, outputFileName, outputFileName + ".xml"), productHintsXml); } // get the product hints as an object var productHints = ProductHintsFactory.ReadFromString(productHintsXml); if (productHints != null && productHints.Product.Icon != null && productHints.Product.Icon.ImageBytes != null) { ProductHintsFactory.UpdateImageFromImageBytes(productHints); var image = productHints.Product.Icon.Image; var imageFormat = productHints.Product.Icon.ImageFormat; if (image != null && imageFormat != null) { Log.Information(string.Format("Found Icon in ProductHints Xml in {0} format. (Dimensions: {1} x {2}, Width: {1} pixels, Height: {2} pixels, Bit depth: {3} bpp)", imageFormat.Name, image.Width, image.Height, image.PixelType.BitsPerPixel)); // save icon to file if (!doList) { var iconFileName = outputFileName + " Icon." + imageFormat.Name.ToLower(); var iconFilePath = Path.Combine(outputDirectoryPath, outputFileName, iconFileName); if (doVerbose) { Log.Debug("Saving Icon to: " + iconFilePath); } // save using ImageSharp // var imageEncoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(imageFormat); // image.Save(iconFilePath, imageEncoder); // save using image bytes BinaryFile.ByteArrayToFile(iconFilePath, productHints.Product.Icon.ImageBytes); } } } bf.Seek(startOffset + 256, SeekOrigin.Begin); var header2 = bf.ReadBytes(16); if (header2.SequenceEqual(NKS_NICNT_MTD)) // 2F 5C 20 4E 49 20 46 43 20 4D 54 44 20 20 2F 5C /\ NI FC MTD /\ { bf.ReadBytes(116); long unknown4 = bf.ReadInt64(); if (doVerbose) { Log.Debug("Unknown4: " + unknown4); } bf.ReadBytes(4); long unknown5 = bf.ReadInt64(); if (doVerbose) { Log.Debug("Unknown5: " + unknown5); } bf.ReadBytes(104); long unknown6 = bf.ReadInt64(); if (doVerbose) { Log.Debug("Unknown6: " + unknown6); } var delimiter1 = bf.ReadBytes(8); if (doVerbose) { Log.Debug("Delimiter1: " + StringUtils.ByteArrayToHexString(delimiter1)); // F0 F0 F0 F0 F0 F0 F0 F0 } if (!delimiter1.SequenceEqual(new byte[] { 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 })) { Log.Error("Delimiter1 not as expected 'F0 F0 F0 F0 F0 F0 F0 F0' but got " + StringUtils.ToHexAndAsciiString(delimiter1)); } long totalResourceCount = bf.ReadInt64(); Log.Information("Total Resource Count: " + totalResourceCount); long totalResourceLength = bf.ReadInt64(); Log.Information("Total Resource Byte Length: " + totalResourceLength); var resourceList = new List <NICNTResource>(); var header3 = bf.ReadBytes(16); if (header3.SequenceEqual(NKS_NICNT_TOC)) // 2F 5C 20 4E 49 20 46 43 20 54 4F 43 20 20 2F 5C /\ NI FC TOC /\ { bf.ReadBytes(600); long lastEndIndex = 0; for (int i = 0; i < totalResourceCount; i++) { var resource = new NICNTResource(); Log.Information("-------- Index: " + bf.Position + " --------"); long resCounter = bf.ReadInt64(); Log.Information("Resource Counter: " + resCounter); resource.Count = resCounter; bf.ReadBytes(16); string resName = bf.ReadString(600, Encoding.Unicode).TrimEnd('\0'); Log.Information("Resource Name: " + resName); resource.Name = resName; long resUnknown = bf.ReadInt64(); if (doVerbose) { Log.Debug("Resource Unknown: " + resUnknown); } long resEndIndex = bf.ReadInt64(); Log.Information("Resource End Index: " + resEndIndex); resource.EndIndex = resEndIndex; // store calculated length if (lastEndIndex > 0) { resource.Length = resEndIndex - lastEndIndex; } else { // for the very first entry the end index is the same as the byte length resource.Length = resEndIndex; } Log.Information("Calculated Resource Byte Length: " + resource.Length); lastEndIndex = resEndIndex; resourceList.Add(resource); } Log.Information("-------- Index: " + bf.Position + " --------"); var delimiter2 = bf.ReadBytes(8); if (doVerbose) { Log.Debug("Delimiter2: " + StringUtils.ByteArrayToHexString(delimiter2)); // F1 F1 F1 F1 F1 F1 F1 F1 } if (!delimiter2.SequenceEqual(new byte[] { 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1 })) { Log.Error("Delimiter2 not as expected 'F1 F1 F1 F1 F1 F1 F1 F1' but got " + StringUtils.ToHexAndAsciiString(delimiter2)); } long unknown13 = bf.ReadInt64(); if (doVerbose) { Log.Debug("Unknown13: " + unknown13); } long unknown14 = bf.ReadInt64(); if (doVerbose) { Log.Debug("Unknown14: " + unknown14); } var header4 = bf.ReadBytes(16); if (header4.SequenceEqual(NKS_NICNT_TOC)) // 2F 5C 20 4E 49 20 46 43 20 54 4F 43 20 20 2F 5C /\ NI FC TOC /\ { bf.ReadBytes(592); if (!doList) { IOUtils.CreateDirectoryIfNotExist(Path.Combine(outputDirectoryPath, outputFileName, "Resources")); } foreach (var res in resourceList) { // convert the unix filename to a windows supported filename string escapedFileName = FromUnixFileNames(res.Name); // and add the counter in front string escapedFileNameWithNumber = string.Format("{0:D3}{1}", res.Count, escapedFileName); Log.Information(String.Format("Resource '{0}' @ position {1} [{2} bytes]", escapedFileNameWithNumber, bf.Position, res.Length)); res.Data = bf.ReadBytes((int)res.Length); // if not only listing, save files if (!doList) { string outputFilePath = Path.Combine(outputDirectoryPath, outputFileName, "Resources", escapedFileNameWithNumber); BinaryFile outBinaryFile = new BinaryFile(outputFilePath, BinaryFile.ByteOrder.LittleEndian, true); outBinaryFile.Write(res.Data); outBinaryFile.Close(); } } } else { Log.Error(inputFilePath + ": Header4 not as expected '/\\ NI FC TOC /\\' but got " + StringUtils.ToHexAndAsciiString(header4)); } } else { Log.Error(inputFilePath + ": Header3 not as expected '/\\ NI FC TOC /\\' but got " + StringUtils.ToHexAndAsciiString(header3)); } } else { Log.Error(inputFilePath + ": Header2 not as expected '/\\ NI FC MTD /\\' but got " + StringUtils.ToHexAndAsciiString(header2)); } } else { Log.Error(inputFilePath + ": Header not as expected '/\\ NI FC MTD /\\' but got " + StringUtils.ToHexAndAsciiString(header)); } } }
/* Function: Save * Saves the current computed comment types into <Comments.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, IDObjects.Manager <CommentType> commentTypes, IDObjects.Manager <Tag> tags, StringTable <CommentType> singularKeywords, StringTable <CommentType> pluralKeywords, StringSet ignoredKeywords) { BinaryFile file = new BinaryFile(); file.OpenForWriting(filename); try { // [String: Tag Name] // [Int32: ID] // ... // [String: null] foreach (Tag tag in tags) { file.WriteString(tag.Name); file.WriteInt32(tag.ID); } file.WriteString(null); // [String: Comment Type Name] // [Int32: ID] // [String: Display Name] // [String: Plural Display Name] // [String: Simple Identifier] // [Byte: Index] // [Int32: Index With ID]? // [Byte: Scope] // [Byte: Break Lists] // [UInt16: Flags] // ... // [String: null] foreach (CommentType commentType in commentTypes) { file.WriteString(commentType.Name); file.WriteInt32(commentType.ID); file.WriteString(commentType.DisplayName); file.WriteString(commentType.PluralDisplayName); file.WriteString(commentType.SimpleIdentifier); file.WriteByte((byte)commentType.Index); if (commentType.Index == CommentType.IndexValue.IndexWith) { file.WriteInt32(commentType.IndexWith); } file.WriteByte((byte)commentType.Scope); file.WriteByte((byte)(commentType.BreakLists ? 1 : 0)); file.WriteUInt16((ushort)commentType.Flags.AllConfigurationProperties); } file.WriteString(null); // [String: Singular Keyword] // [Int32: Comment Type ID] // ... // [String: null] foreach (KeyValuePair <string, CommentType> pair in singularKeywords) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Plural Keyword] // [Int32: Comment Type ID] // ... // [String: null] foreach (KeyValuePair <string, CommentType> pair in pluralKeywords) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Ignored Keyword] // ... // [String: null] foreach (string keyword in ignoredKeywords) { file.WriteString(keyword); } file.WriteString(null); } finally { file.Close(); } }
/* Function: Load * Loads <Files.nd> and returns whether it was successful. If it wasn't it will still return valid objects, they will just * be empty. */ public bool Load(Path filename, out IDObjects.Manager <File> files) { files = new IDObjects.Manager <File>(Config.Manager.KeySettingsForPaths, false); BinaryFile binaryFile = new BinaryFile(); bool result = true; try { // We'll continue to handle 2.0 files in 2.0.2 since it's easy enough if (binaryFile.OpenForReading(filename, "2.0") == false) { result = false; } else { // [Int32: ID] // [String: Path] // [Byte: Type] // [Int64: Last Modification in Ticks or 0] // (if image) // [UInt32: Width in Pixels or 0 if unknown] // [UInt32: Height in Pixels or 0 if unknown] // ... // [Int32: 0] int id; Path path; FileType type; DateTime lastModification; File file; uint width, height; for (;;) { id = binaryFile.ReadInt32(); if (id == 0) { break; } path = binaryFile.ReadString(); type = (FileType)binaryFile.ReadByte(); lastModification = new DateTime(binaryFile.ReadInt64()); if (type == FileType.Image) { if (binaryFile.Version < "2.0.2") { width = 0; height = 0; } else { width = binaryFile.ReadUInt32(); height = binaryFile.ReadUInt32(); } if (width == 0 || height == 0) { // If this file is from a different version of Natural Docs, no matter which one, reset the last modification // time so they'll be reparsed and take another stab at getting the dimensions if (binaryFile.Version != Engine.Instance.Version) { lastModification = new DateTime(0); } file = new ImageFile(path, lastModification); } else { file = new ImageFile(path, lastModification, width, height); } } else { file = new File(path, type, lastModification); } file.ID = id; files.Add(file); } } } catch { result = false; } finally { binaryFile.Close(); } if (result == false) { files.Clear(); } return(result); }
public static void WriteWaveFile(BinaryFile waveFile, float[][] sound, int numChannels, int numSamples, int sampleRate, int bitsPerSample = 32) { /* * The canonical WAVE format starts with the RIFF header: * 0 4 ChunkID Contains the letters "RIFF" in ASCII form * (0x52494646 big-endian form). * 4 4 ChunkSize 36 + SubChunk2Size, or more precisely: * 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) * This is the size of the rest of the chunk * following this number. This is the size of the * entire file in bytes minus 8 bytes for the * two fields not included in this count: * ChunkID and ChunkSize. * 8 4 Format Contains the letters "WAVE" * (0x57415645 big-endian form). * * The "WAVE" format consists of two subchunks: "fmt " and "data": * The "fmt " subchunk describes the sound data's format: * * 12 4 Subchunk1ID Contains the letters "fmt " * (0x666d7420 big-endian form). * 16 4 Subchunk1Size 16 for PCM. This is the size of the * rest of the Subchunk which follows this number. * 20 2 AudioFormat PCM = 1 (i.e. Linear quantization) * Values other than 1 indicate some * form of compression. * 22 2 NumChannels Mono = 1, Stereo = 2, etc. * 24 4 SampleRate 8000, 44100, etc. * 28 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8 * 32 2 BlockAlign == NumChannels * BitsPerSample/8 * The number of bytes for one sample including * all channels. I wonder what happens when * this number isn't an integer? * 34 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc. * 2 ExtraParamSize if PCM, then doesn't exist * X ExtraParams space for extra parameters * * The "data" subchunk contains the size of the data and the actual sound: * * 36 4 Subchunk2ID Contains the letters "data" * (0x64617461 big-endian form). * 40 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 * This is the number of bytes in the data. * You can also think of this as the size * of the read of the subchunk following this * number. * 44 * Data The actual sound data. */ #region WAV tags generation // integers int RIFF = BinaryFile.StringToInt32("RIFF"); // 1179011410 int WAVE = BinaryFile.StringToInt32("WAVE"); // 1163280727 int FMT = BinaryFile.StringToInt32("fmt "); // 544501094 int DATA = BinaryFile.StringToInt32("data"); // 1635017060 int[] tag = { RIFF, 0, WAVE, FMT, 16, 1, 1, 0, 0, 0, 0, DATA, 0, 0 }; tag[12] = numSamples * numChannels * (bitsPerSample / 8); tag[1] = tag[12] + 36; if ((bitsPerSample == 8) || (bitsPerSample == 16)) { tag[5] = WAVE_FORMAT_PCM; } if (bitsPerSample == 32) { tag[5] = WAVE_FORMAT_IEEE_FLOAT; } tag[6] = numChannels; tag[7] = sampleRate; tag[8] = sampleRate * bitsPerSample / 8; // Average bytes per second tag[9] = numChannels * bitsPerSample / 8; // Block align tag[10] = bitsPerSample; // Significant bits per sample #endregion WAV tags generation // tag writing for (int i = 0; i < 13; i++) { if ((i == 5) || (i == 6) || (i == 9) || (i == 10)) { waveFile.Write((ushort)tag[i]); } else { waveFile.Write((uint)tag[i]); } } if (bitsPerSample == 8) { Write8Bit(waveFile, sound, numSamples, numChannels); } else if (bitsPerSample == 16) { Write16Bit(waveFile, sound, numSamples, numChannels); } else if (bitsPerSample == 24) { Write24Bit(waveFile, sound, numSamples, numChannels); } else if (bitsPerSample == 32) { Write32BitFloat(waveFile, sound, numSamples, numChannels); } waveFile.Close(); }