snd_alsa: MIDI input support! MIDI events get mapped to MIDINOTE<n> events (n = 0...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Sep 2009 12:59:45 +0000 (12:59 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Sep 2009 12:59:45 +0000 (12:59 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9232 d7cf8633-e32d-0410-b094-e92efae38249

12 files changed:
host.c
keys.c
keys.h
snd_3dras.c
snd_alsa.c
snd_bsd.c
snd_coreaudio.c
snd_main.h
snd_null.c
snd_oss.c
snd_sdl.c
snd_win.c

diff --git a/host.c b/host.c
index 8e2181d..f70a17f 100644 (file)
--- a/host.c
+++ b/host.c
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "progsvm.h"
 #include "csprogs.h"
 #include "sv_demo.h"
+#include "snd_main.h"
 
 /*
 
@@ -671,6 +672,7 @@ void Host_Main(void)
                cl.islocalgame = NetConn_IsLocalGame();
 
                // get new key events
+               SndSys_SendKeyEvents();
                Sys_SendKeyEvents();
 
                NetConn_UpdateSockets();
diff --git a/keys.c b/keys.c
index 879944f..fe4e8cc 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -321,6 +321,135 @@ static const keyname_t   keynames[] = {
        {"APOSTROPHE", '\''},
        {"BACKSLASH", '\\'},            // because a raw backslash is used for special characters
 
+       {"MIDINOTE0", K_MIDINOTE0},
+       {"MIDINOTE1", K_MIDINOTE1},
+       {"MIDINOTE2", K_MIDINOTE2},
+       {"MIDINOTE3", K_MIDINOTE3},
+       {"MIDINOTE4", K_MIDINOTE4},
+       {"MIDINOTE5", K_MIDINOTE5},
+       {"MIDINOTE6", K_MIDINOTE6},
+       {"MIDINOTE7", K_MIDINOTE7},
+       {"MIDINOTE8", K_MIDINOTE8},
+       {"MIDINOTE9", K_MIDINOTE9},
+       {"MIDINOTE10", K_MIDINOTE10},
+       {"MIDINOTE11", K_MIDINOTE11},
+       {"MIDINOTE12", K_MIDINOTE12},
+       {"MIDINOTE13", K_MIDINOTE13},
+       {"MIDINOTE14", K_MIDINOTE14},
+       {"MIDINOTE15", K_MIDINOTE15},
+       {"MIDINOTE16", K_MIDINOTE16},
+       {"MIDINOTE17", K_MIDINOTE17},
+       {"MIDINOTE18", K_MIDINOTE18},
+       {"MIDINOTE19", K_MIDINOTE19},
+       {"MIDINOTE20", K_MIDINOTE20},
+       {"MIDINOTE21", K_MIDINOTE21},
+       {"MIDINOTE22", K_MIDINOTE22},
+       {"MIDINOTE23", K_MIDINOTE23},
+       {"MIDINOTE24", K_MIDINOTE24},
+       {"MIDINOTE25", K_MIDINOTE25},
+       {"MIDINOTE26", K_MIDINOTE26},
+       {"MIDINOTE27", K_MIDINOTE27},
+       {"MIDINOTE28", K_MIDINOTE28},
+       {"MIDINOTE29", K_MIDINOTE29},
+       {"MIDINOTE30", K_MIDINOTE30},
+       {"MIDINOTE31", K_MIDINOTE31},
+       {"MIDINOTE32", K_MIDINOTE32},
+       {"MIDINOTE33", K_MIDINOTE33},
+       {"MIDINOTE34", K_MIDINOTE34},
+       {"MIDINOTE35", K_MIDINOTE35},
+       {"MIDINOTE36", K_MIDINOTE36},
+       {"MIDINOTE37", K_MIDINOTE37},
+       {"MIDINOTE38", K_MIDINOTE38},
+       {"MIDINOTE39", K_MIDINOTE39},
+       {"MIDINOTE40", K_MIDINOTE40},
+       {"MIDINOTE41", K_MIDINOTE41},
+       {"MIDINOTE42", K_MIDINOTE42},
+       {"MIDINOTE43", K_MIDINOTE43},
+       {"MIDINOTE44", K_MIDINOTE44},
+       {"MIDINOTE45", K_MIDINOTE45},
+       {"MIDINOTE46", K_MIDINOTE46},
+       {"MIDINOTE47", K_MIDINOTE47},
+       {"MIDINOTE48", K_MIDINOTE48},
+       {"MIDINOTE49", K_MIDINOTE49},
+       {"MIDINOTE50", K_MIDINOTE50},
+       {"MIDINOTE51", K_MIDINOTE51},
+       {"MIDINOTE52", K_MIDINOTE52},
+       {"MIDINOTE53", K_MIDINOTE53},
+       {"MIDINOTE54", K_MIDINOTE54},
+       {"MIDINOTE55", K_MIDINOTE55},
+       {"MIDINOTE56", K_MIDINOTE56},
+       {"MIDINOTE57", K_MIDINOTE57},
+       {"MIDINOTE58", K_MIDINOTE58},
+       {"MIDINOTE59", K_MIDINOTE59},
+       {"MIDINOTE60", K_MIDINOTE60},
+       {"MIDINOTE61", K_MIDINOTE61},
+       {"MIDINOTE62", K_MIDINOTE62},
+       {"MIDINOTE63", K_MIDINOTE63},
+       {"MIDINOTE64", K_MIDINOTE64},
+       {"MIDINOTE65", K_MIDINOTE65},
+       {"MIDINOTE66", K_MIDINOTE66},
+       {"MIDINOTE67", K_MIDINOTE67},
+       {"MIDINOTE68", K_MIDINOTE68},
+       {"MIDINOTE69", K_MIDINOTE69},
+       {"MIDINOTE70", K_MIDINOTE70},
+       {"MIDINOTE71", K_MIDINOTE71},
+       {"MIDINOTE72", K_MIDINOTE72},
+       {"MIDINOTE73", K_MIDINOTE73},
+       {"MIDINOTE74", K_MIDINOTE74},
+       {"MIDINOTE75", K_MIDINOTE75},
+       {"MIDINOTE76", K_MIDINOTE76},
+       {"MIDINOTE77", K_MIDINOTE77},
+       {"MIDINOTE78", K_MIDINOTE78},
+       {"MIDINOTE79", K_MIDINOTE79},
+       {"MIDINOTE80", K_MIDINOTE80},
+       {"MIDINOTE81", K_MIDINOTE81},
+       {"MIDINOTE82", K_MIDINOTE82},
+       {"MIDINOTE83", K_MIDINOTE83},
+       {"MIDINOTE84", K_MIDINOTE84},
+       {"MIDINOTE85", K_MIDINOTE85},
+       {"MIDINOTE86", K_MIDINOTE86},
+       {"MIDINOTE87", K_MIDINOTE87},
+       {"MIDINOTE88", K_MIDINOTE88},
+       {"MIDINOTE89", K_MIDINOTE89},
+       {"MIDINOTE90", K_MIDINOTE90},
+       {"MIDINOTE91", K_MIDINOTE91},
+       {"MIDINOTE92", K_MIDINOTE92},
+       {"MIDINOTE93", K_MIDINOTE93},
+       {"MIDINOTE94", K_MIDINOTE94},
+       {"MIDINOTE95", K_MIDINOTE95},
+       {"MIDINOTE96", K_MIDINOTE96},
+       {"MIDINOTE97", K_MIDINOTE97},
+       {"MIDINOTE98", K_MIDINOTE98},
+       {"MIDINOTE99", K_MIDINOTE99},
+       {"MIDINOTE100", K_MIDINOTE100},
+       {"MIDINOTE101", K_MIDINOTE101},
+       {"MIDINOTE102", K_MIDINOTE102},
+       {"MIDINOTE103", K_MIDINOTE103},
+       {"MIDINOTE104", K_MIDINOTE104},
+       {"MIDINOTE105", K_MIDINOTE105},
+       {"MIDINOTE106", K_MIDINOTE106},
+       {"MIDINOTE107", K_MIDINOTE107},
+       {"MIDINOTE108", K_MIDINOTE108},
+       {"MIDINOTE109", K_MIDINOTE109},
+       {"MIDINOTE110", K_MIDINOTE110},
+       {"MIDINOTE111", K_MIDINOTE111},
+       {"MIDINOTE112", K_MIDINOTE112},
+       {"MIDINOTE113", K_MIDINOTE113},
+       {"MIDINOTE114", K_MIDINOTE114},
+       {"MIDINOTE115", K_MIDINOTE115},
+       {"MIDINOTE116", K_MIDINOTE116},
+       {"MIDINOTE117", K_MIDINOTE117},
+       {"MIDINOTE118", K_MIDINOTE118},
+       {"MIDINOTE119", K_MIDINOTE119},
+       {"MIDINOTE120", K_MIDINOTE120},
+       {"MIDINOTE121", K_MIDINOTE121},
+       {"MIDINOTE122", K_MIDINOTE122},
+       {"MIDINOTE123", K_MIDINOTE123},
+       {"MIDINOTE124", K_MIDINOTE124},
+       {"MIDINOTE125", K_MIDINOTE125},
+       {"MIDINOTE126", K_MIDINOTE126},
+       {"MIDINOTE127", K_MIDINOTE127},
+
        {NULL, 0}
 };
 
diff --git a/keys.h b/keys.h
index beb5df6..6c04e09 100644 (file)
--- a/keys.h
+++ b/keys.h
@@ -185,6 +185,134 @@ typedef enum keynum_e
        K_AUX31,
        K_AUX32,
 
+       K_MIDINOTE0 = 896, // to this, the note number is added
+       K_MIDINOTE1,
+       K_MIDINOTE2,
+       K_MIDINOTE3,
+       K_MIDINOTE4,
+       K_MIDINOTE5,
+       K_MIDINOTE6,
+       K_MIDINOTE7,
+       K_MIDINOTE8,
+       K_MIDINOTE9,
+       K_MIDINOTE10,
+       K_MIDINOTE11,
+       K_MIDINOTE12,
+       K_MIDINOTE13,
+       K_MIDINOTE14,
+       K_MIDINOTE15,
+       K_MIDINOTE16,
+       K_MIDINOTE17,
+       K_MIDINOTE18,
+       K_MIDINOTE19,
+       K_MIDINOTE20,
+       K_MIDINOTE21,
+       K_MIDINOTE22,
+       K_MIDINOTE23,
+       K_MIDINOTE24,
+       K_MIDINOTE25,
+       K_MIDINOTE26,
+       K_MIDINOTE27,
+       K_MIDINOTE28,
+       K_MIDINOTE29,
+       K_MIDINOTE30,
+       K_MIDINOTE31,
+       K_MIDINOTE32,
+       K_MIDINOTE33,
+       K_MIDINOTE34,
+       K_MIDINOTE35,
+       K_MIDINOTE36,
+       K_MIDINOTE37,
+       K_MIDINOTE38,
+       K_MIDINOTE39,
+       K_MIDINOTE40,
+       K_MIDINOTE41,
+       K_MIDINOTE42,
+       K_MIDINOTE43,
+       K_MIDINOTE44,
+       K_MIDINOTE45,
+       K_MIDINOTE46,
+       K_MIDINOTE47,
+       K_MIDINOTE48,
+       K_MIDINOTE49,
+       K_MIDINOTE50,
+       K_MIDINOTE51,
+       K_MIDINOTE52,
+       K_MIDINOTE53,
+       K_MIDINOTE54,
+       K_MIDINOTE55,
+       K_MIDINOTE56,
+       K_MIDINOTE57,
+       K_MIDINOTE58,
+       K_MIDINOTE59,
+       K_MIDINOTE60,
+       K_MIDINOTE61,
+       K_MIDINOTE62,
+       K_MIDINOTE63,
+       K_MIDINOTE64,
+       K_MIDINOTE65,
+       K_MIDINOTE66,
+       K_MIDINOTE67,
+       K_MIDINOTE68,
+       K_MIDINOTE69,
+       K_MIDINOTE70,
+       K_MIDINOTE71,
+       K_MIDINOTE72,
+       K_MIDINOTE73,
+       K_MIDINOTE74,
+       K_MIDINOTE75,
+       K_MIDINOTE76,
+       K_MIDINOTE77,
+       K_MIDINOTE78,
+       K_MIDINOTE79,
+       K_MIDINOTE80,
+       K_MIDINOTE81,
+       K_MIDINOTE82,
+       K_MIDINOTE83,
+       K_MIDINOTE84,
+       K_MIDINOTE85,
+       K_MIDINOTE86,
+       K_MIDINOTE87,
+       K_MIDINOTE88,
+       K_MIDINOTE89,
+       K_MIDINOTE90,
+       K_MIDINOTE91,
+       K_MIDINOTE92,
+       K_MIDINOTE93,
+       K_MIDINOTE94,
+       K_MIDINOTE95,
+       K_MIDINOTE96,
+       K_MIDINOTE97,
+       K_MIDINOTE98,
+       K_MIDINOTE99,
+       K_MIDINOTE100,
+       K_MIDINOTE101,
+       K_MIDINOTE102,
+       K_MIDINOTE103,
+       K_MIDINOTE104,
+       K_MIDINOTE105,
+       K_MIDINOTE106,
+       K_MIDINOTE107,
+       K_MIDINOTE108,
+       K_MIDINOTE109,
+       K_MIDINOTE110,
+       K_MIDINOTE111,
+       K_MIDINOTE112,
+       K_MIDINOTE113,
+       K_MIDINOTE114,
+       K_MIDINOTE115,
+       K_MIDINOTE116,
+       K_MIDINOTE117,
+       K_MIDINOTE118,
+       K_MIDINOTE119,
+       K_MIDINOTE120,
+       K_MIDINOTE121,
+       K_MIDINOTE122,
+       K_MIDINOTE123,
+       K_MIDINOTE124,
+       K_MIDINOTE125,
+       K_MIDINOTE126,
+       K_MIDINOTE127,
 }
 keynum_t;
 
index 4df5c09..0f54d17 100644 (file)
@@ -1029,3 +1029,15 @@ int S_GetSoundChannels (void){
        Con_Printf("So let's assume 2.\n");
        return 2;
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}
index 3f9534a..59c85ed 100644 (file)
@@ -36,6 +36,7 @@ static snd_pcm_t* pcm_handle = NULL;
 static snd_pcm_sframes_t expected_delay = 0;
 static unsigned int alsasoundtime;
 
+static snd_seq_t* seq_handle = NULL;
 
 /*
 ====================
@@ -47,14 +48,64 @@ May return a suggested format if the requested format isn't available
 */
 qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
 {
-       const char* pcm_name;
-       int i, err;
+       const char* pcm_name, *seq_name;
+       int i, err, seq_client, seq_port;
        snd_pcm_hw_params_t* hw_params = NULL;
        snd_pcm_format_t snd_pcm_format;
        snd_pcm_uframes_t buffer_size;
 
        Con_Print ("SndSys_Init: using the ALSA module\n");
 
+       seq_name = NULL;
+       i = COM_CheckParm ("-sndseqin"); // TODO turn this into a cvar, maybe
+       if (i != 0 && i < com_argc - 1)
+               seq_name = com_argv[i + 1];
+       if(seq_name)
+       {
+               seq_client = atoi(seq_name);
+               seq_port = 0;
+               if(strchr(seq_name, ':'))
+                       seq_port = atoi(strchr(seq_name, ':') + 1);
+               Con_Printf ("SndSys_Init: seq input port has been set to \"%d:%d\". Enabling sequencer input...\n", seq_client, seq_port);
+               err = snd_seq_open (&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0);
+               if (err < 0)
+               {
+                       Con_Print ("SndSys_Init: can't open seq device\n");
+                       goto seqdone;
+               }
+               err = snd_seq_set_client_name(seq_handle, gamename);
+               if (err < 0)
+               {
+                       Con_Print ("SndSys_Init: can't set name of seq device\n");
+                       goto seqerror;
+               }
+               err = snd_seq_create_simple_port(seq_handle, gamename, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
+               if(err < 0)
+               {
+                       Con_Print ("SndSys_Init: can't create seq port\n");
+                       goto seqerror;
+               }
+               err = snd_seq_connect_from(seq_handle, 0, seq_client, seq_port);
+               if(err < 0)
+               {
+                       Con_Printf ("SndSys_Init: can't connect to seq port \"%d:%d\"\n", seq_client, seq_port);
+                       goto seqerror;
+               }
+               err = snd_seq_nonblock(seq_handle, 1);
+               if(err < 0)
+               {
+                       Con_Print ("SndSys_Init: can't make seq nonblocking\n");
+                       goto seqerror;
+               }
+
+               goto seqdone;
+
+seqerror:
+               snd_seq_close(seq_handle);
+               seq_handle = NULL;
+       }
+
+seqdone:
        // Check the requested sound format
        if (requested->width < 1 || requested->width > 2)
        {
@@ -212,7 +263,10 @@ init_error:
 
        if (hw_params != NULL)
                snd_pcm_hw_params_free (hw_params);
-       SndSys_Shutdown ();
+
+       snd_pcm_close(pcm_handle);
+       pcm_handle = NULL;
+
        return false;
 }
 
@@ -226,6 +280,12 @@ Stop the sound card, delete "snd_renderbuffer" and free its other resources
 */
 void SndSys_Shutdown (void)
 {
+       if (seq_handle != NULL)
+       {
+               snd_seq_close(seq_handle);
+               seq_handle = NULL;
+       }
+
        if (pcm_handle != NULL)
        {
                snd_pcm_close(pcm_handle);
@@ -418,3 +478,37 @@ void SndSys_UnlockRenderBuffer (void)
 {
        // Nothing to do
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       snd_seq_event_t *event;
+       if(!seq_handle)
+               return;
+       for(;;)
+       {
+               if(snd_seq_event_input(seq_handle, &event) <= 0)
+                       break;
+               if(event)
+               {
+                       switch(event->type)
+                       {
+                               case SND_SEQ_EVENT_NOTEON:
+                                       if(event->data.note.velocity)
+                                       {
+                                               Key_Event(K_MIDINOTE0 + event->data.note.note, 0, true);
+                                               break;
+                                       }
+                               case SND_SEQ_EVENT_NOTEOFF:
+                                       Key_Event(K_MIDINOTE0 + event->data.note.note, 0, false);
+                                       break;
+                       }
+               }
+       }
+}
index e32766f..85f10df 100644 (file)
--- a/snd_bsd.c
+++ b/snd_bsd.c
@@ -230,3 +230,15 @@ void SndSys_UnlockRenderBuffer (void)
 {
        // Nothing to do
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}
index 91b7760..bbc97c0 100644 (file)
@@ -385,3 +385,15 @@ void SndSys_UnlockRenderBuffer (void)
 {
        pthread_mutex_unlock(&coreaudio_mutex);
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}
index 00a0afb..07cc6e1 100644 (file)
@@ -184,6 +184,9 @@ qboolean SndSys_LockRenderBuffer (void);
 // Release the exclusive lock on "snd_renderbuffer"
 void SndSys_UnlockRenderBuffer (void);
 
+// if the sound system can generate events, send them
+void SndSys_SendKeyEvents(void);
+
 // exported for capturevideo so ogg can see all channels
 typedef struct portable_samplepair_s
 {
index ab5b4c6..0d7276e 100755 (executable)
@@ -147,3 +147,6 @@ float S_GetChannelPosition (unsigned int ch_ind)
        return -1;
 }
 
+void SndSys_SendKeyEvents(void)
+{
+}
index bde3d50..9926b80 100644 (file)
--- a/snd_oss.c
+++ b/snd_oss.c
@@ -330,3 +330,15 @@ void SndSys_UnlockRenderBuffer (void)
 {
        // Nothing to do
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}
index 32990af..88dfade 100644 (file)
--- a/snd_sdl.c
+++ b/snd_sdl.c
@@ -249,3 +249,15 @@ void SndSys_UnlockRenderBuffer (void)
 {
        SDL_UnlockAudio();
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}
index 1228bd7..b1c6b58 100644 (file)
--- a/snd_win.c
+++ b/snd_win.c
@@ -874,3 +874,15 @@ void SndSys_UnlockRenderBuffer (void)
                IDirectSoundBuffer_Unlock(pDSBuf, dsound_pbuf, dsound_dwSize, dsound_pbuf2, dsound_dwSize2);
 #endif
 }
+
+/*
+====================
+SndSys_SendKeyEvents
+
+Send keyboard events originating from the sound system (e.g. MIDI)
+====================
+*/
+void SndSys_SendKeyEvents(void)
+{
+       // not supported
+}