gssound.cpp
来自「网络泡泡被.net管理」· C++ 代码 · 共 364 行
CPP
364 行
// GsSound.cpp: implementation of the CGsSound class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GSLib_Internal.h"
#include <mmsystem.h>
#include <dxerr8.h>
#include <dsound.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGsSound::CGsSound(CGsEngine* pEngine)
{
m_pEngine = pEngine;
m_pDSB = NULL;
m_pDSB_3d = NULL;
m_flag = 0;
m_key_source = "";
ZeroMemory( &m_dsbd, sizeof(DSBUFFERDESC) );
}
VOID CGsSound::Cleanup()
{
m_flag = 0;
m_key_source = "";
SAFE_RELEASE(m_pDSB);
SAFE_RELEASE(m_pDSB_3d);
ZeroMemory( &m_dsbd, sizeof(DSBUFFERDESC) );
}
CGsSound::~CGsSound()
{
std::map<KEY, std::set<CGsSound*> >::iterator it_sm = m_pEngine->m_sound_cache.find(m_key_source);
std::set<CGsSound*>::iterator it_ss;
if(it_sm!=m_pEngine->m_sound_cache.end())
{
it_ss = it_sm->second.find(this);
if(it_ss!=it_sm->second.end())
{
it_sm->second.erase(it_ss);
}
if(it_sm->second.size()==0)
{
m_pEngine->m_sound_cache.erase(it_sm);
}
}
Cleanup();
}
VOID CGsSound::Set3D(float x, float y, float z)
{
if(m_pDSB_3d)
m_pDSB_3d->SetPosition(x,y,z,DS3D_DEFERRED);
}
HRESULT CGsSound::Play()
{
if(m_pDSB==NULL)
return S_OK;
return m_pDSB->Play( 0, 0, 0);//DSBPLAY_LOOPING );
}
HRESULT CGsSound::PlayLoop()
{
if(m_pDSB==NULL)
return S_OK;
return m_pDSB->Play( 0, 0, DSBPLAY_LOOPING );
}
HRESULT CGsSound::Reset()
{
if(m_pDSB==NULL)
return S_OK;
return m_pDSB->SetCurrentPosition( 0 );
}
HRESULT CGsSound::SetPos(float pos)
{
if(m_pDSB==NULL)
return S_OK;
return m_pDSB->SetCurrentPosition( ((DWORD)(m_size*pos))&m_size );
}
HRESULT CGsSound::Stop()
{
if(m_pDSB==NULL)
return S_OK;
return m_pDSB->Stop();
}
VOID CGsSound::SetSound(char *szFile)
{
if(szFile==NULL)
return;
}
#pragma pack(push, 1)
struct t_dsb_file_head
{
char str_version[16];
};
#pragma pack(pop)
HRESULT CGsSound::Import(const char *szFile)
{
GSFBUF gsbuf;
// if(NULL!=m_pEngine->GetSourcePtr()->FindSource(KEY(szFile), gsbuf))
// {
// return Import(gsbuf);
// }
if((gsbuf.p_fstream = fopen(szFile, "rb"))==NULL)
return E_FAIL;
gsbuf.pos_begin = 0;
gsbuf.file_size = 0;
if(FAILED(Import(gsbuf)))
{
fclose(gsbuf.p_fstream);
return CreateFromWaveFile(szFile);
}
fclose(gsbuf.p_fstream);
return S_OK;
}
HRESULT CGsSound::Import(GSFBUF &gsbuf)
{
HRESULT hr;
t_dsb_file_head head;
ZeroMemory(&head, sizeof(head));
fseek(gsbuf.p_fstream, gsbuf.pos_begin, SEEK_SET);//>seekg(gsbuf.posBegin);
// gsbuf.pfstream->read((char*)&head, sizeof(head));
fread(&head, sizeof(head), 1, gsbuf.p_fstream);
if(strstr(head.str_version, "GSSB")!=head.str_version)
return E_FAIL;
// gsbuf.pfstream->read((char*)&m_dsbd, sizeof(m_dsbd));
fread(&m_dsbd, sizeof(m_dsbd), 1, gsbuf.p_fstream);
hr = m_pEngine->GetDirectSound()->CreateSoundBuffer( &m_dsbd, &m_pDSB, NULL );
if(FAILED(hr))
return hr;
VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
if( FAILED( hr = m_pDSB->Lock( 0, m_dsbd.dwBufferBytes,
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0L ) ) )
return hr;//DXTRACE_ERR( TEXT("Lock"), hr );
// gsbuf.pfstream->read((char*)pDSLockedBuffer, m_dsbd.dwBufferBytes);
if(m_dsbd.dwBufferBytes!=fread(pDSLockedBuffer, 1, m_dsbd.dwBufferBytes, gsbuf.p_fstream))
{
}
m_pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
m_pDSB->QueryInterface( IID_IDirectSound3DBuffer,
(VOID**)&m_pDSB_3d );
return S_OK;
}
HRESULT CGsSound::CreateFromWaveFile(const char *szFile)
{
HRESULT hr;
t_wave_file wave_file;
wave_file.Open( (char*)szFile, NULL, WAVEFILE_READ );
if( wave_file.GetSize() == 0 )
{
// Wave is blank, so don't create it.
return E_FAIL;
}
// Make the DirectSound buffer the same size as the wav file
DWORD dwDSBufferSize = wave_file.GetSize();
// Create the direct sound buffer, and only request the flags needed
// since each requires some overhead and limits if the buffer can
// be hardware accelerated
ZeroMemory( &m_dsbd, sizeof(DSBUFFERDESC) );
m_dsbd.dwSize = sizeof(DSBUFFERDESC);
m_dsbd.dwBufferBytes = dwDSBufferSize;
if(wave_file.m_pwfx->nChannels > 1 || wave_file.m_pwfx->wFormatTag != WAVE_FORMAT_PCM )
{
m_dsbd.dwFlags = 0;
m_dsbd.guid3DAlgorithm = GUID_NULL;
}
else
{
m_dsbd.dwFlags = DSBCAPS_CTRL3D;
m_dsbd.guid3DAlgorithm = DS3DALG_HRTF_FULL;
}
m_dsbd.lpwfxFormat = wave_file.m_pwfx;
// DirectSound is only guarenteed to play PCM data. Other
// formats may or may not work depending the sound card driver.
hr = m_pEngine->GetDirectSound()->CreateSoundBuffer( &m_dsbd, &m_pDSB, NULL );
if(FAILED(hr))
return hr;
VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
DWORD dwWavDataRead = 0; // Amount of data read from the wav file
if( FAILED( hr = m_pDSB->Lock( 0, m_dsbd.dwBufferBytes,
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0L ) ) )
return hr;//DXTRACE_ERR( TEXT("Lock"), hr );
// Reset the wave file to the beginning
wave_file.ResetFile();
if( FAILED( hr = wave_file.Read( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
&dwWavDataRead ) ) )
return hr;//DXTRACE_ERR( TEXT("Read"), hr );
if( dwWavDataRead == 0 )
{
// Wav is blank, so just fill with silence
FillMemory( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
(BYTE)(wave_file.m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
else if( dwWavDataRead < dwDSLockedBufferSize )
{
// If the wav file was smaller than the DirectSound buffer,
// we need to fill the remainder of the buffer with data
/*
if( bRepeatWavIfBufferLarger )
{
// Reset the file and fill the buffer with wav data
DWORD dwReadSoFar = dwWavDataRead; // From previous call above.
while( dwReadSoFar < dwDSLockedBufferSize )
{
// This will keep reading in until the buffer is full
// for very short files
if( FAILED( hr = wave_file.ResetFile() ) )
return hr;//DXTRACE_ERR( TEXT("ResetFile"), hr );
hr = wave_file.Read( (BYTE*)pDSLockedBuffer + dwReadSoFar,
dwDSLockedBufferSize - dwReadSoFar,
&dwWavDataRead );
if( FAILED(hr) )
return hr;//DXTRACE_ERR( TEXT("Read"), hr );
dwReadSoFar += dwWavDataRead;
}
}
else*/
{
// Don't repeat the wav file, just fill in silence
FillMemory( (BYTE*) pDSLockedBuffer + dwWavDataRead,
dwDSLockedBufferSize - dwWavDataRead,
(BYTE)(wave_file.m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
}
m_pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
m_pDSB->QueryInterface( IID_IDirectSound3DBuffer,
(VOID**)&m_pDSB_3d );
return S_OK;
}
DWORD CGsSound::Export(const char *szFile)
{
// fstream fbuf;
// fbuf.open(szFile, ios::in | ios::out | ios::binary | ios::trunc);
// if(!fbuf)
// return 0;
GSFBUF gsbuf;
if((gsbuf.p_fstream = fopen(szFile, "wb"))==NULL)
return 0;
gsbuf.pos_begin = 0;
gsbuf.file_size = 0;
DWORD ret = Export(gsbuf);
fclose(gsbuf.p_fstream);
return ret;
}
DWORD CGsSound::Export(GSFBUF &gsbuf)
{
DWORD dwWrite = 0;
t_dsb_file_head head;
ZeroMemory(&head, sizeof(head));
strcpy(head.str_version, "GSSB2003a");
// gsbuf.pfstream->seekg(gsbuf.posBegin);
fseek(gsbuf.p_fstream, gsbuf.pos_begin, SEEK_SET );
// gsbuf.pfstream->write((char*)&head, sizeof(head));
dwWrite+=fwrite(&head, sizeof(head), 1, gsbuf.p_fstream);
// gsbuf.pfstream->write((char*)&m_dsbd, sizeof(m_dsbd));
dwWrite+=fwrite(&m_dsbd, sizeof(m_dsbd), 1, gsbuf.p_fstream);
VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
if( FAILED( m_pDSB->Lock( 0, m_dsbd.dwBufferBytes,
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0L ) ) )
return 0;//DXTRACE_ERR( TEXT("Lock"), hr );
// gsbuf.pfstream->write((char*)pDSLockedBuffer, m_dsbd.dwBufferBytes);
dwWrite+=fwrite(pDSLockedBuffer, 1, m_dsbd.dwBufferBytes, gsbuf.p_fstream);
m_pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
return dwWrite;
}
BOOL CGsSound::IsPlaying()
{
if(!m_pDSB)
return false;
DWORD dwStatus;
m_pDSB->GetStatus( &dwStatus );
return (( dwStatus & DSBSTATUS_PLAYING ) != 0);
}
VOID CGsSound::SetReserve()
{
m_flag |= GS_SOUND_RESERVE;
}
BOOL CGsSound::IsFree()
{
if((m_flag & GS_SOUND_RESERVE)==GS_SOUND_RESERVE)
return false;
return !IsPlaying();
}
BOOL CGsSound::SetStreamSource(const char *strSource)
{
Cleanup();
m_key_source = strSource;
GSFILE_INFO* file_info = m_pEngine->FindSource(strSource);
if(file_info)
{
switch(file_info->fft)
{
case GSF_WAV:
if(FAILED(Import(file_info->strFile)))
return FALSE;
break;
default:
return FALSE;
}
}
else
{
if(FAILED(Import(strSource)))
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?