/// <summary> /// Save the all-in-one cmp file. /// </summary> /// <param name="savingEnv">Working environment.</param> /// <param name="cmpSetInfo">Information of the cmp set.</param> private static void SaveAllInOneFile(SavingEnv savingEnv, CmpSetInfo cmpSetInfo) { FileStream stream = File.Open(savingEnv.ResultCmpFile, FileMode.Create); try { using (BinaryWriter writer = new BinaryWriter(stream)) { stream = null; writer.Write(cmpSetInfo.SamplePeriod); writer.Write(cmpSetInfo.RecordSize); writer.Write(cmpSetInfo.LspOrder); writer.Write(cmpSetInfo.MbeOrder); writer.Write(cmpSetInfo.PowerOrder); writer.Write(cmpSetInfo.GuidanceLspOrder); writer.Write(cmpSetInfo.SentenceCount); for (int i = 0; i < savingEnv.CmpInfoDict.Count; i++) { SingleCmpInfo singleCmpInfo = savingEnv.CmpInfoDict.Values.ElementAt(i); writer.Write(singleCmpInfo.SentID); writer.Write(singleCmpInfo.SampleCount); // temporarily use indexIntoFile to denotes the position of itself in file singleCmpInfo.IndexIntoFile = (int)writer.BaseStream.Position; writer.Write(singleCmpInfo.IndexIntoFile); savingEnv.CmpInfoDict[savingEnv.CmpInfoDict.Keys.ElementAt(i)] = singleCmpInfo; } int offset = (int)writer.BaseStream.Position; foreach (KeyValuePair<string, SingleCmpInfo> kvp in savingEnv.CmpInfoDict) { SingleCmpInfo singleCmpInfo = kvp.Value; writer.Seek(singleCmpInfo.IndexIntoFile, SeekOrigin.Begin); singleCmpInfo.IndexIntoFile = offset; writer.Write(singleCmpInfo.IndexIntoFile); offset += cmpSetInfo.RecordSize * singleCmpInfo.SampleCount; } writer.Seek(0, SeekOrigin.End); const int SingleCmpHeadSize = 12; for (int i = 0; i < savingEnv.SentPaths.Count; i++) { string sentID = savingEnv.SentIDs[i]; string partialPath = savingEnv.SentPaths[i]; FileStream file = File.Open(FormCmpFullPath(savingEnv.WorkingPath, partialPath), FileMode.Open); try { using (BinaryReader reader = new BinaryReader(file)) { file = null; reader.BaseStream.Seek(SingleCmpHeadSize, SeekOrigin.Begin); CopyStreamData(reader, writer); } } finally { if (null != file) { file.Dispose(); } } } } } finally { if (null != stream) { stream.Dispose(); } } }
/// <summary> /// Get information of all the single cmp files. /// </summary> /// <param name="savingEnv">Working environment.</param> private static void GetCmpInfoDict(SavingEnv savingEnv) { for (int i = 0; i < savingEnv.SentPaths.Count; i++) { string sentID = savingEnv.SentIDs[i]; string partialPath = savingEnv.SentPaths[i]; FileStream file = File.Open(FormCmpFullPath(savingEnv.WorkingPath, partialPath), FileMode.Open); try { using (BinaryReader reader = new BinaryReader(file)) { file = null; int sampleCount = reader.ReadInt32(); // number of samples in file SingleCmpInfo singleCmpInfo = new SingleCmpInfo(); singleCmpInfo.SentID = sentID; singleCmpInfo.SampleCount = sampleCount; savingEnv.CmpInfoDict.Add(sentID, singleCmpInfo); } } finally { if (null != file) { file.Dispose(); } } } }
/// <summary> /// Parse sentence IDs and paths. /// </summary> /// <param name="savingEnv">Working environment.</param> private static void ParseSentPaths(SavingEnv savingEnv) { using (StreamReader reader = new StreamReader(savingEnv.FileMapName)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); string[] tokens = line.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length == 2) { string id = tokens[0]; string path = tokens[1]; if (System.IO.File.Exists(FormCmpFullPath(savingEnv.WorkingPath, path))) { savingEnv.SentIDs.Add(id); savingEnv.SentPaths.Add(path); } } } } }
/// <summary> /// Get general information of the cmp set. /// </summary> /// <param name="savingEnv">Working environment.</param> /// <param name="cmpSetInfo">Information of the cmp set.</param> private static void GetCmpSetInfo(SavingEnv savingEnv, ref CmpSetInfo cmpSetInfo) { cmpSetInfo.SentenceCount = savingEnv.SentIDs.Count; if (cmpSetInfo.SentenceCount > 0) { FileStream file = File.Open(FormCmpFullPath(savingEnv.WorkingPath, savingEnv.SentPaths[0]), FileMode.Open); try { using (BinaryReader reader = new BinaryReader(file)) { file = null; reader.BaseStream.Seek(sizeof(int), SeekOrigin.Begin); // number of samples in file int samplePeriod = reader.ReadInt32(); // sample period in 100ns units cmpSetInfo.SamplePeriod = samplePeriod / 10000; // make it in milliseconds short sampleSize = reader.ReadInt16(); // number of bytes per sample cmpSetInfo.RecordSize = sampleSize; int gainAndF0Order = 2; int mbeOrder = cmpSetInfo.MbeOrder; int powerOrder = cmpSetInfo.PowerOrder; int guidanceLspOrder = cmpSetInfo.GuidanceLspOrder; int placeHolder = gainAndF0Order + mbeOrder + powerOrder + guidanceLspOrder; cmpSetInfo.LspOrder = (sampleSize / (3 * sizeof(float))) - placeHolder; } } finally { if (null != file) { file.Dispose(); } } } }
/// <summary> /// Compile an all-in-one cmp set file from a set of separate cmp files. /// </summary> /// <param name="workingPath">Working path.</param> /// <param name="fileMapName">File map name.</param> /// <param name="resultCmpFile">Name of the all-in-one cmp file.</param> /// <param name="cmpSetInfo">Information of the cmp set.</param> /// <returns>Success or failure.</returns> public static bool CompileCmpFiles(string workingPath, string fileMapName, string resultCmpFile, ref CmpSetInfo cmpSetInfo) { SavingEnv savingEnv = new SavingEnv(); savingEnv.WorkingPath = workingPath; savingEnv.FileMapName = fileMapName; savingEnv.ResultCmpFile = resultCmpFile; ParseSentPaths(savingEnv); GetCmpSetInfo(savingEnv, ref cmpSetInfo); GetCmpInfoDict(savingEnv); SaveAllInOneFile(savingEnv, cmpSetInfo); return true; }