现在的位置: 首页 > 综合 > 正文

DirectSound

2013年07月21日 ⁄ 综合 ⁄ 共 1706字 ⁄ 字号 评论关闭

今天把试了下DirectSound,说实话,用起来还没有PlaySound()方便。但功能却要强得多。

要使用这个组件,首先要用DirectSoundCreate8创建一个LPDIRECTSOUND8对象;

	LPDIRECTSOUND8 m_sound;
	HRESULT hr;

	hr = DirectSoundCreate8(NULL, &m_sound, NULL);
	if (FAILED(hr))
	{
		return FALSE;
	}

然后跟之前所说的DirectInput一样要设置协议。

	hr = m_sound->SetCooperativeLevel(m_hwnd, DSSCL_NORMAL);

	if (FAILED(hr))
	{
		return FALSE;
	}

有了协议之后就只需要创建一个缓冲区来缓冲我们的wav文件,不过很多书上说什么主缓冲区和次缓冲区。龙儿我也不管那么多了。我就创一个缓冲区。

不过在之前要知道怎么读取wav文件。龙儿提供一个完整的读取wav文件的函数

BYTE* Dsound::LoadWaveFile(LPSTR filename, DWORD* length)
{
	HMMIO file = mmioOpenA(filename, NULL, MMIO_READ);

	if (file == NULL)
	{
		return NULL;
	}

	char ch[4];
	mmioSeek(file, 8L, SEEK_SET);
	mmioRead(file, ch, 4L);

	if (ch[0] != 'W' || ch[1] != 'A' || ch[2] != 'V' || ch[3] != 'E')
	{
		mmioClose(file, 0);
		return NULL;
	}

	
	mmioSeek(file, 20L, SEEK_SET);
	mmioRead(file, HPSTR(&m_fmt), sizeof(WAVEFORMATEX));

	DWORD len;
	mmioSeek(file, 40L, SEEK_SET);
	mmioRead(file, (char*)&len, sizeof(DWORD));
	(*length) = len;

	BYTE* data;
	data = new BYTE[len];
	mmioSeek(file, 44L, SEEK_SET);
	mmioRead(file, (char*)data, LONG(len));

	mmioClose(file, 0);
	return data;
}

其中m_fmt是一个WAVEFORMATEX结构体,将会在接下来的创建缓冲区的时候用到。

创建缓冲区说白了就是真充两个结构体。一个DSBUFFERDESC,还有一个WAVEFORMATEX已经在文件中读取到了。简单吧。。。

	DSBUFFERDESC desc;
	ZeroMemory(&desc, sizeof(desc));
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC;
	desc.dwBufferBytes = length;
	desc.lpwfxFormat = &m_fmt;
	hr = m_sound->CreateSoundBuffer(&desc, &lpbuffer, NULL);
	if (FAILED(hr))
	{
		return FALSE;
	}

缓冲区创建后,就只剩锁定你所创建的缓冲区然后把你从wav文件中读取出来的数据写入缓冲区就行了。

	LPVOID lpvPtr;
	DWORD dwByte;

	lpbuffer->Lock(0, 0, &lpvPtr, &dwByte, NULL, NULL, DSBLOCK_ENTIREBUFFER);
	memcpy(lpvPtr, m_data, dwByte);
	lpbuffer->Unlock(lpvPtr, dwByte, NULL, 0);

终于万事俱备,只欠东风了。就差一个play了。

	lpbuffer->SetCurrentPosition(0);
	lpbuffer->Play(0, 0, DSBPLAY_LOOPING);

然后就听一下音乐享受一下自己的成果吧。

龙儿顺便提供一个这几讲的源码吧。

抱歉!评论已关闭.