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(); }