C#でwaveOutをコールバックで動かす

Cでラッパーdllを作ります.

#include "windows.h"

#define DLLEXPORT __declspec(dllexport)

extern "C"
{
	WAVEFORMATEX wfe;
	HWAVEOUT hWaveOut;
	WAVEHDR whdr;
	LPBYTE lpWave;

	DLLEXPORT void __stdcall WaveOutOpen(DWORD hWnd, DWORD SRATE)
	{
		wfe.wFormatTag=WAVE_FORMAT_PCM;
		wfe.nChannels=1;    //モノラル
		wfe.wBitsPerSample=16;    //量子化ビット数
		wfe.nBlockAlign=wfe.nChannels * wfe.wBitsPerSample/8;
		wfe.nSamplesPerSec=SRATE;    //標本化周波数
		wfe.nAvgBytesPerSec=wfe.nSamplesPerSec * wfe.nBlockAlign;
		wfe.cbSize = 0;

		waveOutOpen(&hWaveOut,WAVE_MAPPER,&wfe,hWnd,0,CALLBACK_WINDOW);
		return;
	}

	DLLEXPORT void __stdcall WaveOutWrite(short* data)
	{
		whdr.lpData=(LPSTR)data;
		whdr.dwBufferLength=wfe.nAvgBytesPerSec;
		whdr.dwFlags=WHDR_BEGINLOOP | WHDR_ENDLOOP;
		whdr.dwLoops=1;

		waveOutPrepareHeader(hWaveOut,&whdr,sizeof(WAVEHDR));
		waveOutWrite(hWaveOut,&whdr,sizeof(WAVEHDR));
	}

	DLLEXPORT void __stdcall WaveOutClose()
	{
		waveOutUnprepareHeader(hWaveOut,&whdr,sizeof(WAVEHDR));
		waveOutClose(hWaveOut);
	}
}

C#

		[DllImport("BCI_dll.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern void WaveOutOpen(IntPtr hWnd, uint Fs);

		[DllImport("BCI_dll.dll", CallingConvention = CallingConvention.StdCall)]
		unsafe public static extern void WaveOutWrite(short* data);

		[DllImport("BCI_dll.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern void WaveOutClose();

dllimportして,formクラスに

		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
		protected override void WndProc(ref Message m)
		{
			// Listen for operating system messages.
			switch (m.Msg)
			{
				// The WM_ACTIVATEAPP message occurs when the application
				// becomes the active application or becomes inactive.
				case 0x3BB:
				case 0x3BD:
					WaveOut();
					break;
			}
			base.WndProc(ref m);
		}

		private void button8_Click(object sender, EventArgs e)
		{
			Library.Wave.WaveOutOpen(this.Handle, 1000);
		}
unsafe private void WaveOut()
{
if(ある条件)
{
     			short[] wave_data = new short[44100];
			for (int i = 0; i < 44100; i++)
			{
				wave_data[i] = (short)(30000 * Math.Sin(2 * Math.PI * 440 * i / 44100));
			}
			fixed (short* ptr = &wave_data[0])
			{
				Library.Wave.WaveOutWrite(ptr);
			}
}
else
{
				Library.Wave.WaveOutClose();
}