Merge branch 'musicplus-core' into musicplus-fade-sdltimer

# Conflicts:
#	src/sdl/mixer_sound.c
This commit is contained in:
mazmazz 2018-08-18 23:12:58 -04:00
commit 3bd3e51313
10 changed files with 567 additions and 147 deletions

View file

@ -74,11 +74,6 @@ void I_ResumeSong(INT32 handle)
(void)handle;
}
boolean I_MIDIPlaying(void)
{
return false;
}
boolean I_MusicPlaying(void)
{
return false;
@ -89,6 +84,11 @@ boolean I_MusicPaused(void)
return false;
}
musictype_t I_MusicType(void)
{
return MU_NONE;
}
//
// MIDI I/O
//
@ -158,6 +158,22 @@ boolean I_SetSongSpeed(float speed)
return false;
}
UINT32 I_GetMusicLength(void)
{
return 0;
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetMusicLoopPoint(void)
{
return 0;
}
boolean I_SetMusicPosition(UINT32 position)
{
(void)position;

View file

@ -551,6 +551,22 @@ boolean I_SetSongSpeed(float speed)
return false;
}
UINT32 I_GetMusicLength(void)
{
return 0;
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetMusicLoopPoint(void)
{
return 0;
}
boolean I_SetMusicPosition(UINT32 position)
{
(void)position;
@ -559,12 +575,7 @@ boolean I_SetMusicPosition(UINT32 position)
UINT32 I_GetMusicPosition(void)
{
return 0.;
}
boolean I_MIDIPlaying(void)
{
return (boolean)currsong && music_started;
return 0;
}
boolean I_MusicPlaying(void)
@ -576,3 +587,8 @@ boolean I_MusicPaused(void)
{
return false;
}
musictype_t I_MusicType(void)
{
return MU_NONE;
}

View file

@ -146,6 +146,22 @@ boolean I_SetSongTrack(int track)
return false;
}
UINT32 I_GetMusicLength(void)
{
return 0;
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetMusicLoopPoint(void)
{
return 0;
}
boolean I_SetMusicPosition(UINT32 position)
{
(void)position;
@ -157,11 +173,6 @@ UINT32 I_GetMusicPosition(void)
return 0;
}
boolean I_MIDIPlaying(void)
{
return false;
}
boolean I_MusicPlaying(void)
{
return false;
@ -171,3 +182,8 @@ boolean I_MusicPaused(void)
{
return false;
}
musictype_t I_MusicType(void)
{
return MU_NONE;
}

View file

@ -18,6 +18,21 @@
#include "sounds.h"
#include "command.h"
// copied from SDL mixer, plus GME
typedef enum {
MU_NONE,
MU_CMD,
MU_WAV,
MU_MOD,
MU_MID,
MU_OGG,
MU_MP3,
MU_MP3_MAD_UNUSED, // use MU_MP3 instead
MU_FLAC,
MU_MODPLUG_UNUSED, // use MU_MOD instead
MU_GME
} musictype_t;
/** \brief Sound subsystem runing and waiting
*/
extern UINT8 sound_started;
@ -132,12 +147,6 @@ void I_PauseSong(INT32 handle);
*/
void I_ResumeSong(INT32 handle);
/** \brief Get MIDI music status
\return boolean
*/
boolean I_MIDIPlaying(void);
/** \brief Get general music status
\return boolean
@ -150,6 +159,8 @@ boolean I_MusicPlaying(void);
*/
boolean I_MusicPaused(void);
musictype_t I_MusicType(void);
//
// MIDI I/O
//
@ -224,6 +235,12 @@ void I_ShutdownDigMusic(void);
boolean I_SetSongSpeed(float speed);
UINT32 I_GetMusicLength(void);
boolean I_SetMusicLoopPoint(UINT32 looppoint);
UINT32 I_GetMusicLoopPoint(void);
boolean I_SetMusicPosition(UINT32 position);
UINT32 I_GetMusicPosition(void);

View file

@ -2266,9 +2266,61 @@ static int lib_sSpeedMusic(lua_State *L)
}
#ifdef HAVE_LUA_MUSICPLUS
static int lib_sGetMusicLength(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicLength());
else
lua_pushnil(L);
return 1;
}
static int lib_sSetMusicLoopPoint(lua_State *L)
{
UINT32 looppoint = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_SetMusicLoopPoint(looppoint));
else
lua_pushnil(L);
return 1;
}
static int lib_sGetMusicLoopPoint(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicLoopPoint());
else
lua_pushnil(L);
return 1;
}
static int lib_sSetMusicPosition(lua_State *L)
{
UINT32 position = 0;
UINT32 position = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
@ -2286,8 +2338,18 @@ static int lib_sSetMusicPosition(lua_State *L)
static int lib_sGetMusicPosition(lua_State *L)
{
player_t *player = NULL;
NOHUD
lua_pushinteger(L, (UINT32)S_GetMusicPosition());
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicPosition());
else
lua_pushnil(L);
return 1;
}
@ -2315,9 +2377,9 @@ static int lib_sResumeMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
@ -2351,40 +2413,6 @@ static int lib_sStopMusic(lua_State *L)
return 1;
}
static int lib_sDigitalPlaying(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, !S_MIDIPlaying() && S_MusicPlaying());
else
lua_pushnil(L);
return 1;
}
static int lib_sMidiPlaying(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_MIDIPlaying());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicPlaying(lua_State *L)
{
player_t *player = NULL;
@ -2419,6 +2447,23 @@ static int lib_sMusicPaused(lua_State *L)
return 1;
}
static int lib_sMusicType(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, S_MusicType());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicName(lua_State *L)
{
player_t *player = NULL;
@ -2850,15 +2895,17 @@ static luaL_Reg lib[] = {
{"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic},
#ifdef HAVE_LUA_MUSICPLUS
{"S_GetMusicLength",lib_sGetMusicLength},
{"S_SetMusicLoopPoint",lib_sSetMusicLoopPoint},
{"S_GetMusicLoopPoint",lib_sGetMusicLoopPoint},
{"S_SetMusicPosition",lib_sSetMusicPosition},
{"S_GetMusicPosition",lib_sGetMusicPosition},
{"S_PauseMusic",lib_sPauseMusic},
{"S_ResumeMusic",lib_sResumeMusic},
{"S_StopMusic",lib_sStopMusic},
{"S_DigitalPlaying",lib_sDigitalPlaying},
{"S_MidiPlaying",lib_sMidiPlaying},
{"S_MusicPlaying",lib_sMusicPlaying},
{"S_MusicPaused",lib_sMusicPaused},
{"S_MusicType",lib_sMusicType},
{"S_MusicName",lib_sMusicName},
{"S_MusicExists",lib_sMusicExists},
#endif

View file

@ -1389,7 +1389,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
if(LUAh_MusicChange(music_name, mmusic, newmusic, &mflags, &looping))
return;
#else
strncpy(newmusic, mmusic, 7);
strncpy(newmusic, mmusic, 7);
#endif
newmusic[6] = 0;
@ -1412,11 +1412,31 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
}
musictype_t S_MusicType()
{
return I_MusicType();
}
boolean S_SpeedMusic(float speed)
{
return I_SetSongSpeed(speed);
}
UINT32 S_GetMusicLength(void)
{
return I_GetMusicLength();
}
boolean S_SetMusicLoopPoint(UINT32 looppoint)
{
return I_SetMusicLoopPoint(looppoint);
}
UINT32 S_GetMusicLoopPoint(void)
{
return I_GetMusicLoopPoint();
}
boolean S_SetMusicPosition(UINT32 position)
{
return I_SetMusicPosition(position);
@ -1589,11 +1609,6 @@ void S_ResumeAudio(void)
I_ResumeCD();
}
boolean S_MIDIPlaying(void)
{
return I_MIDIPlaying();
}
boolean S_MusicPlaying(void)
{
return I_MusicPlaying();

View file

@ -14,6 +14,7 @@
#ifndef __S_SOUND__
#define __S_SOUND__
#include "i_sound.h"
#include "sounds.h"
#include "m_fixed.h"
#include "command.h"
@ -132,9 +133,21 @@ void S_StopSound(void *origin);
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
// Get music type
musictype_t S_MusicType();
// Set Speed of Music
boolean S_SpeedMusic(float speed);
// Get Length of Music
UINT32 S_GetMusicLength(void);
// Set LoopPoint of Music
boolean S_SetMusicLoopPoint(UINT32 looppoint);
// Get LoopPoint of Music
UINT32 S_GetMusicLoopPoint(void);
// Set Position of Music
boolean S_SetMusicPosition(UINT32 position);
@ -148,9 +161,6 @@ void S_StopMusic(void);
void S_PauseAudio(void);
void S_ResumeAudio(void);
// Gets MIDI music status
boolean S_MIDIPlaying(void);
// Gets general music status
boolean S_MusicPlaying(void);

View file

@ -66,6 +66,7 @@ static boolean midimode;
static Mix_Music *music;
static UINT8 music_volume, midi_volume, sfx_volume;
static float loop_point;
static float music_length; // length in seconds
static boolean songpaused;
static UINT32 music_bytes;
static boolean is_looping;
@ -80,6 +81,15 @@ static Music_Emu *gme;
static INT32 current_track;
#endif
static void varcleanup(void)
{
loop_point = music_length =\
music_bytes = 0;
songpaused = is_looping =\
midimode = false;
}
void I_StartupSound(void)
{
I_Assert(!sound_started);
@ -315,6 +325,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
len = (info->play_length * 441 / 10) << 2;
mem = Z_Malloc(len, PU_SOUND, NULL);
gme_play(emu, len >> 1, mem);
gme_free_info(info);
gme_delete(emu);
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
@ -387,6 +398,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
len = (info->play_length * 441 / 10) << 2;
mem = Z_Malloc(len, PU_SOUND, NULL);
gme_play(emu, len >> 1, mem);
gme_free_info(info);
gme_delete(emu);
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
@ -443,9 +455,25 @@ void I_SetSfxVolume(UINT8 volume)
// Music
//
musictype_t I_MusicType(void)
{
if (gme)
return MU_GME;
else if (midimode)
return MU_MID;
else if (!music)
return MU_NONE;
else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED)
return MU_MOD;
else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED)
return MU_MP3;
else
return (musictype_t)Mix_GetMusicType(music);
}
static void count_music_bytes(int chan, void *stream, int len, void *udata)
{
if(midimode || !music)
if (gme || midimode || !music || I_MusicType() == MU_MOD)
return;
music_bytes += len;
}
@ -457,15 +485,10 @@ static void music_loop(void)
{
Mix_PlayMusic(music, 0);
Mix_SetMusicPosition(loop_point);
music_bytes = loop_point/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetMusicPosition)
music_bytes = loop_point*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetMusicPosition)
}
else
{
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
music_bytes = 0;
// be consistent with FMOD, otherwise I'd prefer to freeze music_bytes
// since the other flags indicate music is still playing.
}
I_StopDigSong();
}
static UINT32 music_fadeout(UINT32 interval)
@ -526,8 +549,13 @@ void I_ShutdownMusic(void)
void I_PauseSong(INT32 handle)
{
(void)handle;
if(!midimode)
if(midimode) // really, SDL Mixer? why can't you pause MIDI???
return;
if(!gme && I_MusicType() != MU_MOD)
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_PauseMusic();
songpaused = true;
}
@ -535,23 +563,23 @@ void I_PauseSong(INT32 handle)
void I_ResumeSong(INT32 handle)
{
(void)handle;
if(!midimode)
if (midimode)
return;
if (!gme && I_MusicType() != MU_MOD)
{
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
// HACK: fixes issue of multiple effect callbacks being registered
if(music && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
// midimode and music must be checked in case nothing is actually playing
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
}
Mix_ResumeMusic();
songpaused = false;
}
boolean I_MIDIPlaying(void)
{
return midimode && music;
}
boolean I_MusicPlaying(void)
{
return (boolean)music;
@ -559,7 +587,7 @@ boolean I_MusicPlaying(void)
boolean I_MusicPaused(void)
{
return Mix_PausedMusic();
return songpaused;
}
//
@ -588,8 +616,7 @@ void I_ShutdownDigMusic(void)
#endif
if (!music)
return;
is_fadingin = is_fadingout = is_looping = false;
music_bytes = 0;
varcleanup();
SDL_RemoveTimer(fading_id);
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_HookMusicFinished(NULL);
@ -610,7 +637,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
if (lumpnum == LUMPERROR)
return false;
midimode = false;
varcleanup();
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
len = W_LumpLength(lumpnum);
@ -723,50 +751,127 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
// Find the OGG loop point.
is_looping = looping;
loop_point = 0.0f;
music_length = 0.0f;
if (looping)
{
const char *key1 = "LOOP";
const char *key2 = "POINT=";
const char *key3 = "MS=";
const char *key4 = "LENGTHMS=";
const size_t key1len = strlen(key1);
const size_t key2len = strlen(key2);
const size_t key3len = strlen(key3);
const size_t key4len = strlen(key4);
// for mp3 wide chars
const char *key1w = "L\0O\0O\0P\0";
const char *key2w = "P\0O\0I\0N\0T\0\0\0\xFF\xFE";
const char *key3w = "M\0S\0\0\0\xFF\xFE";
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0\0\0\xFF\xFE";
const char *wterm = "\0\0";
char wval[10];
size_t wstart, wp;
char *p = data;
while ((UINT32)(p - data) < len)
{
if (strncmp(p++, key1, key1len))
continue;
p += key1len-1; // skip OOP (the L was skipped in strncmp)
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
if (!loop_point && !strncmp(p, key1, key1len))
{
p += key2len; // skip POINT=
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
// because SDL_Mixer is USELESS and can't even tell us
// something simple like the frequency of the streaming music,
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
p += key1len; // skip LOOP
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
{
p += key2len; // skip POINT=
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
// because SDL_Mixer is USELESS and can't even tell us
// something simple like the frequency of the streaming music,
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
}
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
{
p += key3len; // skip MS=
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
}
}
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
else if (!music_length && !strncmp(p, key4, key4len)) // is it LENGTHMS=?
{
p += key3len; // skip MS=
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
p += key4len; // skip LENGTHMS
music_length = (float)(atoi(p) / 1000.0L);
}
// Neither?! Continue searching.
// below: search MP3 or other tags that use wide char encoding
else if (!loop_point && !memcmp(p, key1w, key1len*2)) // LOOP wide char
{
p += key1len*2;
if (!memcmp(p, key2w, (key2len+1)*2)) // POINT= wide char
{
p += (key2len+1)*2;
wstart = (size_t)p;
wp = 0;
while (wp < 9 && memcmp(p, wterm, 2))
{
wval[wp] = *p;
p += 2;
wp = ((size_t)(p-wstart))/2;
}
wval[min(wp, 9)] = 0;
loop_point = (float)((44.1L+atoi(wval) / 44100.0L));
}
else if (!memcmp(p, key3w, (key3len+1)*2)) // MS= wide char
{
p += (key3len+1)*2;
wstart = (size_t)p;
wp = 0;
while (wp < 9 && memcmp(p, wterm, 2))
{
wval[wp] = *p;
p += 2;
wp = ((size_t)(p-wstart))/2;
}
wval[min(wp, 9)] = 0;
loop_point = (float)(atoi(wval) / 1000.0L);
}
}
else if (!music_length && !memcmp(p, key4w, (key4len+1)*2)) // LENGTHMS= wide char
{
p += (key4len+1)*2;
wstart = (size_t)p;
wp = 0;
while (wp < 9 && memcmp(p, wterm, 2))
{
wval[wp] = *p;
p += 2;
wp = ((size_t)(p-wstart))/2;
}
wval[min(wp, 9)] = 0;
music_length = (float)(atoi(wval) / 1000.0L);
}
if (loop_point && music_length && music_length > loop_point) // Got what we needed
// the last case is a sanity check, in case the wide char searches were false matches.
break;
else // continue searching
p++;
}
}
if (Mix_PlayMusic(music, 0) == -1)
if (I_MusicType() != MU_MOD && Mix_PlayMusic(music, 0) == -1)
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return true;
}
else if ((I_MusicType() == MU_MOD) && Mix_PlayMusic(music, -1) == -1) // if MOD, loop forever
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return true;
}
Mix_VolumeMusic((UINT32)music_volume*128/31);
Mix_HookMusicFinished(music_loop);
if (I_MusicType() != MU_MOD)
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
music_bytes = 0;
if(!Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
if(I_MusicType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
return true;
@ -788,8 +893,7 @@ void I_StopDigSong(void)
#endif
if (!music)
return;
is_looping = false;
music_bytes = 0;
varcleanup();
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_HookMusicFinished(NULL);
Mix_FreeMusic(music);
@ -822,30 +926,175 @@ boolean I_SetSongSpeed(float speed)
return false;
}
UINT32 I_GetMusicLength(void)
{
INT32 length;
if (gme)
{
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
length = 0;
}
else
{
// reconstruct info->play_length, from GME source
// we only want intro + 1 loop, not 2
length = info->length;
if (length <= 0)
{
length = info->intro_length + info->loop_length; // intro + 1 loop
if (length <= 0)
length = 150 * 1000; // 2.5 minutes
}
}
gme_free_info(info);
return max(length, 0);
}
else if (midimode || !music || I_MusicType() == MU_MOD)
return 0;
else
{
// VERY IMPORTANT to set your LENGTHMS= in your song files, folks!
// SDL mixer can't read music length itself.
length = (UINT32)(music_length*1000);
if (!length)
CONS_Debug(DBG_BASIC, "Getting music length: music is missing LENGTHMS= in music tag.\n");
return length;
}
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
if (midimode || gme || !music || I_MusicType() == MU_MOD || !is_looping)
return false;
else
{
UINT32 length = I_GetMusicLength();
if (length > 0)
looppoint %= length;
loop_point = max((float)(looppoint / 1000.0L), 0);
return true;
}
}
UINT32 I_GetMusicLoopPoint(void)
{
if (gme)
{
INT32 looppoint;
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
looppoint = 0;
}
else
looppoint = info->intro_length > 0 ? info->intro_length : 0;
gme_free_info(info);
return max(looppoint, 0);
}
else if (midimode || !music || I_MusicType() == MU_MOD)
return 0;
else
return (UINT32)(loop_point * 1000);
}
boolean I_SetMusicPosition(UINT32 position)
{
if(midimode || !music)
UINT32 length;
if (gme)
{
// this isn't required technically, but GME thread-locks for a second
// if you seek too high from the counter
length = I_GetMusicLength();
if (length)
position %= length;
SDL_LockAudio();
gme_err_t gme_e = gme_seek(gme, position);
SDL_UnlockAudio();
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
return false;
}
else
return true;
}
else if (midimode || !music)
return false;
Mix_RewindMusic(); // needed for mp3
if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0)
music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPositon)
else if (I_MusicType() == MU_MOD)
return Mix_SetMusicPosition(position); // Goes by channels
else
// NOTE: This block fires on incorrect song format,
// NOT if position input is greater than song length.
// This means music_bytes will be inaccurate because we can't compare to
// max song length. So, don't write your scripts to seek beyond the song.
music_bytes = 0;
return true;
{
// Because SDL mixer can't identify song length, if you have
// a position input greater than the real length, then
// music_bytes becomes inaccurate.
length = I_GetMusicLength(); // get it in MS
if (length)
position %= length;
Mix_RewindMusic(); // needed for mp3
if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0)
music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
else
// NOTE: This block fires on incorrect song format,
// NOT if position input is greater than song length.
music_bytes = 0;
return true;
}
}
UINT32 I_GetMusicPosition(void)
{
if(midimode)
if (gme)
{
INT32 position = gme_tell(gme);
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
return position;
}
else
{
// adjust position, since GME's counter keeps going past loop
if (info->length > 0)
position %= info->length;
else if (info->intro_length + info->loop_length > 0)
position = ((position - info->intro_length) % info->loop_length) + info->intro_length;
else
position %= 150 * 1000; // 2.5 minutes
}
gme_free_info(info);
return max(position, 0);
}
else if (midimode || !music)
return 0;
return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz
// 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel)
// This is hardcoded in I_StartupSound. Other formats for factor:
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
else
return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz
// 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel)
// This is hardcoded in I_StartupSound. Other formats for factor:
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
}
boolean I_SetSongTrack(int track)
@ -874,7 +1123,10 @@ boolean I_SetSongTrack(int track)
SDL_UnlockAudio();
return false;
}
else
#endif
if (I_MusicType() == MU_MOD)
return !Mix_SetMusicPosition(track);
(void)track;
return false;
}
@ -936,9 +1188,8 @@ void I_ShutdownMIDIMusic(void)
{
if (!midimode || !music)
return;
is_looping = false;
varcleanup();
//MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_FreeMusic(music);
music = NULL;
@ -972,6 +1223,8 @@ boolean I_PlaySong(INT32 handle, boolean looping)
{
(void)handle;
varcleanup();
midimode = true;
if (Mix_PlayMusic(music, looping ? -1 : 0) == -1)
@ -985,7 +1238,6 @@ boolean I_PlaySong(INT32 handle, boolean looping)
//MIDI does count correctly, but dummy out because unsupported
//If this is enabled, you need to edit Mix_PlayMusic above to never loop (0)
//and register the music_loop callback
//music_bytes = 0;
//if(!Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
// CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
@ -998,10 +1250,8 @@ void I_StopSong(INT32 handle)
if (!midimode || !music)
return;
is_looping = false;
varcleanup();
//MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
(void)handle;
Mix_HaltMusic();
@ -1012,10 +1262,8 @@ void I_UnRegisterSong(INT32 handle)
if (!midimode || !music)
return;
is_looping = false;
varcleanup();
//MIDI does count correctly, but dummy out because unsupported
//music_bytes = 0;
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
(void)handle;
Mix_FreeMusic(music);

View file

@ -1649,12 +1649,6 @@ void I_StopSong(INT32 handle)
#endif
}
boolean I_MIDIPlaying(void)
{
// todo: no way to tell specifically if MIDI is playing, implement midimode
return !nomidimusic && nodigimusic && musicStarted;
}
boolean I_MusicPlaying(void)
{
return musicStarted;
@ -1665,6 +1659,11 @@ boolean I_MusicPaused(void)
return Mix_PausedMusic();
}
musictype_t I_MusicType(void)
{
return MU_NONE;
}
void I_UnRegisterSong(INT32 handle)
{
#ifdef HAVE_MIXER
@ -1989,6 +1988,22 @@ boolean I_SetSongSpeed(float speed)
return false;
}
UINT32 I_GetMusicLength(void)
{
return 0;
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetMusicLoopPoint(void)
{
return 0;
}
boolean I_SetMusicPosition(UINT32 position)
{
(void)position;

View file

@ -468,11 +468,6 @@ void I_ResumeSong(INT32 handle)
FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false));
}
boolean I_MIDIPlaying(void)
{
return midimode && music_stream;
}
boolean I_MusicPlaying(void)
{
return (boolean)music_stream;
@ -486,6 +481,11 @@ boolean I_MusicPaused(void)
return fmpaused;
}
musictype_t I_MusicType(void)
{
return MU_NONE;
}
void I_InitDigMusic(void)
{
}
@ -774,6 +774,26 @@ boolean I_SetSongSpeed(float speed)
return true;
}
UINT32 I_GetMusicLength()
{
if (midimode)
return 0;
UINT32 length;
e = FMOD_Sound_GetLength(music_stream, length, FMOD_TIMEUNIT_MS);
return length;
}
boolean I_SetMusicLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetMusicLoopPoint(void)
{
return 0;
}
boolean I_SetMusicPosition(UINT32 position)
{
if(midimode)