C语言程序代码:
#include <initguid.h>
#include <dsound.h>
#include <math.h>
#include <tchar.h>
#pragma comment(lib, "dsound.lib")
IDirectSound8 *pds8 = NULL;
IDirectSoundBuffer *pdsbuf = NULL;
IDirectSoundBuffer8 *pdsbuf8 = NULL;
void generate_sound_data(char *mem, int len)
{
char value;
int i;
for (i = 0; i < len; i += 2)
{
value = (char)(sin(i / 20.0) * 127);
mem[i] = value;
mem[i + 1] = value;
}
}
void play_sound(HWND hwnd)
{
void *mem;
DSBUFFERDESC dsbufdesc = {0};
DWORD len;
HRESULT hr;
WAVEFORMATEX wavefmt = {0};
hr = DirectSoundCreate8(NULL, &pds8, NULL);
if (SUCCEEDED(hr))
{
IDirectSound8_SetCooperativeLevel(pds8, hwnd, DSSCL_NORMAL);
dsbufdesc.dwSize = sizeof(DSBUFFERDESC);
dsbufdesc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
dsbufdesc.lpwfxFormat = &wavefmt;
wavefmt.cbSize = sizeof(WAVEFORMATEX);
wavefmt.wFormatTag = WAVE_FORMAT_PCM;
wavefmt.nChannels = 2;
wavefmt.nSamplesPerSec = 8000;
wavefmt.wBitsPerSample = 8;
wavefmt.nBlockAlign = wavefmt.nChannels * wavefmt.wBitsPerSample / 8;
wavefmt.nAvgBytesPerSec = wavefmt.nSamplesPerSec * wavefmt.nBlockAlign;
dsbufdesc.dwBufferBytes = DSBSIZE_FX_MIN * wavefmt.nAvgBytesPerSec;
hr = IDirectSound8_CreateSoundBuffer(pds8, &dsbufdesc, &pdsbuf, NULL);
if (SUCCEEDED(hr))
{
hr = IDirectSoundBuffer_QueryInterface(pdsbuf, &IID_IDirectSoundBuffer8, &pdsbuf8);
if (SUCCEEDED(hr))
{
hr = IDirectSoundBuffer8_Lock(pdsbuf8, 0, 0, &mem, &len, NULL, NULL, DSBLOCK_ENTIREBUFFER);
if (SUCCEEDED(hr))
{
generate_sound_data(mem, len);
IDirectSoundBuffer8_Unlock(pdsbuf8, mem, len, NULL, 0);
mem = NULL;
IDirectSoundBuffer8_SetCurrentPosition(pdsbuf8, 0);
IDirectSoundBuffer8_SetVolume(pdsbuf8, DSBVOLUME_MIN);
//IDirectSoundBuffer8_SetVolume(pdsbuf8, DSBVOLUME_MIN + 8000);
IDirectSoundBuffer8_Play(pdsbuf8, 0, 0, DSBPLAY_LOOPING);
IDirectSoundBuffer8_Stop(pdsbuf8);
}
}
}
}
}
void stop_sound()
{
if (pdsbuf8 != NULL)
{
IDirectSoundBuffer8_Release(pdsbuf8);
pdsbuf8 = NULL;
}
if (pdsbuf != NULL)
{
IDirectSoundBuffer_Release(pdsbuf);
pdsbuf = NULL;
}
if (pds8 != NULL)
{
IDirectSound8_Release(pds8);
pds8 = NULL;
}
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_CREATE:
play_sound(hwnd);
break;
case WM_DESTROY:
stop_sound();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPTSTR cmdline, int cmdshow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wcex.hInstance = instance;
wcex.lpfnWndProc = wnd_proc;
wcex.lpszClassName = TEXT("main_window");
RegisterClassEx(&wcex);
hwnd = CreateWindow(wcex.lpszClassName, TEXT("keep_speaker_alive"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, instance, NULL);
//ShowWindow(hwnd, cmdshow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}