/// <summary> /// Reads one HMM stream instance from text reader instance. /// </summary> /// <param name="rewinder">The text reader to read stream from.</param> /// <returns>HMM stream instance loaded.</returns> private static HmmStream ReadStream(RewindableTextReader rewinder) { Helper.ThrowIfNull(rewinder); HmmStream stream = new HmmStream(); string line = rewinder.PeekLine(); int streamIndex = 0; if (line.StartsWith("<STREAM>")) { streamIndex = ParseTagValue(rewinder.ReadLine(), "<STREAM>"); } int mixtureNumber = 1; line = rewinder.PeekLine(); if (line.StartsWith("<NUMMIXES>")) { mixtureNumber = ParseTagValue(rewinder.ReadLine(), "<NUMMIXES>"); } List<Gaussian> gaussians = new List<Gaussian>(); for (int i = 0; i < mixtureNumber; i++) { int mixtureIndex = 0; float weight = 0.0f; line = rewinder.PeekLine(); if (line.StartsWith("<MIXTURE>")) { string[] values = ParseTagValues(rewinder.ReadLine(), "<MIXTURE>"); mixtureIndex = int.Parse(values[0], CultureInfo.InvariantCulture); weight = float.Parse(values[1], CultureInfo.InvariantCulture); if (mixtureIndex != i + 1) { throw new InvalidDataException( Helper.NeutralFormat("The mixture index is mis-matched between {0} and {1} in line [{2}]", i, mixtureIndex, line)); } } Gaussian gaussian = ReadGaussian(rewinder); gaussian.Weight = weight; gaussians.Add(gaussian); } stream.Gaussians = gaussians.ToArray(); return stream; }
/// <summary> /// Converts the HMM stream instance into string in MMF format. /// </summary> /// <param name="stream">The stream instance to convert.</param> /// <returns>Stream instance in string format.</returns> private static string ToString(HmmStream stream) { Helper.ThrowIfNull(stream); StringBuilder builder = new StringBuilder(); if (stream.Gaussians.Length > 1) { builder.AppendFormat(CultureInfo.InvariantCulture, "<NUMMIXES> {1}{0}", Environment.NewLine, stream.Gaussians.Length); } for (int i = 0; i < stream.Gaussians.Length; i++) { if (stream.Gaussians.Length > 1) { builder.AppendFormat(CultureInfo.InvariantCulture, "<MIXTURE> {1} {2:e6}{0}", Environment.NewLine, i + 1, stream.Gaussians[i].Weight); } builder.Append(ToString(stream.Gaussians[i])); } return builder.ToString(); }
/// <summary> /// Tell whether two stream macro name equal with each other. /// It will ignore the compare on intern leaf node index. /// </summary> /// <param name="left">Left.</param> /// <param name="right">Right.</param> /// <returns>True if yes, otherwise false.</returns> public static bool IsNameEqual(HmmStream left, HmmStream right) { Helper.ThrowIfNull(left); Helper.ThrowIfNull(right); return left.PhoneLabel == right.PhoneLabel && left.ModelType == right.ModelType && left.StateIndex == right.StateIndex && left.StreamIndex == right.StreamIndex; }
/// <summary> /// Tell whether two HMM streams equals with each other. /// </summary> /// <param name="left">Left stream object.</param> /// <param name="right">Right stream object.</param> /// <param name="comareData">Flag to indicate whether comparing data in Gaussian distribution.</param> /// <returns>True if equal, otherwise false.</returns> public static bool IsEqual(HmmStream left, HmmStream right, bool comareData) { Helper.ThrowIfNull(left); Helper.ThrowIfNull(right); return (left.Name == null || right.Name == null || IsNameEqual(left, right)) && IsEqual(left.Gaussians, right.Gaussians, comareData); }
/// <summary> /// Prune dimension in HMM Stream. /// </summary> /// <param name="stream">Stream to prune.</param> /// <param name="keepDimension">First dimensions to keep.</param> /// <returns>Pruned stream.</returns> private static HmmStream Prune(HmmStream stream, int keepDimension) { Helper.ThrowIfNull(stream); HmmStream prunedStream = new HmmStream(); prunedStream.Name = stream.Name; prunedStream.Gaussians = new Gaussian[stream.Gaussians.Length]; for (int i = 0; i < stream.Gaussians.Length; i++) { prunedStream.Gaussians[i].Weight = stream.Gaussians[i].Weight; prunedStream.Gaussians[i].Variance = stream.Gaussians[i].Variance; prunedStream.Gaussians[i].Mean = stream.Gaussians[i].Mean.Take(keepDimension).ToArray(); prunedStream.Gaussians[i].Variance = stream.Gaussians[i].Variance.Take(keepDimension).ToArray(); prunedStream.Gaussians[i].Length = Math.Min(keepDimension, stream.Gaussians[i].Length); } return prunedStream; }
/// <summary> /// Get a stream distribution. /// </summary> /// <returns>HMM stream.</returns> public HmmStream ReadStream() { HmmStream hmmStream = new HmmStream(); hmmStream.Name = ReadString(); hmmStream.Gaussians = ReadGaussian(); return hmmStream; }