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_CHANNELGROUP *bgm_channelGroup = NULL;
FMOD_CHANNEL *bgm_channel = NULL; FMOD_CHANNEL *bgm_channel = NULL;
FMOD_SOUND *bgm_sound = NULL; FMOD_SOUND *bgm_sound = NULL;
byte *bgm_data = NULL;
static const char *extensions[] = static const char *extensions[] =
{ {
@ -136,9 +135,7 @@ void BGM_Shutdown (void)
static qboolean BGM_PlayStream(const char *filename) static qboolean BGM_PlayStream(const char *filename)
{ {
FILE *f;
int len;
FMOD_CREATESOUNDEXINFO exinfo;
char netpath[MAX_OSPATH];
FMOD_RESULT result; FMOD_RESULT result;
if (!fmod_system || !bgm_channelGroup) if (!fmod_system || !bgm_channelGroup)
@ -147,28 +144,13 @@ static qboolean BGM_PlayStream(const char *filename)
return false; 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); Con_Printf("Could not open BGM file %s, file not found\n", filename);
return false; 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) if (result != FMOD_OK || !bgm_sound)
{ {
Con_Printf("Failed to create FMOD sound: %s\n", FMOD_ErrorString(result)); 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; return false;
} }
Con_DPrintf("BGM_PlayStream: Successfully loaded %s\n", filename);
result = FMOD_System_PlaySound(fmod_system, bgm_sound, bgm_channelGroup, false, &bgm_channel); result = FMOD_System_PlaySound(fmod_system, bgm_sound, bgm_channelGroup, false, &bgm_channel);
if (result != FMOD_OK || !bgm_channel) if (result != FMOD_OK || !bgm_channel)
{ {
@ -298,12 +282,6 @@ void BGM_Stop(void)
FMOD_Sound_Release(bgm_sound); FMOD_Sound_Release(bgm_sound);
bgm_sound = NULL; bgm_sound = NULL;
} }
if (bgm_data)
{
free(bgm_data);
bgm_data = NULL;
}
} }
void BGM_Pause (void) 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. 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; searchpath_t *search;
char netpath[MAX_OSPATH];
pack_t *pak; pack_t *pak;
int i, findtime; 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"); Sys_Error ("COM_FindFile: both handle and file set");
file_from_pak = 0; file_from_pak = 0;
memset(netpath, 0, size);
// //
// search through the path, one element at a time // 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; continue;
} }
q_snprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename);
q_snprintf (netpath, size, "%s/%s",search->filename, filename);
findtime = Sys_FileTime (netpath); findtime = Sys_FileTime (netpath);
if (findtime == -1) if (findtime == -1)
continue; continue;
@ -1703,6 +1702,11 @@ static int COM_FindFile (const char *filename, int *handle, FILE **file,
return com_filesize; 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); 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); int COM_FOpenFile (const char *filename, FILE **file, unsigned int *path_id);
qboolean COM_FileExists (const char *filename, unsigned int *path_id); qboolean COM_FileExists (const char *filename, unsigned int *path_id);
void COM_CloseFile (int h); 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 // 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 // buffer. the buffer is allocated with a total size of com_filesize + 1. the

Loading…
Cancel
Save