From 65f6c04779aa58c69929e0d22967bf152dac17c1 Mon Sep 17 00:00:00 2001 From: divverent Date: Fri, 25 Sep 2009 12:59:45 +0000 Subject: [PATCH] snd_alsa: MIDI input support! MIDI events get mapped to MIDINOTE events (n = 0 to 127) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9232 d7cf8633-e32d-0410-b094-e92efae38249 --- host.c | 2 + keys.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ keys.h | 128 +++++++++++++++++++++++++++++++++++++++++++++++ snd_3dras.c | 12 +++++ snd_alsa.c | 100 +++++++++++++++++++++++++++++++++++-- snd_bsd.c | 12 +++++ snd_coreaudio.c | 12 +++++ snd_main.h | 3 ++ snd_null.c | 3 ++ snd_oss.c | 12 +++++ snd_sdl.c | 12 +++++ snd_win.c | 12 +++++ 12 files changed, 434 insertions(+), 3 deletions(-) diff --git a/host.c b/host.c index 8e2181df..f70a17f7 100644 --- 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 879944f9..fe4e8cce 100644 --- 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 beb5df69..6c04e094 100644 --- 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; diff --git a/snd_3dras.c b/snd_3dras.c index 4df5c09e..0f54d174 100644 --- a/snd_3dras.c +++ b/snd_3dras.c @@ -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 +} diff --git a/snd_alsa.c b/snd_alsa.c index 3f9534ae..59c85edf 100644 --- a/snd_alsa.c +++ b/snd_alsa.c @@ -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; + } + } + } +} diff --git a/snd_bsd.c b/snd_bsd.c index e32766f1..85f10df4 100644 --- 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 +} diff --git a/snd_coreaudio.c b/snd_coreaudio.c index 91b77603..bbc97c07 100644 --- a/snd_coreaudio.c +++ b/snd_coreaudio.c @@ -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 +} diff --git a/snd_main.h b/snd_main.h index 00a0afb0..07cc6e11 100644 --- a/snd_main.h +++ b/snd_main.h @@ -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 { diff --git a/snd_null.c b/snd_null.c index ab5b4c6e..0d7276ea 100755 --- a/snd_null.c +++ b/snd_null.c @@ -147,3 +147,6 @@ float S_GetChannelPosition (unsigned int ch_ind) return -1; } +void SndSys_SendKeyEvents(void) +{ +} diff --git a/snd_oss.c b/snd_oss.c index bde3d508..9926b800 100644 --- 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 +} diff --git a/snd_sdl.c b/snd_sdl.c index 32990af8..88dfade6 100644 --- 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 +} diff --git a/snd_win.c b/snd_win.c index 1228bd7f..b1c6b58b 100644 --- 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 +} -- 2.39.2