void audioRefreshTimer_Tick(Object sender, EventArgs e) { restartaudio: double actualDelay = 0.04; if (!videoDecoder.HasVideo) { updateObservableVariables(); } // returns null when framequeue is paused or closed VideoLib.AudioFrame audioFrame = videoDecoder.FrameQueue.getDecodedAudioFrame(); if (audioFrame == null) { // stop audio if playing audioPlayer.stop(); if (VideoState == VideoState.CLOSED) { audioPlayer.flush(); return; } // when paused spin idle } else { if (audioPlayer.Status == SharpDX.DirectSound.BufferStatus.None) { // reset audio frame timer before (re)starting playing audioFrameTimer = videoFrameTimer = HRTimer.getTimestamp(); } audioPts = audioFrame.Pts; audioDts = audioFrame.Dts; // if the audio is lagging behind too much, skip the buffer completely double diff = getVideoClock() - audioFrame.Pts; if (diff > 0.2 && diff < 3 && syncMode == SyncMode.AUDIO_SYNCS_TO_VIDEO) { //log.Warn("dropping audio buffer, lagging behind: " + (getVideoClock() - audioFrame.Pts).ToString() + " seconds"); goto restartaudio; } //adjustAudioSamplesPerSecond(audioFrame); adjustAudioLength(audioFrame); audioPlayer.play(audioFrame); int frameLength = audioFrame.Length; actualDelay = synchronizeAudio(frameLength); if (actualDelay < 0) { // delay too small, play next frame as quickly as possible goto restartaudio; } } // start timer with delay for next frame audioRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5); audioRefreshTimer.start(); }