Browse Source

Stream music files from disk with FMOD, instead of preloading the entire file into memory and playing from there. Added a helper function to COM_ to assist with this.

This removes the noticeable delay when loading into a level, and simplifies the music playback code as well.
console
Nico de Poel 5 years ago
parent
commit
3e0c4b5314
  1. 32
      engine/Quake/bgmusic.c
  2. 28
      engine/Quake/common.c
  3. 1
      engine/Quake/common.h

32
engine/Quake/bgmusic.c

@ -42,7 +42,6 @@ extern FMOD_SYSTEM *fmod_system;
FMOD_CHANNELGROUP *bgm_channelGroup = NULL;
FMOD_CHANNEL *bgm_channel = NULL;
FMOD_SOUND *bgm_sound = NULL;
byte *bgm_data = NULL;
static const char *extensions[] =
{
@ -136,9 +135,7 @@ void BGM_Shutdown (void)
static qboolean BGM_PlayStream(const char *filename)
{
FILE *f;
int len;
FMOD_CREATESOUNDEXINFO exinfo;
char netpath[MAX_OSPATH];
FMOD_RESULT result;
if (!fmod_system || !bgm_channelGroup)
@ -147,28 +144,13 @@ static qboolean BGM_PlayStream(const char *filename)
return false;
}
len = COM_FOpenFile(filename, &f, NULL);
fclose(f);
if (len < 1)
if (!COM_FullFilePath(filename, netpath, sizeof(netpath)))
{
Con_Printf("Could not open BGM file %s, file not found\n", filename);
return false;
}
bgm_data = COM_LoadMallocFile(filename, NULL); // TODO is there really no better way to pre-cache this data than with malloc?
if (!bgm_data)
{
Con_Printf("Failed to load BGM file %s\n", filename);
return false;
}
Con_DPrintf("BGM_PlayStream: Successfully loaded %s\n", filename);
memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.length = len;
result = FMOD_System_CreateSound(fmod_system, (const char*)bgm_data, FMOD_OPENMEMORY | FMOD_2D, &exinfo, &bgm_sound);
result = FMOD_System_CreateSound(fmod_system, netpath, FMOD_CREATESTREAM | FMOD_2D, NULL, &bgm_sound);
if (result != FMOD_OK || !bgm_sound)
{
Con_Printf("Failed to create FMOD sound: %s\n", FMOD_ErrorString(result));
@ -176,6 +158,8 @@ static qboolean BGM_PlayStream(const char *filename)
return false;
}
Con_DPrintf("BGM_PlayStream: Successfully loaded %s\n", filename);
result = FMOD_System_PlaySound(fmod_system, bgm_sound, bgm_channelGroup, false, &bgm_channel);
if (result != FMOD_OK || !bgm_channel)
{
@ -298,12 +282,6 @@ void BGM_Stop(void)
FMOD_Sound_Release(bgm_sound);
bgm_sound = NULL;
}
if (bgm_data)
{
free(bgm_data);
bgm_data = NULL;
}
}
void BGM_Pause (void)

28
engine/Quake/common.c

@ -1604,11 +1604,9 @@ If neither of file or handle is set, this
can be used for detecting a file's presence.
===========
*/
static int COM_FindFile (const char *filename, int *handle, FILE **file,
unsigned int *path_id)
static int COM_FindFile2(const char *filename, int *handle, FILE **file, unsigned int *path_id, char *netpath, size_t size)
{
searchpath_t *search;
char netpath[MAX_OSPATH];
pack_t *pak;
int i, findtime;
@ -1616,6 +1614,7 @@ static int COM_FindFile (const char *filename, int *handle, FILE **file,
Sys_Error ("COM_FindFile: both handle and file set");
file_from_pak = 0;
memset(netpath, 0, size);
//
// search through the path, one element at a time
@ -1661,7 +1660,7 @@ static int COM_FindFile (const char *filename, int *handle, FILE **file,
continue;
}
q_snprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename);
q_snprintf (netpath, size, "%s/%s",search->filename, filename);
findtime = Sys_FileTime (netpath);
if (findtime == -1)
continue;
@ -1703,6 +1702,11 @@ static int COM_FindFile (const char *filename, int *handle, FILE **file,
return com_filesize;
}
static int COM_FindFile(const char *filename, int *handle, FILE **file, unsigned int *path_id)
{
char netpath[MAX_OSPATH];
return COM_FindFile2(filename, handle, file, path_id, netpath, sizeof(netpath));
}
/*
===========
@ -1762,6 +1766,22 @@ void COM_CloseFile (int h)
Sys_FileClose (h);
}
/*
================
COM_FullFilePath
Get the full canonical file path of the requested file on disk.
If it is inside a pak file, this returns false.
================
*/
qboolean COM_FullFilePath(const char *filename, char *netpath, size_t size)
{
int ret = COM_FindFile2(filename, NULL, NULL, NULL, netpath, size);
if (ret < 0 || !*netpath || file_from_pak)
return false;
return true;
}
/*
============

1
engine/Quake/common.h

@ -233,6 +233,7 @@ int COM_OpenFile (const char *filename, int *handle, unsigned int *path_id);
int COM_FOpenFile (const char *filename, FILE **file, unsigned int *path_id);
qboolean COM_FileExists (const char *filename, unsigned int *path_id);
void COM_CloseFile (int h);
qboolean COM_FullFilePath(const char *filename, char *netpath, size_t size);
// these procedures open a file using COM_FindFile and loads it into a proper
// buffer. the buffer is allocated with a total size of com_filesize + 1. the

Loading…
Cancel
Save