namespace QuikDawEditor; public partial class ProjectPlayer { MicroTimer projPlayTimer; float[] sendFloats; public double ProcessingRateMs; ////An even numbered Rate for 44.1k //public double ProcessingRateMs = 20; //Timer (cycle) passes //internal int blockSize = 441; (220.5) ////...nearly all other hosts process blocks with a constant size of 2^n samples like 64, 128, 256, 512 internal int blockSize = 288; // ProcessingRateMs => 13.0612244898D; //internal int blockSize = 256; // ProcessingRateMs => 11.6099xxx; //internal int blockSize = 340; // ProcessingRateMs => 15.419501133786849D; //private double CalculateProcessingRate => (double)sendFloats.Length / 44.1 / 4D; private double CalculateProcessingRate => (double)sendFloats.Length / 44.1 / 2D; internal void CreateTimer() { //sendFloats = new float[blockSize * 8]; sendFloats = new float[blockSize * 4]; ProcessingRateMs = CalculateProcessingRate; projPlayTimer = new MicroTimer((long)ProcessingRateMs * 1000); projPlayTimer.MicroTimerElapsed += projPlayTimer_MicroTimerElapsed; SendLocalMessage("Processing RateMs=" + ProcessingRateMs); } //internal bool StopAntiClickOn = false; private void projPlayTimer_MicroTimerElapsed(object sender, MicroTimerEventArgs timerEventArgs) { try { if (IsProjectPlaying) CurrentPlayingPosMS += ProcessingRateMs; //Keep reading even if play is stopped (allow midi input to be heard) try { int readcount = mmsp.Read(sendFloats, 0, sendFloats.Length); bufferedSampleProvider.AddSamples(sendFloats, 0, readcount); } catch { } if (IsMidiArmed) if (editingProject.GetRecordingTrack != null) foreach (ActiveVstPlugin avp in editingProject.GetRecordingTrack.TrackInstrumentVsts.Where(vsti => vsti.IsActive)) { avp.myContext.PluginCommandStub.Commands.ProcessEvents(avp.midEventsToSend.ToArray()); //this line causes error and app exit avp.midEventsToSend.Clear(); } } catch (Exception ex ) { Debug.WriteLine("Error in microtimer:\n" + ex.Message); } } }