Last active
October 9, 2022 00:02
-
-
Save gekka/5570ad4e6a1ce591906a7f4d3cfcf3c0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pch.h" | |
#include "test.h" | |
#include <objbase.h> | |
#include <initguid.h> | |
#include <mmsystem.h> | |
#include <dsound.h> | |
#pragma comment(lib, "dsound.lib") | |
static BOOL ReadWav(void** ppmem, DWORD* psize, WAVEFORMATEX* pformat); | |
void Test(HWND hwnd) | |
{ | |
void* pwav = NULL; //WAVのデータ格納 | |
DWORD wavsize;//WAVデータの大きさ | |
WAVEFORMATEX format;//WAVのフォーマット | |
if (!ReadWav(&pwav, &wavsize, &format))//再生させたいWAVデータを取得 | |
{ | |
return; | |
} | |
LPDIRECTSOUNDBUFFER buffer = NULL; | |
LPDIRECTSOUNDNOTIFY notify = NULL; | |
LPDIRECTSOUND8 pds = NULL; | |
DirectSoundCreate8(NULL, &pds, NULL); | |
if (pds == NULL) | |
{ | |
goto FINALLY; | |
} | |
if (pds->SetCooperativeLevel(hwnd, DSSCL_NORMAL) != DS_OK) | |
{ | |
goto FINALLY; | |
} | |
DSBUFFERDESC desc;//バッファ定義 | |
memset(&desc, 0, sizeof(desc)); | |
desc.dwSize = sizeof(desc); | |
desc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY; //通知を有効にする | |
desc.dwBufferBytes = wavsize; | |
desc.lpwfxFormat = &format; | |
desc.guid3DAlgorithm = GUID_NULL; | |
//再生バッファ | |
if (pds->CreateSoundBuffer(&desc, &buffer, NULL) != DS_OK) | |
{ | |
goto FINALLY; | |
} | |
//バッファにWAVを書き込み | |
void* pbuff[2]; | |
DWORD sz[2]; | |
buffer->SetCurrentPosition(0); | |
buffer->Lock(0, wavsize, &pbuff[0], &sz[0], &pbuff[1], &sz[1], DSBLOCK_ENTIREBUFFER); | |
memcpy(pbuff[0], pwav, wavsize); | |
buffer->Unlock(pbuff[0], sz[0], pbuff[1], sz[1]); | |
//通知登録用のインターフェースを取得 | |
if (buffer->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)¬ify) != S_OK) | |
{ | |
goto FINALLY; | |
} | |
DSBPOSITIONNOTIFY pos;//通知定義 | |
memset(&pos, 0, sizeof(pos)); | |
pos.dwOffset = DSBPN_OFFSETSTOP;//再生が終わったら通知。 // wavsize - 1; //最後(の一瞬前)まで進んだら通知 | |
pos.hEventNotify = CreateEvent(NULL, TRUE, FALSE, NULL);//通知に使うイベントを用意 | |
if (notify->SetNotificationPositions(1, &pos) != DS_OK)//通知されるように登録 | |
{ | |
goto FINALLY; | |
} | |
if (buffer->Play(0, 0, 0) != DS_OK)//一回だけ再生 | |
{ | |
goto FINALLY; | |
} | |
while (WaitForSingleObject(pos.hEventNotify, 100) == WAIT_TIMEOUT) | |
{//最後まで再生されたらイベントがTrueになるので、それまで待つ | |
} | |
FINALLY: | |
if (pos.hEventNotify != 0) { CloseHandle(pos.hEventNotify); } | |
if (notify != NULL) { notify->Release(); } | |
if (buffer != NULL) { buffer->Release(); } | |
if (pds != NULL) { pds->Release(); } | |
if (pwav != NULL) { free(pwav); } | |
} | |
BOOL ReadWav(void** ppmem, DWORD* psize, WAVEFORMATEX* pformat) | |
{ | |
*ppmem = NULL; | |
*psize = 0; | |
HANDLE hFile = 0; | |
hFile = CreateFile(WAVFILEPATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |
if (hFile == 0) | |
{ | |
return FALSE; | |
} | |
DWORD read = 0; | |
DWORD sizeH; | |
DWORD sizeL; | |
sizeL = GetFileSize(hFile, &sizeH); | |
if (sizeH) | |
{//大きすぎ | |
return FALSE; | |
} | |
if (sizeL == 0) | |
{//データなし | |
return FALSE; | |
} | |
void* pmem; | |
pmem = malloc(sizeL); | |
ReadFile(hFile, pmem, sizeL, &read, NULL); | |
CloseHandle(hFile); hFile = NULL; | |
if (sizeL != read) | |
{ | |
free(pmem); | |
return FALSE; | |
} | |
*psize = sizeL; | |
*ppmem = pmem; | |
//面倒なので固定値 | |
pformat->cbSize = sizeof(WAVEFORMATEX); | |
pformat->wFormatTag = WAVE_FORMAT_PCM; | |
pformat->nChannels = 2; | |
pformat->nSamplesPerSec = 44100; | |
pformat->wBitsPerSample = 16; | |
pformat->nBlockAlign = (pformat->wBitsPerSample / 8) * pformat->nChannels; | |
pformat->nAvgBytesPerSec = pformat->nBlockAlign * pformat->nSamplesPerSec; | |
return TRUE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pch.h" | |
#include "test.h" | |
#include <objbase.h> | |
#include <initguid.h> | |
#include <mmsystem.h> | |
#include <dsound.h> | |
#pragma comment(lib, "dsound.lib") | |
typedef struct | |
{ | |
HWND hwnd; | |
HANDLE waitHandle; | |
} STEMP; | |
LPDIRECTSOUNDBUFFER buffer = NULL; | |
LPDIRECTSOUND8 pds = NULL; | |
static BOOL ReadWav(void** ppmem, DWORD* psize, WAVEFORMATEX* pformat); | |
static DWORD WINAPI WaitPlay(void* arg); | |
void Test(HWND hwnd) | |
{ | |
void* pwav = NULL; //WAVのデータ格納 | |
DWORD wavsize;//WAVデータの大きさ | |
WAVEFORMATEX format;//WAVのフォーマット | |
if (!ReadWav(&pwav, &wavsize, &format))//再生させたいWAVデータを取得 | |
{ | |
return; | |
} | |
LPDIRECTSOUNDNOTIFY notify = NULL; | |
DirectSoundCreate8(NULL, &pds, NULL); | |
if (pds == NULL) | |
{ | |
goto FINALLY; | |
} | |
if (pds->SetCooperativeLevel(hwnd, DSSCL_NORMAL) != DS_OK) | |
{ | |
goto FINALLY; | |
} | |
DSBUFFERDESC desc;//バッファ定義 | |
memset(&desc, 0, sizeof(desc)); | |
desc.dwSize = sizeof(desc); | |
desc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY; //通知を有効にする | |
desc.dwBufferBytes = wavsize; | |
desc.lpwfxFormat = &format; | |
desc.guid3DAlgorithm = GUID_NULL; | |
//再生バッファ | |
if (pds->CreateSoundBuffer(&desc, &buffer, NULL) != DS_OK) | |
{ | |
goto FINALLY; | |
} | |
//バッファにWAVを書き込み | |
void* pbuff[2]; | |
DWORD sz[2]; | |
buffer->SetCurrentPosition(0); | |
buffer->Lock(0, wavsize, &pbuff[0], &sz[0], &pbuff[1], &sz[1], DSBLOCK_ENTIREBUFFER); | |
memcpy(pbuff[0], pwav, wavsize); | |
buffer->Unlock(pbuff[0], sz[0], pbuff[1], sz[1]); | |
//通知登録用のインターフェースを取得 | |
if (buffer->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)¬ify) != S_OK) | |
{ | |
goto FINALLY; | |
} | |
DSBPOSITIONNOTIFY pos;//通知定義 | |
memset(&pos, 0, sizeof(pos)); | |
pos.dwOffset = DSBPN_OFFSETSTOP;//再生が終わったら通知。 // wavsize - 1; //最後(の一瞬前)まで進んだら通知 | |
//pos.dwOffset = wavsize - 1; | |
pos.hEventNotify = CreateEvent(NULL, TRUE, FALSE, NULL);//通知に使うイベントを用意 | |
if (notify->SetNotificationPositions(1, &pos) != DS_OK)//通知されるように登録 | |
{ | |
goto FINALLY; | |
} | |
if (buffer->Play(0, 0, 0) != DS_OK)//一回だけ再生 | |
{ | |
goto FINALLY; | |
} | |
//while (WaitForSingleObject(pos.hEventNotify, 100) == WAIT_TIMEOUT) | |
//{//最後まで再生されたらイベントがTrueになるので、それまで待つ | |
//} | |
//typedef struct | |
//{ | |
// HWND hwnd; | |
// HANDLE waitHandle; | |
//} STEMP; | |
STEMP* ptemp; | |
ptemp = (STEMP*)malloc(sizeof(STEMP)); | |
ptemp->hwnd = hwnd; | |
ptemp->waitHandle = pos.hEventNotify; | |
if (NULL == CreateThread(NULL, 0, WaitPlay, (void*)ptemp, 0, NULL))//スレッドを作る | |
{ | |
CloseHandle(pos.hEventNotify); | |
buffer->Release(); | |
pds->Release(); | |
} | |
FINALLY: | |
//if (pos.hEventNotify != 0) { CloseHandle(pos.hEventNotify); } | |
if (notify != NULL) { notify->Release(); } | |
//if (buffer != NULL) { buffer->Release(); } | |
//if (pds != NULL) { pds->Release(); } | |
if (pwav != NULL) { free(pwav); } | |
} | |
DWORD WINAPI WaitPlay(void* arg) | |
{ | |
STEMP temp = *(STEMP*)arg; | |
free(arg); | |
while (WaitForSingleObject(temp.waitHandle, 100) == WAIT_TIMEOUT) //スレッドで待つ | |
{//最後まで再生されたらイベントがTrueになるので、それまで待つ | |
} | |
CloseHandle(temp.waitHandle); | |
if (buffer != NULL) { buffer->Release(); } | |
if (pds != NULL) { pds->Release(); } | |
PostMessage(temp.hwnd, WM_COMMAND, MESSAGE_ID , 0); | |
return 0; | |
} | |
BOOL ReadWav(void** ppmem, DWORD* psize, WAVEFORMATEX* pformat) | |
{ | |
*ppmem = NULL; | |
*psize = 0; | |
HANDLE hFile = 0; | |
hFile = CreateFile(WAVFILEPATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |
if (hFile == 0) | |
{ | |
return FALSE; | |
} | |
DWORD read = 0; | |
DWORD sizeH; | |
DWORD sizeL; | |
sizeL = GetFileSize(hFile, &sizeH); | |
if (sizeH) | |
{//大きすぎ | |
return FALSE; | |
} | |
if (sizeL == 0) | |
{//データなし | |
return FALSE; | |
} | |
void* pmem; | |
pmem = malloc(sizeL); | |
ReadFile(hFile, pmem, sizeL, &read, NULL); | |
CloseHandle(hFile); hFile = NULL; | |
if (sizeL != read) | |
{ | |
free(pmem); | |
return FALSE; | |
} | |
*psize = sizeL; | |
*ppmem = pmem; | |
//面倒なので固定値 | |
pformat->cbSize = sizeof(WAVEFORMATEX); | |
pformat->wFormatTag = WAVE_FORMAT_PCM; | |
pformat->nChannels = 2; | |
pformat->nSamplesPerSec = 44100; | |
pformat->wBitsPerSample = 16; | |
pformat->nBlockAlign = (pformat->wBitsPerSample / 8) * pformat->nChannels; | |
pformat->nAvgBytesPerSec = pformat->nBlockAlign * pformat->nSamplesPerSec; | |
return TRUE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment