From 4cbd55491dd86ea99e1ea8190a20bd13e0f328ae Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Sat, 16 Jul 2005 01:43:18 +0000 Subject: fixed bugs, adopted some patches. svn path=/trunk/; revision=3347 --- pd/src/s_midi_alsa.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 pd/src/s_midi_alsa.c (limited to 'pd/src/s_midi_alsa.c') diff --git a/pd/src/s_midi_alsa.c b/pd/src/s_midi_alsa.c new file mode 100644 index 00000000..437ac792 --- /dev/null +++ b/pd/src/s_midi_alsa.c @@ -0,0 +1,233 @@ +/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler, +* Winfried Ritsch, Karl MacMillan, and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* MIDI I/O for Linux using ALSA */ + +#include +#ifdef UNISTD +#include +#endif +#include +#include +#include +#include +#include +#include +#include "m_pd.h" +#include "s_stuff.h" + +static int alsa_nmidiin; +static int alsa_midiinfd[MAXMIDIINDEV]; +static int alsa_nmidiout; +static int alsa_midioutfd[MAXMIDIOUTDEV]; + +static snd_seq_t *midi_handle; + +static snd_midi_event_t *midiev; + + + +static unsigned short CombineBytes(unsigned char First, unsigned char Second) +{ + unsigned short _14bit; + _14bit = (unsigned short)Second; + _14bit <<= 7; + _14bit |= (unsigned short)First; + return(_14bit); +} + +void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, + int nmidiout, int *midioutvec) +{ + + char portname[50]; + int err = 0; + int client; + int i; + alsa_nmidiin = 0; + alsa_nmidiout = 0; + + if (nmidiin>0 && nmidiout>0) + err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0); + else if (nmidiin > 0) + err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0); + else if (nmidiout > 0) + err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0); + + if (err!=0) + { + sys_setalarm(1000000); + post("couldn't open alsa sequencer"); + return; + } + for (i=0;i= 0 && portno < alsa_nmidiout) + { + if (a >= 224) // pitchbend + { + channel = a-224; + snd_seq_ev_set_pitchbend(&ev,channel,CombineBytes(b,c)); + } + else if (a >= 208) // touch + { + channel = a-208; + snd_seq_ev_set_chanpress(&ev,channel,b); + } + else if (a >= 192) // program + { + channel = a-192; + snd_seq_ev_set_pgmchange(&ev,channel,b); + } + else if (a >= 176) // controller + { + channel = a-176; + snd_seq_ev_set_controller(&ev,channel,b,c); + } + else if (a >= 160) // polytouch + { + channel = a-160; + snd_seq_ev_set_keypress(&ev,channel,b,c); + } + else if (a >= 144) // note + { + channel = a-144; + if (c) + snd_seq_ev_set_noteon(&ev,channel,b,c); + else + snd_seq_ev_set_noteoff(&ev,channel,b,c); + } + snd_seq_ev_set_direct(&ev); + snd_seq_ev_set_subs(&ev); + snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]); + snd_seq_event_output_direct(midi_handle,&ev); + } + //post("%d %d %d\n",a,b,c); +} + +void sys_alsa_putmidibyte(int portno, int byte) +{ + snd_seq_event_t ev; + snd_seq_ev_clear(&ev); + if (portno >= 0 && portno < alsa_nmidiout) + { + // repack into 1 byte char and put somewhere to point at + unsigned char data = (unsigned char)byte; + unsigned char *dataptr = malloc(1); + memcpy(dataptr,&byte,1); + + snd_seq_ev_set_sysex(&ev,1,dataptr); //...set_variable *should* have worked but didn't + snd_seq_ev_set_direct(&ev); + snd_seq_ev_set_subs(&ev); + snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]); + snd_seq_event_output_direct(midi_handle,&ev); + } +} + + + /* this version uses the asynchronous "read()" ... */ +void sys_alsa_poll_midi(void) +{ + char buf[20]; + int count, alsa_source; + int i; + snd_seq_event_t *midievent = NULL; + + if (alsa_nmidiout == 0 && alsa_nmidiin == 0) return; + + snd_midi_event_init(midiev); + + if (!alsa_nmidiout && !alsa_nmidiin) return; + count = snd_seq_event_input_pending(midi_handle,1); + if (count != 0) + count = snd_seq_event_input(midi_handle,&midievent); + if (midievent != NULL) + { + count = snd_midi_event_decode(midiev,buf,20,midievent); + alsa_source = midievent->dest.port; + for(i=0;i maxndev) + ndev = maxndev; + for (i = 0; i < ndev; i++) + sprintf(indevlist + i * devdescsize, "ALSA MIDI device #%d", i+1); + *nindevs = ndev; + + if ((ndev = alsa_nmidioutdevs) > maxndev) + ndev = maxndev; + for (i = 0; i < ndev; i++) + sprintf(outdevlist + i * devdescsize, "ALSA MIDI device #%d", i+1); + *noutdevs = ndev; +} -- cgit v1.2.1