/// <summary> /// Read macros in the MMF file. /// </summary> /// <param name="filePath">MMF file.</param> /// <returns>Macros.</returns> private static IEnumerable<Macro> Macros(string filePath) { Helper.ThrowIfNull(filePath); using (HmmReader reader = new HmmReader(filePath)) { for (char macroType = ' '; reader.ReadNextMacro(out macroType);) { Macro macro = new Macro() { Type = macroType, Reader = reader }; yield return macro; if (macroType == 'h') { break; } } } }
/// <summary> /// Get state distribution and physical HMM model mapping [Key = "state name", Value = "HMM names"]. /// </summary> /// <param name="fileName">Binary HMM model file.</param> /// <param name="stateTag">Tag indicating which model mapping to get.</param> /// <returns>The state distribution->model mapping.</returns> public static Dictionary<string, Collection<string>> GetStateAndHmmMapping(string fileName, string stateTag) { Helper.ThrowIfNull(fileName); Helper.ThrowIfNull(stateTag); Dictionary<string, Collection<string>> mapping = new Dictionary<string, Collection<string>>(); using (HmmReader hr = new HmmReader(fileName)) { bool isHmmPart = false; string hmmName = string.Empty; char macroType = ' '; while (hr.ReadNextMacro(out macroType)) { if (macroType.Equals('p') || macroType.Equals('s')) { string state = hr.ReadString(); if (isHmmPart) { if (mapping.ContainsKey(state)) { mapping[state].Add(hmmName); } } else { // check whether it's the required type if (state.Contains(stateTag)) { mapping.Add(state, new Collection<string>()); } // Don't skip reading the Gaussian distribution!! hr.ReadGaussian(); } } else if (macroType.Equals('t')) { if (!isHmmPart) { hr.ReadTransMatrix(); } } else if (macroType.Equals('h')) { hmmName = hr.ReadString(); if (!isHmmPart) { isHmmPart = true; } } else if (macroType == 'v') { hr.ReadVariance(); } } } return mapping; }
/// <summary> /// Get physical HMM and state distribution model mapping [Key = "HMM name", /// Value = "model names". First dimension is state, second dimension is stream]. /// </summary> /// <param name="mmfFileName">Binary HMM model file.</param> /// <returns>The model->state distribution mapping.</returns> public static Dictionary<string, string[,]> GetHmmAndStateMapping(string mmfFileName) { Helper.ThrowIfNull(mmfFileName); Dictionary<string, Collection<string>> hmmModels = new Dictionary<string, Collection<string>>(); int streamNumber = -1; using (HmmReader hr = new HmmReader(mmfFileName)) { bool isHmmPart = false; string hmmName = string.Empty; char macroType = ' '; while (hr.ReadNextMacro(out macroType)) { if (macroType.Equals('p') || macroType.Equals('s')) { string state = hr.ReadString(); if (isHmmPart) { Debug.Assert(hmmModels.ContainsKey(hmmName)); hmmModels[hmmName].Add(state); } else { // Don't skip reading the Gaussian distribution!! hr.ReadGaussian(); } } else if (macroType.Equals('t')) { if (!isHmmPart) { hr.ReadTransMatrix(); } } else if (macroType.Equals('h')) { hmmName = hr.ReadString(); if (!hmmModels.ContainsKey(hmmName)) { hmmModels.Add(hmmName, new Collection<string>()); } if (!isHmmPart) { isHmmPart = true; } } else if (macroType.Equals('o')) { HmmSymbol symbol = hr.ReadNextSymbol(); Debug.Assert(symbol == HmmSymbol.StreamInfo); short[] mmfStreamWidths = hr.ReadInt16Array(); streamNumber = mmfStreamWidths.Length; } else if (macroType == 'v') { hr.ReadVariance(); } } } Dictionary<string, string[,]> model2Streams = new Dictionary<string, string[,]>(); foreach (KeyValuePair<string, Collection<string>> pair in hmmModels) { Debug.Assert(pair.Value.Count % streamNumber == 0); int stateNumber = pair.Value.Count / streamNumber; string[,] streams = new string[stateNumber, streamNumber]; for (int i = 0; i < stateNumber; ++i) { for (int j = 0; j < streamNumber; ++j) { streams[i, j] = pair.Value[(i * streamNumber) + j]; } } model2Streams.Add(pair.Key, streams); } return model2Streams; }
/// <summary> /// Get Gaussians width information. /// </summary> /// <param name="hmr">Model reader.</param> /// <param name="streamIndexes">Stream indexes.</param> /// <returns>Stream Widths.</returns> public static int[] ReadStreamWidths(HmmReader hmr, int[] streamIndexes) { Helper.ThrowIfNull(hmr); Helper.ThrowIfNull(streamIndexes); HmmSymbol symbol = hmr.ReadNextSymbol(); Debug.Assert(symbol == HmmSymbol.StreamInfo); short[] mmfStreamWidths = hmr.ReadInt16Array(); Debug.Assert(streamIndexes.Length <= mmfStreamWidths.Length); int[] streamWidths = new int[streamIndexes.Length]; for (int i = 0; i < streamIndexes.Length; i++) { streamWidths[i] = mmfStreamWidths[streamIndexes[i] - 1]; // To 0 based index } if (hmr.ReadNextSymbol() == HmmSymbol.MSDINFO) { hmr.ReadInt16Array(); } return streamWidths; }