⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsound.cpp

📁 vc写的源程序,是关于游戏类的程序。调用了系统的很多API
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// 释放主声音缓冲区
	if (lpDSBPrimary != NULL)
	{
		lpDSBPrimary->Release();
		lpDSBPrimary = NULL;
	}
	// 释放DirectSound对象
	if (lpDS != NULL)
	{
		lpDS->Release();
		lpDS = NULL;
	}
	// 关闭音效和音乐
	sound_on = music_on = FALSE;
}

int play_sample(SAMPLE *sample, int loop, long pan, long volume)
{
	if (!sound_on)
		return -1;
	int i;
	STATICSOUND *ss;
	for (i = 0; i < MAXSAMPLE; i++)
	{
		ss = &static_buffer[i];
		if (ss->status < 0)
			break;
	}
	if (i >= MAXSAMPLE)
		return -1;
	ss->pos = 0;
	ss->sample = sample;
	ss->pan = pan;
	ss->volume = volume;
	ss->status = loop;
	sample->number = i;
	zero_static_buffer(i);
	if (!static_next_data(ss, 0, SAMPLE_BUFFER_SIZE >> 1))
		return -1;
	ss->lpDSB->SetCurrentPosition(0);
	ss->lpDSB->SetPan(ss->pan);
	ss->lpDSB->SetVolume(ss->volume);
	if (ss->lpDSB->Play(0, 0, DSBPLAY_LOOPING) != DS_OK)
		return -1;
	return i;
}

void play_music(MUSIC *music, int loop, long pan, long volume)
{
	if (!music_on)
		return;
	stream_buffer.lpDSB->Stop();
	stream_buffer.status = -1;
	music->pack_offset = music->pos;
	stream_buffer.music = music;
	stream_buffer.pan = pan;
	stream_buffer.volume = volume;
	stream_buffer.status = loop;
	fseek(data_file->fp, music->pos, SEEK_SET);
	if (!stream_next_data(0, MUSIC_BUFFER_SIZE >> 1))
		return;
	stream_buffer.lpDSB->SetCurrentPosition(0);
	stream_buffer.lpDSB->SetPan(stream_buffer.pan);
	stream_buffer.lpDSB->SetVolume(stream_buffer.volume);
	stream_buffer.lpDSB->Play(0, 0, DSBPLAY_LOOPING);
}

BOOL static_next_data(STATICSOUND *ss, DWORD pos, DWORD size)
{
	char *buffer;
	DWORD buffersize, s;
	if (ss->status < 0)
	{   
		// 停止播放
		ss->lpDSB->Stop();
		ss->lpDSB->SetCurrentPosition(0);
		ss->sample = NULL;
		return TRUE;
	}
	if (pos + size > SAMPLE_BUFFER_SIZE)
		return FALSE;
	put_message(ss->lpDSB->Lock(pos, size, (void **)&buffer, &buffersize, NULL, NULL, 0) != DS_OK, 
		"错误,声音缓冲区锁定失败。");
	if (ss->pos + buffersize > ss->sample->size)
	{
		s = ss->sample->size - ss->pos;
		if (ss->status & PLAYLOOP)
		{
			memcpy(buffer, ss->sample->bit + ss->pos, s);
			memcpy(buffer + s, ss->sample->bit, buffersize - s);
			ss->pos = buffersize - s;
		}
		else
		{
			memcpy(buffer, ss->sample->bit + ss->pos, s);
			if (wf.wBitsPerSample == 16)
				FillMemory(buffer + s, buffersize - s, 0);
			else
				FillMemory(buffer + s, buffersize - s, 0x80);
			ss->pos = ss->sample->size;
			if (ss->status == PLAYLOOP)
			{
				ss->lpDSB->Unlock(buffer, buffersize, NULL, 0);
				zero_static_buffer(ss->sample->number);
				ss->pos = 0;
				return TRUE;
			}
			else
				ss->status = -1;   // 播放结束
		}
	}
	else
	{
		memcpy(buffer, ss->sample->bit + ss->pos, buffersize);
		ss->pos += buffersize;
	}
	ss->lpDSB->Unlock(buffer, buffersize, NULL, 0);

	return TRUE;
}

BOOL stream_next_data(int pos, int size)
{
	char *buffer;
	int buffersize, s;

	if (stream_buffer.status < 0)
	{   
		// 停止播放音乐
		stream_buffer.lpDSB->Stop();
		stream_buffer.lpDSB->SetCurrentPosition(0);
		stream_buffer.music = NULL;
		return TRUE;
	}
	put_message(stream_buffer.lpDSB->Lock(pos, size, (void **)&buffer, (DWORD *)&buffersize, NULL, NULL, 0) != DS_OK, 
		"错误,声音流缓冲锁定失败.");
	if (stream_buffer.music->source == MUSIC_IN_FILE)
	{
		if (!fread(buffer, buffersize, 1, stream_buffer.music->fp))
		{
			s = ftell(stream_buffer.music->fp);
			s = size - s;
			if (stream_buffer.status == PLAYLOOP && s < 1)
			{
				stream_buffer.lpDSB->Unlock(buffer, buffersize, NULL, 0);
				zero_stream_buffer();
				fseek(stream_buffer.music->fp, stream_buffer.music->pos, SEEK_SET);
				return TRUE;
			}
			else
			{
				if (s < 1)
				{
					stream_buffer.status = -1;
				}
				else
				{
					fread(buffer, s, 1, stream_buffer.music->fp);
					FillMemory(buffer + s, buffersize - s, 0);
				}
			}
		}
	}
	else if (stream_buffer.music->source == MUSIC_IN_PACKFILE)
	{
		fseek(data_file->fp, stream_buffer.music->pack_offset, SEEK_SET);
		s = stream_buffer.music->size - (stream_buffer.music->pack_offset - stream_buffer.music->pos) + 1;
		if (s < buffersize)
		{
			if (stream_buffer.status == PLAYLOOP && s < 1)
			{
				stream_buffer.lpDSB->Unlock(buffer, buffersize, NULL, 0);
				stream_buffer.music->pack_offset = stream_buffer.music->pos;
				zero_stream_buffer();
				fseek(data_file->fp, stream_buffer.music->pos, SEEK_SET);
				return TRUE;
			}
			else
			{
				if (s < 1)
				{
					stream_buffer.status = -1;
					stream_buffer.music->pack_offset = stream_buffer.music->pos;
				}
				else
				{
					fread(buffer, s, 1, data_file->fp);
					stream_buffer.music->pack_offset += s;
					FillMemory(buffer + s, buffersize - s, 0);
				}
			}
		}
		else
		{
			fread(buffer, buffersize, 1, data_file->fp);
			stream_buffer.music->pack_offset += buffersize;
		}
	}
	stream_buffer.lpDSB->Unlock(buffer, buffersize, NULL, 0);

	return TRUE;
}

DWORD WINAPI DirectSoundThread(LPVOID p)
{
	DWORD i;
	while(TRUE)
	{
		i = MsgWaitForMultipleObjects(MAXSAMPLE * 2 + 2, sound_event, FALSE, INFINITE, 0);
		if (i == MAXSAMPLE * 2)
		{
			if (!stream_next_data(MUSIC_BUFFER_SIZE >> 1, MUSIC_BUFFER_SIZE >> 1))
			{
				stream_buffer.lpDSB->Stop();
				stream_buffer.lpDSB->SetCurrentPosition(0);
				stream_buffer.music = NULL;
				stream_buffer.status = -1;
			}
		}
		else if (i == MAXSAMPLE * 2 + 1)
		{
			if (!stream_next_data(0, MUSIC_BUFFER_SIZE >> 1)) 
			{
				stream_buffer.lpDSB->Stop();
				stream_buffer.lpDSB->SetCurrentPosition(0);
				stream_buffer.music = NULL;
				stream_buffer.status = -1;
			}
		}
		else if (!static_next_data(&static_buffer[i / 2], (i & 1) ? 0 : (SAMPLE_BUFFER_SIZE >> 1), SAMPLE_BUFFER_SIZE >> 1))
		{
			static_buffer[i / 2].lpDSB->Stop();
			static_buffer[i / 2].lpDSB->SetCurrentPosition(0);
			static_buffer[i / 2].sample = NULL;
			static_buffer[i / 2].status = -1;
		}
		Sleep(30);
	}
	return 0;
}

void zero_static_buffer(int i)
{
	char *buffer;
	int buffersize;
	put_message(static_buffer[i].lpDSB->Lock(0, SAMPLE_BUFFER_SIZE, (void **)&buffer, (DWORD *)&buffersize, NULL, NULL, 0) != DS_OK, 
		"错误,静态声音缓冲区锁定失败.");
	ZeroMemory(buffer, SAMPLE_BUFFER_SIZE >> 1);
	static_buffer[i].lpDSB->Unlock(buffer, buffersize, NULL, NULL);
}

void zero_stream_buffer()
{
	char *buffer;
	int buffersize;
	put_message(stream_buffer.lpDSB->Lock(0, MUSIC_BUFFER_SIZE, (void **)&buffer, (DWORD *)&buffersize, NULL, NULL, 0) != DS_OK, 
		"错误,声音流缓冲锁定失败.");
	ZeroMemory(buffer, MUSIC_BUFFER_SIZE);
	stream_buffer.lpDSB->Unlock(buffer, buffersize, NULL, NULL);
}

long set_sample_pan(long pan)
{
	long old = sample_pan;
	if (pan < -10000 || pan > 10000)
		return 0;
	sample_pan = pan;
	return old;
}

long set_sample_volume(long volume)
{
	long old = sample_volume;
	if (volume < -10000 || volume > 10000)
		return 0;
	sample_volume = volume;
	return old;
}

long set_music_pan(long pan)
{
	long old = music_pan;
	if (pan < -10000 || pan > 10000)
		return 0;
	stream_buffer.pan = pan;
	stream_buffer.lpDSB->SetVolume(stream_buffer.volume);
	music_pan = pan;
	return old;
}

long set_music_volume(long volume)
{
	long old = music_volume;
	if (volume < -10000 || volume > 10000)
		return 0;
	stream_buffer.volume = volume;
	stream_buffer.lpDSB->SetVolume(stream_buffer.volume);
	music_volume = volume;
	return old;
}

void set_sample_on()
{
	sound_on = TRUE;
}

void set_sample_off()
{
	sound_on = FALSE;
}

void set_music_on()
{
	music_on = TRUE;
}

void set_music_off()
{
	music_on = FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -