shithub: choc

Download patch

ref: 765ca3a04dafe63b8803443067293ee46f53b951
parent: a3e2dbc78825378307509201f904a1de3bf8bab8
author: Simon Howard <fraggle@gmail.com>
date: Sat Mar 22 20:55:13 EDT 2014

music: Add config var for external music program.

Mix_SetMusicCMD() allows a program to be specified to configure an
external program to be invoked for music playback. Add a config
variable (snd_musiccmd) to allow this to be set from a configuration
file. Thanks to Holering for his comments on Doomworld about how to do
this.

--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -222,6 +222,14 @@
 
     RemoveTimidityConfig();
 
+    // If snd_musiccmd is set, we need to call Mix_SetMusicCMD to
+    // configure an external music playback program.
+
+    if (strlen(snd_musiccmd) > 0)
+    {
+        Mix_SetMusicCMD(snd_musiccmd);
+    }
+
     return music_initialized;
 }
 
@@ -378,10 +386,10 @@
     {
         return NULL;
     }
-    
+
     // MUS files begin with "MUS"
     // Reject anything which doesnt have this signature
-    
+
     filename = M_TempFile("doom.mid");
 
     if (IsMid(data, len) && len < MAXMIDLENGTH)
@@ -388,7 +396,7 @@
     {
         M_WriteFile(filename, data, len);
     }
-    else 
+    else
     {
 	// Assume a MUS file and try to convert
 
@@ -395,10 +403,12 @@
         ConvertMus(data, len, filename);
     }
 
-    // Load the MIDI
+    // Load the MIDI. In an ideal world we'd be using Mix_LoadMUS_RW()
+    // by now, but Mix_SetMusicCMD() only works with Mix_LoadMUS(), so
+    // we have to generate a temporary file.
 
     music = Mix_LoadMUS(filename);
-    
+
     if (music == NULL)
     {
         // Failed to load
@@ -406,9 +416,15 @@
         fprintf(stderr, "Error loading midi: %s\n", Mix_GetError());
     }
 
-    // remove file now
+    // Remove the temporary MIDI file; however, when using an external
+    // MIDI program we can't delete the file. Otherwise, the program
+    // won't find the file to play. This means we leave a mess on
+    // disk :(
 
-    remove(filename);
+    if (strlen(snd_musiccmd) == 0)
+    {
+        remove(filename);
+    }
 
     Z_Free(filename);
 
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -52,6 +52,10 @@
 
 int snd_maxslicetime_ms = 28;
 
+// External command to invoke to play back music.
+
+char *snd_musiccmd = "";
+
 // Low-level sound and music modules we are using
 
 static sound_module_t *sound_module;
@@ -440,6 +444,7 @@
     M_BindVariable("snd_sbdma",         &snd_sbdma);
     M_BindVariable("snd_mport",         &snd_mport);
     M_BindVariable("snd_maxslicetime_ms", &snd_maxslicetime_ms);
+    M_BindVariable("snd_musiccmd",      &snd_musiccmd);
     M_BindVariable("snd_samplerate",    &snd_samplerate);
     M_BindVariable("snd_cachesize",     &snd_cachesize);
     M_BindVariable("opl_io_port",       &opl_io_port);
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -234,6 +234,7 @@
 extern int snd_samplerate;
 extern int snd_cachesize;
 extern int snd_maxslicetime_ms;
+extern char *snd_musiccmd;
 
 void I_BindSoundVariables(void);
 
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -807,6 +807,14 @@
     CONFIG_VARIABLE_INT(snd_maxslicetime_ms),
 
     //!
+    // External command to invoke to perform MIDI playback. If set to
+    // the empty string, SDL_mixer's internal MIDI playback is used.
+    // This only has any effect when snd_musicdevice is set to General
+    // MIDI output.
+
+    CONFIG_VARIABLE_STRING(snd_musiccmd),
+
+    //!
     // The I/O port to use to access the OPL chip.  Only relevant when
     // using native OPL music playback.
     //
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@ -74,6 +74,7 @@
 int snd_samplerate = 44100;
 int opl_io_port = 0x388;
 int snd_cachesize = 64 * 1024 * 1024;
+char *snd_musiccmd = "";
 
 static int numChannels = 8;
 static int sfxVolume = 15;
@@ -317,6 +318,7 @@
     M_BindVariable("snd_sbirq",           &snd_sbirq);
     M_BindVariable("snd_sbdma",           &snd_sbdma);
     M_BindVariable("snd_mport",           &snd_mport);
+    M_BindVariable("snd_musiccmd",        &snd_musiccmd);
 
     M_BindVariable("snd_cachesize",       &snd_cachesize);
     M_BindVariable("opl_io_port",         &opl_io_port);