Problem with waveOutWrite and waveOutGetPosition deadlock

后端 未结 3 1829
囚心锁ツ
囚心锁ツ 2021-01-22 15:05

I\'m working on an app that plays audio continuously using the waveOut... API from winmm.dll. The app uses \"leapfrog\" buffers, which are basically a

3条回答
  •  情深已故
    2021-01-22 15:26

    It deadlocks inside the mmsys API code. Calling waveOutGetPosition() inside the callback deadlocks when the main thread is busy executing waveOutWrite(). It is fixable, you'll need a lock so these two functions cannot execute at the same time. Add this field to LeapFrogPlayer:

        private object mLocker = new object();
    

    And use it in GetElapsedMilliseconds():

            if (!noAPIcall)
            {
              lock (mLocker) {
                ret = WaveOutX.waveOutGetPosition(_hWaveOut, ref _timestruct,
                    _timestructsize);
              }
            }
    

    and HandleWaveCallback():

            // play the next buffer
            lock (mLocker) {
              int ret = WaveOutX.waveOutWrite(_hWaveOut, ref _header[_currentBuffer],
                  Marshal.SizeOf(_header[_currentBuffer]));
              if (ret != WaveOutX.MMSYSERR_NOERROR) {
                throw new Exception("error writing audio");
              }
            }
    

    This might have side-effects, I didn't notice any though. Take a look at the NAudio project.

    Please use Build + Clean the next time you create an uploadable .zip of your project.

提交回复
热议问题