📄 dsound.cpp
字号:
// 释放主声音缓冲区
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 + -