Add server shutdown and music overrides
- The process will now cut the music and shut down when Chocolate Doom does. - The process will now peacefully coexist with music overrides, such as digital music packs.
This commit is contained in:
parent
6f366890c4
commit
7791ace57e
5 changed files with 141 additions and 30 deletions
|
|
@ -41,8 +41,37 @@ static HANDLE midi_process_in; // Standard In.
|
|||
static HANDLE midi_process_out; // Standard Out.
|
||||
static buffer_t *midi_buffer; // Data from client.
|
||||
|
||||
// Currently playing music track
|
||||
static Mix_Music *music = NULL;
|
||||
// Currently playing music track.
|
||||
static Mix_Music *music = NULL;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Private functions
|
||||
//
|
||||
|
||||
//
|
||||
// Unregisters the currently playing song. This is never called from the
|
||||
// protocol, we simply do this before playing a new song.
|
||||
//
|
||||
static void UnregisterSong()
|
||||
{
|
||||
if (music == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
//
|
||||
// Bookkeeping stuff we need to do when we're shutting off the subprocess.
|
||||
//
|
||||
static void ShutdownSDL(void)
|
||||
{
|
||||
UnregisterSong();
|
||||
Mix_CloseAudio();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
|
@ -53,6 +82,7 @@ static boolean RegisterSong(const char *filename)
|
|||
{
|
||||
fprintf(stderr, "%s %s\n", __FUNCTION__, filename);
|
||||
|
||||
UnregisterSong();
|
||||
music = Mix_LoadMUS(filename);
|
||||
fprintf(stderr, "<-- %p\n", music);
|
||||
|
||||
|
|
@ -76,8 +106,19 @@ static void SetVolume(int vol)
|
|||
static void PlaySong(int loops)
|
||||
{
|
||||
fprintf(stderr, "%s %d\n", __FUNCTION__, loops);
|
||||
fprintf(stderr, "%s %d\n", "Playing at volume", Mix_VolumeMusic(-1));
|
||||
|
||||
Mix_PlayMusic(music, loops);
|
||||
|
||||
// [AM] BUG: In my testing, setting the volume of a MIDI track while there
|
||||
// is no song playing appears to be a no-op. This can happen when
|
||||
// you're mixing midiproc with vanilla SDL_Mixer, such as when you
|
||||
// are alternating between a digital music pack (in the parent
|
||||
// process) and MIDI (in this process).
|
||||
//
|
||||
// To work around this bug, we set the volume to itself after the MIDI
|
||||
// has started playing.
|
||||
Mix_VolumeMusic(Mix_VolumeMusic(-1));
|
||||
}
|
||||
|
||||
static void StopSong()
|
||||
|
|
@ -87,16 +128,6 @@ static void StopSong()
|
|||
Mix_HaltMusic();
|
||||
}
|
||||
|
||||
//
|
||||
// ShutdownSDL
|
||||
//
|
||||
static void ShutdownSDL()
|
||||
{
|
||||
UnregisterSong();
|
||||
Mix_CloseAudio();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Pipe Server Interface
|
||||
|
|
@ -151,13 +182,18 @@ boolean MidiPipe_PlaySong(buffer_reader_t *reader)
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean MidiPipe_StopSong(buffer_reader_t *reader)
|
||||
boolean MidiPipe_StopSong()
|
||||
{
|
||||
StopSong();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean MidiPipe_Shutdown()
|
||||
{
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Server Implementation
|
||||
|
|
@ -177,7 +213,9 @@ boolean ParseCommand(buffer_reader_t *reader, uint16_t command)
|
|||
case NET_MIDIPIPE_PACKET_TYPE_PLAY_SONG:
|
||||
return MidiPipe_PlaySong(reader);
|
||||
case NET_MIDIPIPE_PACKET_TYPE_STOP_SONG:
|
||||
return MidiPipe_StopSong(reader);
|
||||
return MidiPipe_StopSong();
|
||||
case NET_MIDIPIPE_PACKET_TYPE_SHUTDOWN:
|
||||
return MidiPipe_Shutdown(reader);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -288,6 +326,8 @@ boolean InitSDL()
|
|||
return false;
|
||||
}
|
||||
|
||||
atexit(ShutdownSDL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ static HANDLE midi_process_out_reader; // Output stream for midi process.
|
|||
static HANDLE midi_process_out_writer;
|
||||
|
||||
static boolean server_init = false; // if true, server was started
|
||||
static boolean client_init = false; // if true, client was bound
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
|
@ -144,7 +143,7 @@ fail:
|
|||
// Tells the MIDI subprocess to load a specific filename for playing. This
|
||||
// function blocks until there is an acknowledgement from the server.
|
||||
//
|
||||
Mix_Music *I_MidiPipe_RegisterSong(const char *filename)
|
||||
boolean I_MidiPipe_RegisterSong(const char *filename)
|
||||
{
|
||||
boolean ok;
|
||||
net_packet_t *packet;
|
||||
|
|
@ -250,6 +249,32 @@ void I_MidiPipe_StopSong()
|
|||
DEBUGOUT("I_MidiPipe_StopSong succeeded");
|
||||
}
|
||||
|
||||
//
|
||||
// I_MidiPipe_StopSong
|
||||
//
|
||||
// Tells the MIDI subprocess to shutdown.
|
||||
//
|
||||
void I_MidiPipe_ShutdownServer()
|
||||
{
|
||||
boolean ok;
|
||||
net_packet_t *packet;
|
||||
|
||||
packet = NET_NewPacket(2);
|
||||
NET_WriteInt16(packet, NET_MIDIPIPE_PACKET_TYPE_SHUTDOWN);
|
||||
ok = WritePipe(packet);
|
||||
NET_FreePacket(packet);
|
||||
|
||||
server_init = false;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
DEBUGOUT("I_MidiPipe_ShutdownServer failed");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUGOUT("I_MidiPipe_ShutdownServer succeeded");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Public Interface
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
|
||||
Mix_Music *I_MidiPipe_RegisterSong(const char *filename);
|
||||
boolean I_MidiPipe_RegisterSong(const char *filename);
|
||||
void I_MidiPipe_SetVolume(int vol);
|
||||
void I_MidiPipe_PlaySong(int loops);
|
||||
void I_MidiPipe_StopSong();
|
||||
void I_MidiPipe_ShutdownServer();
|
||||
|
||||
boolean I_MidiPipe_InitServer();
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,9 @@ static Mix_Music *current_track_music = NULL;
|
|||
// If true, the currently playing track is being played on loop.
|
||||
static boolean current_track_loop;
|
||||
|
||||
// If true, the current track is being handled via midiproc.
|
||||
static boolean using_midiproc;
|
||||
|
||||
// Given a time string (for LOOP_START/LOOP_END), parse it and return
|
||||
// the time (in # samples since start of track) it represents.
|
||||
static unsigned int ParseVorbisTime(unsigned int samplerate_hz, char *value)
|
||||
|
|
@ -878,6 +881,9 @@ static void I_SDL_ShutdownMusic(void)
|
|||
{
|
||||
if (music_initialized)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
I_MidiPipe_ShutdownServer();
|
||||
#endif
|
||||
Mix_HaltMusic();
|
||||
music_initialized = false;
|
||||
|
||||
|
|
@ -974,7 +980,8 @@ static boolean I_SDL_InitMusic(void)
|
|||
LoadSubstituteConfigs();
|
||||
}
|
||||
|
||||
#if WIN32
|
||||
#if defined(_WIN32)
|
||||
// [AM] Start up midiproc to handle playing MIDI music.
|
||||
I_MidiPipe_InitServer();
|
||||
#endif
|
||||
|
||||
|
|
@ -999,11 +1006,10 @@ static void UpdateMusicVolume(void)
|
|||
vol = (current_music_volume * MIX_MAX_VOLUME) / 127;
|
||||
}
|
||||
|
||||
#if WIN32
|
||||
#if defined(_WIN32)
|
||||
I_MidiPipe_SetVolume(vol);
|
||||
#else
|
||||
Mix_VolumeMusic(vol);
|
||||
#endif
|
||||
Mix_VolumeMusic(vol);
|
||||
}
|
||||
|
||||
// Set music volume (0 - 127)
|
||||
|
|
@ -1027,7 +1033,7 @@ static void I_SDL_PlaySong(void *handle, boolean looping)
|
|||
return;
|
||||
}
|
||||
|
||||
if (handle == NULL)
|
||||
if (handle == NULL && !using_midiproc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1055,7 +1061,14 @@ static void I_SDL_PlaySong(void *handle, boolean looping)
|
|||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
I_MidiPipe_PlaySong(loops);
|
||||
if (using_midiproc)
|
||||
{
|
||||
I_MidiPipe_PlaySong(loops);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mix_PlayMusic(current_track_music, loops);
|
||||
}
|
||||
#else
|
||||
Mix_PlayMusic(current_track_music, loops);
|
||||
#endif
|
||||
|
|
@ -1093,7 +1106,15 @@ static void I_SDL_StopSong(void)
|
|||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
I_MidiPipe_StopSong();
|
||||
if (using_midiproc)
|
||||
{
|
||||
I_MidiPipe_StopSong();
|
||||
using_midiproc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mix_HaltMusic();
|
||||
}
|
||||
#else
|
||||
Mix_HaltMusic();
|
||||
#endif
|
||||
|
|
@ -1116,9 +1137,7 @@ static void I_SDL_UnRegisterSong(void *handle)
|
|||
return;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
Mix_FreeMusic(music);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Determine whether memory block is a .mid file
|
||||
|
|
@ -1182,6 +1201,9 @@ static void *I_SDL_RegisterSong(void *data, int len)
|
|||
}
|
||||
else
|
||||
{
|
||||
// [AM] Substitute music never uses midiproc.
|
||||
using_midiproc = false;
|
||||
|
||||
// Read loop point metadata from the file so that we know where
|
||||
// to loop the music.
|
||||
playing_substitute = true;
|
||||
|
|
@ -1211,17 +1233,39 @@ static void *I_SDL_RegisterSong(void *data, int len)
|
|||
// we have to generate a temporary file.
|
||||
|
||||
#if defined(_WIN32)
|
||||
music = I_MidiPipe_RegisterSong(filename);
|
||||
// [AM] If we do not have an external music command defined, play
|
||||
// music with midiproc.exe.
|
||||
if (strlen(snd_musiccmd) == 0)
|
||||
{
|
||||
music = NULL;
|
||||
if (I_MidiPipe_RegisterSong(filename))
|
||||
{
|
||||
using_midiproc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error loading midi: %s\n",
|
||||
"Could not communicate with midiproc.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using_midiproc = false;
|
||||
music = Mix_LoadMUS(filename);
|
||||
if (music == NULL)
|
||||
{
|
||||
// Failed to load
|
||||
fprintf(stderr, "Error loading midi: %s\n", Mix_GetError());
|
||||
}
|
||||
}
|
||||
#else
|
||||
music = Mix_LoadMUS(filename);
|
||||
#endif
|
||||
|
||||
if (music == NULL)
|
||||
{
|
||||
// Failed to load
|
||||
|
||||
fprintf(stderr, "Error loading midi: %s\n", Mix_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Remove the temporary MIDI file; however, when using an external
|
||||
// MIDI program we can't delete the file. Otherwise, the program
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ typedef enum {
|
|||
NET_MIDIPIPE_PACKET_TYPE_SET_VOLUME,
|
||||
NET_MIDIPIPE_PACKET_TYPE_PLAY_SONG,
|
||||
NET_MIDIPIPE_PACKET_TYPE_STOP_SONG,
|
||||
NET_MIDIPIPE_PACKET_TYPE_SHUTDOWN
|
||||
} net_midipipe_packet_type_t;
|
||||
|
||||
// Settings specified when the client connects to the server.
|
||||
|
|
|
|||
Loading…
Reference in a new issue