using System; using System.Diagnostics; using System.Windows; using System.Collections.Generic; using System.Windows.Threading; using FrequencyDetection; using SoundCapture; namespace GuitarNoteNameTutor { /// /// Interaction logic for Window1.xaml /// public partial class Window { private bool IsListenning { get; set; } private static readonly Dictionary HalfNoteSharpNames = new Dictionary { {0, "A"}, {1, "A\u266F"}, {2, "B"}, {3, "C"}, {4, "C\u266F"}, {5, "D"}, {6, "D\u266F"}, {7, "E"}, {8, "F"}, {9, "F\u266F"}, {10, "G"}, {11, "G\u266F"}, }; private static readonly Dictionary HalfNoteFlatNames = new Dictionary { {0, "A"}, {1, "B\u266D"}, {2, "B"}, {3, "C"}, {4, "D\u266D"}, {5, "D"}, {6, "E\u266D"}, {7, "E"}, {8, "F"}, {9, "G\u266D"}, {10, "G"}, {11, "A\u266D"}, }; static readonly double ToneStep = Math.Pow(2, 1.0 / 12); private readonly Random _rand = new Random(); FrequencyInfoSource _frequencyInfoSource; public Window() { InitializeComponent(); //timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(2)}; //timer.Tick += timer_Tick; //timer.Start(); } private void StopListenning() { IsListenning = false; _frequencyInfoSource.FrequencyDetected -= FrequencyInfoSource_FrequencyDetected; _frequencyInfoSource.Stop(); _frequencyInfoSource = null; } private void StartListenning(SoundCaptureDevice device) { IsListenning = true; _frequencyInfoSource = new SoundFrequencyInfoSource(device); _frequencyInfoSource.FrequencyDetected += FrequencyInfoSource_FrequencyDetected; _frequencyInfoSource.Listen(); } void FrequencyInfoSource_FrequencyDetected(object sender, FrequencyDetectedEventArgs e) { if (!Dispatcher.CheckAccess()) { Dispatcher.BeginInvoke( new EventHandler(FrequencyInfoSource_FrequencyDetected), sender, e); } else { if (e.Frequency <= 0) { unknownFreqLabel.Visibility = Visibility.Visible; frequencyLabel.Content = "?"; return; } unknownFreqLabel.Visibility = Visibility.Hidden; NoteFrequency closestNote = FindClosestNote(e.Frequency); label.Content = HalfNoteSharpNames[closestNote.HalfStepsFromA]; frequencyLabel.Content = string.Format("{0:0.0}Hz", e.Frequency); } } private class NoteFrequency { public int HalfStepsFromA; public double Frequency; } private static NoteFrequency FindClosestNote(double frequency) { const double aFrequency = 440.0; const int toneIndexOffsetToPositives = 120; int toneIndex = (int)Math.Round(Math.Log(frequency / aFrequency, ToneStep)); int toneHalfStep = (toneIndexOffsetToPositives + toneIndex) % HalfNoteSharpNames.Count; Debug.WriteLine(string.Format("{0}, {1}", toneIndexOffsetToPositives + toneIndex, (toneIndexOffsetToPositives + toneIndex) / 12 - 7)); NoteFrequency noteFrequency = new NoteFrequency { HalfStepsFromA = toneHalfStep, Frequency = Math.Pow(ToneStep, toneIndex)*aFrequency, }; return noteFrequency; } private DispatcherTimer timer; private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (IsListenning) { StopListenning(); } } private void startButton_Click(object sender, RoutedEventArgs e) { SoundCaptureDevice device = null; SelectDevice form = new SelectDevice {Owner = this}; bool? dialogResponse = form.ShowDialog(); if (dialogResponse.HasValue && dialogResponse == true) { device = form.SelectedDevice; } if (device != null) { label.Content = string.Empty; StartListenning(device); } } } }