Browse Source

Respect sfx_STREAM in PlaySFX

Changes audio playback of sounds with the `sfx_STREAM` flag, such as towner lines, to stream.
pull/1205/head
Gleb Mazovetskiy 5 years ago committed by Anders Jenbo
parent
commit
0c2284a091
  1. 2
      Source/effects.cpp
  2. 2
      Source/sound.h
  3. 2
      SourceS/miniwin/misc.h
  4. 5
      SourceS/soundsample.h
  5. 37
      SourceX/sound.cpp
  6. 13
      SourceX/soundsample.cpp
  7. 20
      SourceX/storm_sdl_rw.cpp
  8. 1
      structs.h

2
Source/effects.cpp

@ -1093,7 +1093,7 @@ static void stream_play(TSFX *pSFX, int lVolume, int lPan)
if (lVolume > VOLUME_MAX) if (lVolume > VOLUME_MAX)
lVolume = VOLUME_MAX; lVolume = VOLUME_MAX;
if (pSFX->pSnd == NULL) if (pSFX->pSnd == NULL)
pSFX->pSnd = sound_file_load(pSFX->pszName); pSFX->pSnd = sound_file_load(pSFX->pszName, /*stream=*/true);
pSFX->pSnd->DSB->Play(lVolume, lPan, 0); pSFX->pSnd->DSB->Play(lVolume, lPan, 0);
sgpStreamSFX = pSFX; sgpStreamSFX = pSFX;
} }

2
Source/sound.h

@ -17,7 +17,7 @@ void snd_update(BOOL bStopAll);
void snd_stop_snd(TSnd *pSnd); void snd_stop_snd(TSnd *pSnd);
BOOL snd_playing(TSnd *pSnd); BOOL snd_playing(TSnd *pSnd);
void snd_play_snd(TSnd *pSnd, int lVolume, int lPan); void snd_play_snd(TSnd *pSnd, int lVolume, int lPan);
TSnd *sound_file_load(const char *path); TSnd *sound_file_load(const char *path, bool stream = false);
void sound_file_cleanup(TSnd *sound_file); void sound_file_cleanup(TSnd *sound_file);
void snd_init(); void snd_init();
void sound_cleanup(); void sound_cleanup();

2
SourceS/miniwin/misc.h

@ -66,6 +66,8 @@ bool PostMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
#define DVL_FILE_CURRENT 1 #define DVL_FILE_CURRENT 1
#define DVL_FILE_END 2 #define DVL_FILE_END 2
#define DVL_ERROR_HANDLE_EOF 1002
#define DVL_WM_QUIT 0x0012 #define DVL_WM_QUIT 0x0012
// //

5
SourceS/soundsample.h

@ -3,17 +3,18 @@
namespace dvl { namespace dvl {
typedef struct SoundSample final { class SoundSample final {
public: public:
void Release(); void Release();
bool IsPlaying(); bool IsPlaying();
void Play(int lVolume, int lPan, int channel = -1); void Play(int lVolume, int lPan, int channel = -1);
void Stop(); void Stop();
int SetChunkStream(HANDLE stormHandle);
int SetChunk(BYTE *fileData, DWORD dwBytes); int SetChunk(BYTE *fileData, DWORD dwBytes);
int GetLength(); int GetLength();
private: private:
Mix_Chunk *chunk; Mix_Chunk *chunk;
} SoundSample; };
} // namespace dvl } // namespace dvl

37
SourceX/sound.cpp

@ -94,28 +94,37 @@ void snd_play_snd(TSnd *pSnd, int lVolume, int lPan)
pSnd->start_tc = tc; pSnd->start_tc = tc;
} }
TSnd *sound_file_load(const char *path) TSnd *sound_file_load(const char *path, bool stream)
{ {
HANDLE file; HANDLE file;
BYTE *wave_file;
TSnd *pSnd; TSnd *pSnd;
DWORD dwBytes; int error = 0;
int error;
SFileOpenFile(path, &file); if (!SFileOpenFile(path, &file)) {
ErrDlg("SFileOpenFile failed", path, __FILE__, __LINE__);
return NULL;
}
pSnd = (TSnd *)DiabloAllocPtr(sizeof(TSnd)); pSnd = (TSnd *)DiabloAllocPtr(sizeof(TSnd));
memset(pSnd, 0, sizeof(TSnd)); memset(pSnd, 0, sizeof(TSnd));
pSnd->sound_path = path; pSnd->sound_path = path;
pSnd->start_tc = SDL_GetTicks() - 80 - 1; pSnd->start_tc = SDL_GetTicks() - 80 - 1;
dwBytes = SFileGetFileSize(file, NULL);
wave_file = DiabloAllocPtr(dwBytes);
SFileReadFile(file, wave_file, dwBytes, NULL, NULL);
pSnd->DSB = new SoundSample(); pSnd->DSB = new SoundSample();
error = pSnd->DSB->SetChunk(wave_file, dwBytes);
SFileCloseFile(file); if (stream) {
mem_free_dbg(wave_file); pSnd->file_handle = file;
error = pSnd->DSB->SetChunkStream(file);
if (error != 0) {
SFileCloseFile(file);
ErrSdl();
}
} else {
DWORD dwBytes = SFileGetFileSize(file, NULL);
BYTE *wave_file = DiabloAllocPtr(dwBytes);
SFileReadFile(file, wave_file, dwBytes, NULL, NULL);
error = pSnd->DSB->SetChunk(wave_file, dwBytes);
SFileCloseFile(file);
mem_free_dbg(wave_file);
}
if (error != 0) { if (error != 0) {
ErrSdl(); ErrSdl();
} }
@ -132,6 +141,8 @@ void sound_file_cleanup(TSnd *sound_file)
delete sound_file->DSB; delete sound_file->DSB;
sound_file->DSB = NULL; sound_file->DSB = NULL;
} }
if (sound_file->file_handle != NULL)
SFileCloseFile(sound_file->file_handle);
mem_free_dbg(sound_file); mem_free_dbg(sound_file);
} }

13
SourceX/soundsample.cpp

@ -2,6 +2,8 @@
#include "stubs.h" #include "stubs.h"
#include <SDL.h> #include <SDL.h>
#include "storm_sdl_rw.h"
namespace dvl { namespace dvl {
///// SoundSample ///// ///// SoundSample /////
@ -9,6 +11,7 @@ namespace dvl {
void SoundSample::Release() void SoundSample::Release()
{ {
Mix_FreeChunk(chunk); Mix_FreeChunk(chunk);
chunk = NULL;
}; };
/** /**
@ -66,6 +69,16 @@ void SoundSample::Stop()
} }
}; };
int SoundSample::SetChunkStream(HANDLE stormHandle)
{
chunk = Mix_LoadWAV_RW(SFileRw_FromStormHandle(stormHandle), /*freesrc=*/1);
if (chunk == NULL) {
SDL_Log("Mix_LoadWAV_RW: %s", Mix_GetError());
return -1;
}
return 0;
}
/** /**
* @brief This can load WAVE, AIFF, RIFF, OGG, and VOC formats * @brief This can load WAVE, AIFF, RIFF, OGG, and VOC formats
* @param fileData Buffer containing file data * @param fileData Buffer containing file data

20
SourceX/storm_sdl_rw.cpp

@ -19,10 +19,7 @@ static void SFileRw_SetHandle(struct SDL_RWops *context, HANDLE handle)
#ifndef USE_SDL1 #ifndef USE_SDL1
static Sint64 SFileRw_size(struct SDL_RWops *context) static Sint64 SFileRw_size(struct SDL_RWops *context)
{ {
DWORD result; return SFileGetFileSize(SFileRw_GetHandle(context), NULL);
if (!SFileGetFileSize(SFileRw_GetHandle(context), &result))
return -1;
return result;
} }
#endif #endif
@ -46,7 +43,11 @@ static int SFileRw_seek(struct SDL_RWops *context, int offset, int whence)
default: default:
return -1; return -1;
} }
return SFileSetFilePointer(SFileRw_GetHandle(context), offset, NULL, swhence); DWORD result = SFileSetFilePointer(SFileRw_GetHandle(context), offset, NULL, swhence);
if (result == (DWORD)-1) {
SDL_Log("SFileRw_seek error: %ud", (unsigned int)SErrGetLastError());
}
return result;
} }
#ifndef USE_SDL1 #ifndef USE_SDL1
@ -56,8 +57,13 @@ static int SFileRw_read(struct SDL_RWops *context, void *ptr, int size, int maxn
#endif #endif
{ {
DWORD num_read = 0; DWORD num_read = 0;
SFileReadFile(SFileRw_GetHandle(context), ptr, maxnum * size, &num_read, NULL); if (!SFileReadFile(SFileRw_GetHandle(context), ptr, maxnum * size, &num_read, NULL)) {
return num_read; const DWORD err_code = SErrGetLastError();
if (err_code != DVL_ERROR_HANDLE_EOF) {
SDL_Log("SFileRw_read error: %u %u ERROR CODE %u", (unsigned int)size, (unsigned int)maxnum, (unsigned int)err_code);
}
}
return num_read / size;
} }
static int SFileRw_close(struct SDL_RWops *context) static int SFileRw_close(struct SDL_RWops *context)

1
structs.h

@ -23,6 +23,7 @@ typedef struct TextDataStruct {
typedef struct TSnd { typedef struct TSnd {
const char *sound_path; const char *sound_path;
HANDLE file_handle; // for streamed audio
SoundSample *DSB; SoundSample *DSB;
int start_tc; int start_tc;
} TSnd; } TSnd;

Loading…
Cancel
Save