private string TransmitText(string txText, int wpmValue, CancellationToken cancelToken) { try { (List <MorseSymbol> symbols, string outputText) = Morse.GetTimeSequence(txText, wpmValue); this.audioHandler.PlayWaveStream(symbols, cancelToken); return(outputText); } catch (Exception e) { // Add error information to the interface and cancel the transmission. MessageBox.Show( Environment.NewLine + "Problem creating the Morse audio transmission:" + Environment.NewLine + e.Message ); } return(""); }
/// <summary> /// Gets the MorseSymbol sequence (has-sound, timing/spacing, string) /// </summary> /// <param name="wpm"></param> /// <returns></returns> public List <MorseSymbol> GetSequence(int wpm) { /* * Multiply the 'duration' value from each sequence item by the new rate. Ex w/ five WPM: * - DIT = 1.00 * 240 = 240ms * - DAH = 3.00 * 240 = 720ms */ List <MorseSymbol> timeSequence = new List <MorseSymbol>(); foreach (MorseSymbol sym in this.baseSequence) { timeSequence.Add(new MorseSymbol( sym.hasSound(), Math.Round( (double)(sym.getDuration() * Morse.GetWPMFactor(wpm)), 2 ), sym.getRepresentation() )); } return(timeSequence); }
/// <summary> /// Generate a morse time-sequence for the given string (converted to upper-case of course) for the given speed. /// This function is the "core" of the Morse module, to get an audio sequence for the audio handler to deal with. /// </summary> /// <param name="txText">The text to transmit; case-insensitive.</param> /// <param name="wpmSpeed">The WPM speed of the sequence.</param> /// <returns>A list of Morse symbols representing the txText parameter at the given WPM. Audio-player-ready.</returns> /// <seealso cref="MorseSymbol"/> public static (List <MorseSymbol>, string) GetTimeSequence(string txText, int wpmSpeed) { List <MorseSymbol> fullTimeSequence = new List <MorseSymbol>(); StringBuilder outputString = new StringBuilder(); // Trim the provided string and force upper-case. txText = txText.ToUpper().Trim(); // Get all valid prosigns, map their unique positions to a tuple of their (length, symbols [ie '...---'], text). MatchCollection mc = Regex.Matches(txText, "<([^>]+)>"); var matchedProsigns = new Dictionary <int, (int lengthPastIndex, string psSymbolSequence, string psRepresentation)>(); foreach (Match m in mc) { // For each character between the <>, get its symbols (... --- etc) and string them all together via a StringBuilder. var prosignText = new StringBuilder(); foreach (char c in m.Groups[1].Value) { try { MorseSequence seq; Morse.Characters.TryGetValue(c, out seq); if (seq is null) { throw new Exception(); } prosignText.Append(seq.symbolSequence); } catch { throw new Exception("Morse.GetTimeSequence: invalid character in prosign: " + c); } } // Add it to the capture Dictionary. matchedProsigns.Add(m.Groups[0].Index, (m.Groups[0].Length, prosignText.ToString(), m.Groups[1].Value)); } // For each item in the (parsed) text, get the timing information and append the output string. for (int i = 0; i < txText.Length; i++) { // Check if the current index is the location of a known prosign. if (matchedProsigns.ContainsKey(i)) { try { // Get the prosign contents. (int len, string seq, string rep)prosign; matchedProsigns.TryGetValue(i, out prosign); // Set up a new sequence with the full symbol string from an earlier step. var x = new MorseSequence(prosign.seq); if (x == null) { continue; } // For each symbol, add it to the overall sequencer. foreach (MorseSymbol sym in x.GetSequence(wpmSpeed)) { fullTimeSequence.Add(sym); } // Write the prosign contents to the output string as-is. outputString.Append(string.Format("<{0}>", prosign.rep)); // Add a sequence gapping at the end of this "character" (prosigns are considered one character unit). fullTimeSequence.Add(new MorseSymbol(false, Morse.GetWPMFactor(wpmSpeed) * MorseSequence.PER_CHARACTER, " ")); // Increment the index to 'skip over' the rest of the prosign. If this lands on '>', no big deal; it will be skipped. i += (prosign.len - 1); } catch { throw new Exception("Morse.GetTimeSequence: unknown prosign is the TX sequence at position: " + i); } // Forcibly continue. continue; } // If no prosign was detected at the current position, proceed normally. char c = txText[i]; try { MorseSequence morseChar; Morse.Characters.TryGetValue(c, out morseChar); if (morseChar == null) { continue; } // Append all symbols and string representations foreach (MorseSymbol sym in morseChar.GetSequence(wpmSpeed)) { fullTimeSequence.Add(sym); outputString.Append(sym.getRepresentation()); } outputString.Append(string.Format("({0}) ", c.ToString())); //append a space between characters // Add the gap between individual characters fullTimeSequence.Add(new MorseSymbol(false, Morse.GetWPMFactor(wpmSpeed) * MorseSequence.PER_CHARACTER, " ")); } catch { throw new Exception(string.Format("Morse.GetTimeSequence: unknown character \"{0}\" in the TX sequence.", c)); } } // Pop off the last PER_CHARACTER item in the time sequence, as well as the trailing space in the outputString. fullTimeSequence.RemoveAt(fullTimeSequence.Count - 1); outputString.Remove(outputString.Length - 1, 1); // Send back the information. return(fullTimeSequence, outputString.ToString()); }