I'm trying to build my own Metronome UWP application, here's what i've done so far:
I design a Class that will handle all the desired operations for my app, with a DispatcherTimer
... public MetronomeContructor(int upperNum, int lowerNum, int bpm, System.Uri baseURI, MainPage page, MediaElement mediaTick, MediaElement mediaTock) { UpperNum = upperNum; LowerNum = lowerNum; Bpm = bpm; BaseURI = baseURI; CalculateBpm(Bpm); Page = page; Tick = mediaTick; Tock = mediaTock; DispTimer = new DispatcherTimer(); DispTimer.Tick += new EventHandler<object>(timer_Tick); Tick.AutoPlay = false; Tock.AutoPlay = false; Tick.Source = new Uri(Page.BaseUri, Page.Sounds.Where(X => X.Name == "Tick").FirstOrDefault().AudioFile.ToString()); Tock.Source = new Uri(Page.BaseUri, Page.Sounds.Where(X => X.Name == "Click").FirstOrDefault().AudioFile.ToString()); StartInterval(); } //************************************************************* //Methods public void CalculateBpm(int bpms) { this.TimerMSecs = (1000 * 60) / bpms; } //********************************* //Dispatcher Methods and Events public void StartInterval() { DispTimer.Interval = TimeSpan.FromMilliseconds(TimerMSecs); } async void timer_Tick(object sender, object e) { await Page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { Tick.Play(); }); }
My MainPage look like this:
public sealed partial class MainPage : Page { public ObservableCollection<Sound> Sounds; private MetronomeContructor novo; public MainPage() { this.InitializeComponent(); Sounds = new ObservableCollection<Sound>(); SoundManager.GetAllSounds(Sounds); novo = new MetronomeContructor(4, 4, 120, this.BaseUri, this, MediaElemTick, MediaElemTock); } private void sliderBpm_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) { if (novo != null) { novo.Bpm = (int)sliderBpm.Value; novo.CalculateBpm(novo.Bpm); DisplayTxtBlock.Text = novo.Bpm.ToString(); novo.StartInterval(); } } private void StartButton_Click(object sender, RoutedEventArgs e) { if (novo!=null) { novo.DispTimer.Start(); } } private void StopButton_Click(object sender, RoutedEventArgs e) { if (novo != null) { novo.DispTimer.Stop(); } }
I'm still beggining to implement the functionality, but as a musician i realized that the Dispatcher is not running effectively at a given TimeSpan, so I tried to make it Async operation. Eventhough is not accurate.
I read that with a Dispatcher we only have for sure that will not run before the TimeSpan, but there is the chance it can run after the TimeSpan without control. My question is this a Design issue? Does anyone know an effective Timer in UWP? What can be done to implement a simple metronome that can be effective?
Considerations: I'm building a UWP windows 10 App using VisualStudio 2015 I'm a musician that like's to Code in my free time, any design or code improvement ideias are wellcome. Also English is not my native language. TY