waveOutOpenの引数にコールバックを指定した場合、waveOutProcはスレッドセーフっぽくないんですが。
なんか現在のスレッドの処理に割り込んで呼び出されませんか?
WM_DONEで再びWaveOutWriteしようとするとかなりの割合でスタックが破壊されています。