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);
}
}
}
}