// Called to switch the instrument to receive mode. Kills the InstrumentWatcherThread, chooses a code for the user to listen to, and starts the thread to play it. private void StartReceiveMode() { InstrumentWatcherThread.Abort(); InstrumentWatcherThread = new Thread(CallAttentionWatcher); lblInstruction.Visible = false; lblResult.Visible = false; ChosenCode = SelectRandomCode(); InstrumentPlayerThread = new Thread(RunCodePlayer); InstrumentPlayerThread.Start(); InstrumentWatcherThread.Start(); }
// Play a code. Should be run in its own thread because it sleeps between bell strokes. private void PlayCode(BellCode code) { foreach (BellGroup group in code.BellGroups) { foreach (BellStroke stroke in group.Bells) { bellPlayer.Stop(); Thread.Sleep(5); // without this pause playback is crackly, with pops between bells. It's still occasionally crackly with it... bellPlayer.Play(); needle.ActiveState = true; Thread.Sleep(stroke == BellStroke.Hold ? 2000 : 125); needle.ActiveState = false; Thread.Sleep(125); } Thread.Sleep(350); } }
// Convert a list of tap events to a bell signal. private void BuildCode() { if (RecentTapEvents.Count < 2) { return; } if (CurrentCode == null) { CurrentCode = new BellCode(); } if (RecentTapEvents.Count == 2 || (RecentTapEvents[RecentTapEvents.Count - 2].Timestamp - RecentTapEvents[RecentTapEvents.Count - 3].Timestamp).TotalSeconds > Properties.Settings.Default.GroupPauseThreshold) { CurrentCode.BellGroups.Add(new BellGroup()); } CurrentCode.BellGroups[CurrentCode.BellGroups.Count - 1].Bells .Add((RecentTapEvents[RecentTapEvents.Count - 1].Timestamp - RecentTapEvents[RecentTapEvents.Count - 2].Timestamp).TotalSeconds > Properties.Settings.Default.HoldDownThreshold ? BellStroke.Hold : BellStroke.Normal); }
// Called to set up sending mode: kill the player thread, start the watcher thread, pick a code and display a belling request. private void StartSendMode() { if (InstrumentPlayerThread != null) { InstrumentPlayerThread.Abort(); InstrumentPlayerThread = null; } if (InstrumentWatcherThread != null) { InstrumentWatcherThread.Abort(); } InstrumentWatcherThread = new Thread(StatusCheckRunner); InstrumentWatcherThread.Start(); comboCodeList.Visible = false; ExpectedCode = SelectRandomCode(); lblInstruction.Text = "Please bell:\n" + ExpectedCode.Name; lblInstruction.Visible = true; RecentTapEvents.Clear(); needle.ActiveState = false; CurrentCode = null; }
private void CallAttentionWatcher() { BellCode callAttention = new BellCode { BellGroups = new List <BellGroup> { new BellGroup { Bells = new List <BellStroke> { BellStroke.Normal } } } }; while (true) { BlockForCodeEnd(); if (CurrentCode != null && CurrentCode == callAttention && InstrumentPlayerThread.ThreadState != ThreadState.Running) { InstrumentPlayerThread = new Thread(RunCodePlayer); InstrumentPlayerThread.Start(); } CurrentCode = new BellCode(); RecentTapEvents.Clear(); } }
/// <summary> /// The method behind the InstrumentWatcherThread. Wakes every half-second to check if the plunger has not been touched for longer than the code-end threshold, and if so, work out if the /// signal sent is the signal requested to be sent then display a new belling request. /// </summary> public void StatusCheckRunner() { while (true) { BlockForCodeEnd(); if (CurrentCode == ExpectedCode) { correctCount++; CorrectUpdateScore(); } else { WrongUpdateScore(InstrumentMode.Send); } Thread.Sleep(2000); doneCount++; CurrentCode = null; ExpectedCode = SelectRandomCode(); RecentTapEvents.Clear(); ResetResultLabel(); } }
public HiddenCode(BellCode realCode) { Code = realCode; }