Browse Source

Clean up narator sound logic

Also this provides a helper function for calculating the length of a
sound
pull/986/head
Anders Jenbo 5 years ago
parent
commit
88a715cdcc
  1. 6
      3rdParty/Storm/Source/storm.h
  2. 37
      Source/effects.cpp
  3. 1
      Source/effects.h
  4. 11
      SourceS/soundsample.h
  5. 2
      SourceX/sound.cpp
  6. 54
      SourceX/soundsample.cpp
  7. 66
      SourceX/storm/storm.cpp

6
3rdParty/Storm/Source/storm.h vendored

@ -211,12 +211,6 @@ SNetSendTurn(
BOOL STORMAPI SFileCloseArchive(HANDLE hArchive);
BOOL STORMAPI SFileCloseFile(HANDLE hFile);
BOOL STORMAPI SFileDdaBeginEx(HANDLE hFile, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int pan, int a7);
void SFileFreeChunk();
BOOL STORMAPI SFileDdaDestroy();
BOOL STORMAPI SFileDdaEnd(HANDLE hFile);
BOOL STORMAPI SFileDdaGetPos(HANDLE hFile, DWORD *current, DWORD *end);
BOOL STORMAPI SFileDdaSetVolume(HANDLE hFile, signed int bigvolume, signed int volume);
LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);

37
Source/effects.cpp

@ -11,10 +11,8 @@ DEVILUTION_BEGIN_NAMESPACE
int sfxdelay;
int sfxdnum;
/** A handle to the current sound effect playing. */
HANDLE sghStream;
/** Specifies the sound file and the playback state of the current sound effect. */
TSFX *sgpStreamSFX;
static TSFX *sgpStreamSFX = NULL;
/**
* Monster sound type prefix
@ -1069,11 +1067,10 @@ BOOL effect_is_playing(int nSFX)
void stream_stop()
{
if (sghStream) {
SFileDdaEnd(sghStream);
SFileCloseFile(sghStream);
SFileFreeChunk();
sghStream = NULL;
if (sgpStreamSFX != NULL) {
sgpStreamSFX->pSnd->DSB->Stop();
sound_file_cleanup(sgpStreamSFX->pSnd);
sgpStreamSFX->pSnd = NULL;
sgpStreamSFX = NULL;
}
}
@ -1089,23 +1086,16 @@ static void stream_play(TSFX *pSFX, int lVolume, int lPan)
if (lVolume >= VOLUME_MIN) {
if (lVolume > VOLUME_MAX)
lVolume = VOLUME_MAX;
success = SFileOpenFile(pSFX->pszName, &sghStream);
if (!success) {
sghStream = NULL;
} else {
if (!SFileDdaBeginEx(sghStream, 0x40000, 0, 0, lVolume, lPan, 0))
stream_stop();
else
sgpStreamSFX = pSFX;
}
if (pSFX->pSnd == NULL)
pSFX->pSnd = sound_file_load(pSFX->pszName);
pSFX->pSnd->DSB->Play(lVolume, lPan, 0);
sgpStreamSFX = pSFX;
}
}
static void stream_update()
{
DWORD current, end;
if (sghStream != NULL && SFileDdaGetPos(sghStream, &current, &end) && current >= end) {
if (sgpStreamSFX != NULL && !sgpStreamSFX->pSnd->DSB->IsPlaying()) {
stream_stop();
}
}
@ -1410,4 +1400,11 @@ void effects_play_sound(const char *snd_file)
}
}
int GetSFXLength(int nSFX)
{
if (sgSFX[nSFX].pSnd == NULL)
sgSFX[nSFX].pSnd = sound_file_load(sgSFX[nSFX].pszName);
return sgSFX[nSFX].pSnd->DSB->GetLength();
}
DEVILUTION_END_NAMESPACE

1
Source/effects.h

@ -29,6 +29,7 @@ void effects_cleanup_sfx();
void sound_init();
void ui_sound_init();
void effects_play_sound(const char *snd_file);
int GetSFXLength(int nSFX);
#ifdef __cplusplus
}

11
SourceS/soundsample.h

@ -5,11 +5,12 @@ namespace dvl {
typedef struct SoundSample final {
public:
void Release() ;
bool IsPlaying() ;
void Play(int lVolume, int lPan) ;
void Stop() ;
int SetChunk(BYTE *fileData, DWORD dwBytes) ;
void Release();
bool IsPlaying();
void Play(int lVolume, int lPan, int channel = -1);
void Stop();
int SetChunk(BYTE *fileData, DWORD dwBytes);
int GetLength();
private:
Mix_Chunk *chunk;

2
SourceX/sound.cpp

@ -173,8 +173,6 @@ void snd_init(HWND hWnd)
void sound_cleanup()
{
SFileDdaDestroy();
if (gbSndInited) {
gbSndInited = false;
snd_set_volume("Sound Volume", sglSoundVolume);

54
SourceX/soundsample.cpp

@ -11,9 +11,16 @@ void SoundSample::Release()
Mix_FreeChunk(chunk);
};
/**
* @brief Check if a the sound is being played atm
*/
bool SoundSample::IsPlaying()
{
for (int i = 1; i < Mix_AllocateChannels(-1); i++) {
if (chunk == NULL)
return false;
int channels = Mix_AllocateChannels(-1);
for (int i = 0; i < channels; i++) {
if (Mix_GetChunk(i) == chunk && Mix_Playing(i)) {
return true;
}
@ -22,9 +29,15 @@ bool SoundSample::IsPlaying()
return false;
};
void SoundSample::Play(int lVolume, int lPan)
/**
* @brief Start playing the sound
*/
void SoundSample::Play(int lVolume, int lPan, int channel)
{
int channel = Mix_PlayChannel(-1, chunk, 0);
if (chunk == NULL)
return;
channel = Mix_PlayChannel(channel, chunk, 0);
if (channel == -1) {
SDL_Log("Too few channels, skipping sound");
return;
@ -35,9 +48,16 @@ void SoundSample::Play(int lVolume, int lPan)
Mix_SetPanning(channel, pan > 0 ? pan : 255, pan < 0 ? abs(pan) : 255);
};
/**
* @brief Stop playing the sound
*/
void SoundSample::Stop()
{
for (int i = 1; i < Mix_AllocateChannels(-1); i++) {
if (chunk == NULL)
return;
int channels = Mix_AllocateChannels(-1);
for (int i = 0; i < channels; i++) {
if (Mix_GetChunk(i) != chunk) {
continue;
}
@ -46,6 +66,12 @@ void SoundSample::Stop()
}
};
/**
* @brief This can load WAVE, AIFF, RIFF, OGG, and VOC formats
* @param fileData Buffer containing file data
* @param dwBytes Length of buffer
* @return 0 on success, -1 otherwise
*/
int SoundSample::SetChunk(BYTE *fileData, DWORD dwBytes)
{
SDL_RWops *buf1 = SDL_RWFromConstMem(fileData, dwBytes);
@ -61,4 +87,24 @@ int SoundSample::SetChunk(BYTE *fileData, DWORD dwBytes)
return 0;
};
/**
* @return Audio duration in ms
*/
int SoundSample::GetLength()
{
if (chunk == NULL)
return 0;
int frequency, channels;
Uint16 format;
Mix_QuerySpec(&frequency, &format, &channels);
int bytePerSample = 2;
if (format == AUDIO_U8 || format == AUDIO_S8) {
bytePerSample = 1;
}
return chunk->alen * 1000 / (frequency * channels * bytePerSample);
};
} // namespace dvl

66
SourceX/storm/storm.cpp

@ -40,72 +40,6 @@ radon::File &getIni()
return ini;
}
static Mix_Chunk *SFileChunk = NULL;
BOOL SFileDdaBeginEx(HANDLE hFile, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove,
signed __int32 volume, signed int pan, int a7)
{
DWORD bytestoread = SFileGetFileSize(hFile, 0);
char *SFXbuffer = (char *)malloc(bytestoread);
SFileReadFile(hFile, SFXbuffer, bytestoread, NULL, NULL);
SDL_RWops *rw = SDL_RWFromConstMem(SFXbuffer, bytestoread);
if (rw == NULL) {
SDL_Log(SDL_GetError());
return false;
}
if (SFileChunk) {
SFileDdaEnd(hFile);
SFileFreeChunk();
}
SFileChunk = Mix_LoadWAV_RW(rw, 1);
free(SFXbuffer);
Mix_Volume(0, MIX_MAX_VOLUME - MIX_MAX_VOLUME * volume / VOLUME_MIN);
int panned = 255 - 255 * abs(pan) / 10000;
Mix_SetPanning(0, pan <= 0 ? 255 : panned, pan >= 0 ? 255 : panned);
Mix_PlayChannel(0, SFileChunk, 0);
return true;
}
void SFileFreeChunk()
{
if (SFileChunk) {
Mix_FreeChunk(SFileChunk);
SFileChunk = NULL;
}
}
BOOL SFileDdaDestroy()
{
if (SFileChunk) {
Mix_FreeChunk(SFileChunk);
SFileChunk = NULL;
}
return true;
}
BOOL SFileDdaEnd(HANDLE hFile)
{
Mix_HaltChannel(0);
return true;
}
BOOL SFileDdaGetPos(HANDLE hFile, DWORD *current, DWORD *end)
{
*current = 0;
*end = 1;
if (Mix_GetChunk(0) != SFileChunk || !Mix_Playing(0)) {
*current = *end;
}
return true;
}
BOOL SFileDdaSetVolume(HANDLE hFile, signed int bigvolume, signed int volume)
{
Mix_VolumeMusic(MIX_MAX_VOLUME - MIX_MAX_VOLUME * bigvolume / VOLUME_MIN);

Loading…
Cancel
Save