summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/s_midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/s_midi.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/s_midi.c640
1 files changed, 0 insertions, 640 deletions
diff --git a/apps/plugins/pdbox/PDa/src/s_midi.c b/apps/plugins/pdbox/PDa/src/s_midi.c
index 4338b49432..72a8792b25 100644
--- a/apps/plugins/pdbox/PDa/src/s_midi.c
+++ b/apps/plugins/pdbox/PDa/src/s_midi.c
@@ -639,644 +639,4 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
639 sys_close_midi(); 639 sys_close_midi();
640 sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev); 640 sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev);
641} 641}
642/* Copyright (c) 1997-1999 Miller Puckette and others.
643* For information on usage and redistribution, and for a DISCLAIMER OF ALL
644* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
645
646/* Clock functions (which should move, but where?) and MIDI queueing */
647
648#include "m_pd.h"
649#include "s_stuff.h"
650#include "m_imp.h"
651#ifdef UNIX
652#include <unistd.h>
653#include <sys/time.h>
654#ifdef HAVE_BSTRING_H
655#include <bstring.h>
656#endif
657#endif
658#ifdef MSW
659#include <winsock.h>
660#include <sys/types.h>
661#include <sys/timeb.h>
662#include <wtypes.h>
663#endif
664#include <string.h>
665#include <stdio.h>
666#include <signal.h>
667
668typedef struct _midiqelem
669{
670 double q_time;
671 int q_portno;
672 unsigned char q_onebyte;
673 unsigned char q_byte1;
674 unsigned char q_byte2;
675 unsigned char q_byte3;
676} t_midiqelem;
677
678#define MIDIQSIZE 1024
679
680t_midiqelem midi_outqueue[MIDIQSIZE];
681int midi_outhead, midi_outtail;
682t_midiqelem midi_inqueue[MIDIQSIZE];
683int midi_inhead, midi_intail;
684static double sys_midiinittime;
685
686 /* this is our current estimate for at what "system" real time the
687 current logical time's output should occur. */
688static double sys_dactimeminusrealtime;
689 /* same for input, should be schduler advance earlier. */
690static double sys_adctimeminusrealtime;
691
692static double sys_newdactimeminusrealtime = -1e20;
693static double sys_newadctimeminusrealtime = -1e20;
694static double sys_whenupdate;
695
696void sys_initmidiqueue( void)
697{
698 sys_midiinittime = clock_getlogicaltime();
699 sys_dactimeminusrealtime = sys_adctimeminusrealtime = 0;
700}
701
702 /* this is called from the OS dependent code from time to time when we
703 think we know the delay (outbuftime) in seconds, at which the last-output
704 audio sample will go out the door. */
705void sys_setmiditimediff(double inbuftime, double outbuftime)
706{
707 double dactimeminusrealtime =
708 .001 * clock_gettimesince(sys_midiinittime)
709 - outbuftime - sys_getrealtime();
710 double adctimeminusrealtime =
711 .001 * clock_gettimesince(sys_midiinittime)
712 + inbuftime - sys_getrealtime();
713 if (dactimeminusrealtime > sys_newdactimeminusrealtime)
714 sys_newdactimeminusrealtime = dactimeminusrealtime;
715 if (adctimeminusrealtime > sys_newadctimeminusrealtime)
716 sys_newadctimeminusrealtime = adctimeminusrealtime;
717 if (sys_getrealtime() > sys_whenupdate)
718 {
719 sys_dactimeminusrealtime = sys_newdactimeminusrealtime;
720 sys_adctimeminusrealtime = sys_newadctimeminusrealtime;
721 sys_newdactimeminusrealtime = -1e20;
722 sys_newadctimeminusrealtime = -1e20;
723 sys_whenupdate = sys_getrealtime() + 1;
724 }
725}
726
727 /* return the logical time of the DAC sample we believe is currently
728 going out, based on how much "system time" has elapsed since the
729 last time sys_setmiditimediff got called. */
730static double sys_getmidioutrealtime( void)
731{
732 return (sys_getrealtime() + sys_dactimeminusrealtime);
733}
734
735static double sys_getmidiinrealtime( void)
736{
737 return (sys_getrealtime() + sys_adctimeminusrealtime);
738}
739
740static void sys_putnext( void)
741{
742 int portno = midi_outqueue[midi_outtail].q_portno;
743 if (midi_outqueue[midi_outtail].q_onebyte)
744 sys_putmidibyte(portno, midi_outqueue[midi_outtail].q_byte1);
745 else sys_putmidimess(portno, midi_outqueue[midi_outtail].q_byte1,
746 midi_outqueue[midi_outtail].q_byte2,
747 midi_outqueue[midi_outtail].q_byte3);
748 midi_outtail = (midi_outtail + 1 == MIDIQSIZE ? 0 : midi_outtail + 1);
749}
750
751/* #define TEST_DEJITTER */
752
753void sys_pollmidioutqueue( void)
754{
755#ifdef TEST_DEJITTER
756 static int db = 0;
757#endif
758 double midirealtime = sys_getmidioutrealtime();
759#ifdef TEST_DEJITTER
760 if (midi_outhead == midi_outtail)
761 db = 0;
762#endif
763 while (midi_outhead != midi_outtail)
764 {
765#ifdef TEST_DEJITTER
766 if (!db)
767 {
768 post("out: del %f, midiRT %f logicaltime %f, RT %f dacminusRT %f",
769 (midi_outqueue[midi_outtail].q_time - midirealtime),
770 midirealtime, .001 * clock_gettimesince(sys_midiinittime),
771 sys_getrealtime(), sys_dactimeminusrealtime);
772 db = 1;
773 }
774#endif
775 if (midi_outqueue[midi_outtail].q_time <= midirealtime)
776 sys_putnext();
777 else break;
778 }
779}
780
781static void sys_queuemidimess(int portno, int onebyte, int a, int b, int c)
782{
783 t_midiqelem *midiqelem;
784 int newhead = midi_outhead +1;
785 if (newhead == MIDIQSIZE)
786 newhead = 0;
787 /* if FIFO is full flush an element to make room */
788 if (newhead == midi_outtail)
789 sys_putnext();
790 midi_outqueue[midi_outhead].q_portno = portno;
791 midi_outqueue[midi_outhead].q_onebyte = onebyte;
792 midi_outqueue[midi_outhead].q_byte1 = a;
793 midi_outqueue[midi_outhead].q_byte2 = b;
794 midi_outqueue[midi_outhead].q_byte3 = c;
795 midi_outqueue[midi_outhead].q_time =
796 .001 * clock_gettimesince(sys_midiinittime);
797 midi_outhead = newhead;
798 sys_pollmidioutqueue();
799}
800
801#define MIDI_NOTEON 144
802#define MIDI_POLYAFTERTOUCH 160
803#define MIDI_CONTROLCHANGE 176
804#define MIDI_PROGRAMCHANGE 192
805#define MIDI_AFTERTOUCH 208
806#define MIDI_PITCHBEND 224
807
808void outmidi_noteon(int portno, int channel, int pitch, int velo)
809{
810 if (pitch < 0) pitch = 0;
811 else if (pitch > 127) pitch = 127;
812 if (velo < 0) velo = 0;
813 else if (velo > 127) velo = 127;
814 sys_queuemidimess(portno, 0, MIDI_NOTEON + (channel & 0xf), pitch, velo);
815}
816
817void outmidi_controlchange(int portno, int channel, int ctl, int value)
818{
819 if (ctl < 0) ctl = 0;
820 else if (ctl > 127) ctl = 127;
821 if (value < 0) value = 0;
822 else if (value > 127) value = 127;
823 sys_queuemidimess(portno, 0, MIDI_CONTROLCHANGE + (channel & 0xf),
824 ctl, value);
825}
826
827void outmidi_programchange(int portno, int channel, int value)
828{
829 if (value < 0) value = 0;
830 else if (value > 127) value = 127;
831 sys_queuemidimess(portno, 0,
832 MIDI_PROGRAMCHANGE + (channel & 0xf), value, 0);
833}
834
835void outmidi_pitchbend(int portno, int channel, int value)
836{
837 if (value < 0) value = 0;
838 else if (value > 16383) value = 16383;
839 sys_queuemidimess(portno, 0, MIDI_PITCHBEND + (channel & 0xf),
840 (value & 127), ((value>>7) & 127));
841}
842
843void outmidi_aftertouch(int portno, int channel, int value)
844{
845 if (value < 0) value = 0;
846 else if (value > 127) value = 127;
847 sys_queuemidimess(portno, 0, MIDI_AFTERTOUCH + (channel & 0xf), value, 0);
848}
849
850void outmidi_polyaftertouch(int portno, int channel, int pitch, int value)
851{
852 if (pitch < 0) pitch = 0;
853 else if (pitch > 127) pitch = 127;
854 if (value < 0) value = 0;
855 else if (value > 127) value = 127;
856 sys_queuemidimess(portno, 0, MIDI_POLYAFTERTOUCH + (channel & 0xf),
857 pitch, value);
858}
859
860void outmidi_mclk(int portno)
861{
862 sys_queuemidimess(portno, 1, 0xf8, 0,0);
863}
864
865/* ------------------------- MIDI input queue handling ------------------ */
866typedef struct midiparser
867{
868 int mp_status;
869 int mp_gotbyte1;
870 int mp_byte1;
871} t_midiparser;
872
873#define MIDINOTEOFF 0x80 /* 2 following 'data bytes' */
874#define MIDINOTEON 0x90 /* 2 */
875#define MIDIPOLYTOUCH 0xa0 /* 2 */
876#define MIDICONTROLCHANGE 0xb0 /* 2 */
877#define MIDIPROGRAMCHANGE 0xc0 /* 1 */
878#define MIDICHANNELTOUCH 0xd0 /* 1 */
879#define MIDIPITCHBEND 0xe0 /* 2 */
880#define MIDISTARTSYSEX 0xf0 /* (until F7) */
881#define MIDITIMECODE 0xf1 /* 1 */
882#define MIDISONGPOS 0xf2 /* 2 */
883#define MIDISONGSELECT 0xf3 /* 1 */
884#define MIDIRESERVED1 0xf4 /* ? */
885#define MIDIRESERVED2 0xf5 /* ? */
886#define MIDITUNEREQUEST 0xf6 /* 0 */
887#define MIDIENDSYSEX 0xf7 /* 0 */
888#define MIDICLOCK 0xf8 /* 0 */
889#define MIDITICK 0xf9 /* 0 */
890#define MIDISTART 0xfa /* 0 */
891#define MIDICONT 0xfb /* 0 */
892#define MIDISTOP 0xfc /* 0 */
893#define MIDIACTIVESENSE 0xfe /* 0 */
894#define MIDIRESET 0xff /* 0 */
895
896 /* functions in x_midi.c */
897void inmidi_realtimein(int portno, int cmd);
898void inmidi_byte(int portno, int byte);
899void inmidi_sysex(int portno, int byte);
900void inmidi_noteon(int portno, int channel, int pitch, int velo);
901void inmidi_controlchange(int portno, int channel, int ctlnumber, int value);
902void inmidi_programchange(int portno, int channel, int value);
903void inmidi_pitchbend(int portno, int channel, int value);
904void inmidi_aftertouch(int portno, int channel, int value);
905void inmidi_polyaftertouch(int portno, int channel, int pitch, int value);
906
907static void sys_dispatchnextmidiin( void)
908{
909 static t_midiparser parser[MAXMIDIINDEV], *parserp;
910 int portno = midi_inqueue[midi_intail].q_portno,
911 byte = midi_inqueue[midi_intail].q_byte1;
912 if (!midi_inqueue[midi_intail].q_onebyte)
913 bug("sys_dispatchnextmidiin");
914 if (portno < 0 || portno >= MAXMIDIINDEV)
915 bug("sys_dispatchnextmidiin 2");
916 parserp = parser + portno;
917 outlet_setstacklim();
918
919 if (byte >= 0xf8)
920 inmidi_realtimein(portno, byte);
921 else
922 {
923 inmidi_byte(portno, byte);
924 if (byte & 0x80)
925 {
926 if (byte == MIDITUNEREQUEST || byte == MIDIRESERVED1 ||
927 byte == MIDIRESERVED2)
928 parserp->mp_status = 0;
929 else if (byte == MIDISTARTSYSEX)
930 {
931 inmidi_sysex(portno, byte);
932 parserp->mp_status = byte;
933 }
934 else if (byte == MIDIENDSYSEX)
935 {
936 inmidi_sysex(portno, byte);
937 parserp->mp_status = 0;
938 }
939 else
940 {
941 parserp->mp_status = byte;
942 }
943 parserp->mp_gotbyte1 = 0;
944 }
945 else
946 {
947 int cmd = (parserp->mp_status >= 0xf0 ? parserp->mp_status :
948 (parserp->mp_status & 0xf0));
949 int chan = (parserp->mp_status & 0xf);
950 int byte1 = parserp->mp_byte1, gotbyte1 = parserp->mp_gotbyte1;
951 switch (cmd)
952 {
953 case MIDINOTEOFF:
954 if (gotbyte1)
955 inmidi_noteon(portno, chan, byte1, 0),
956 parserp->mp_gotbyte1 = 0;
957 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
958 break;
959 case MIDINOTEON:
960 if (gotbyte1)
961 inmidi_noteon(portno, chan, byte1, byte),
962 parserp->mp_gotbyte1 = 0;
963 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
964 break;
965 case MIDIPOLYTOUCH:
966 if (gotbyte1)
967 inmidi_polyaftertouch(portno, chan, byte1, byte),
968 parserp->mp_gotbyte1 = 0;
969 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
970 break;
971 case MIDICONTROLCHANGE:
972 if (gotbyte1)
973 inmidi_controlchange(portno, chan, byte1, byte),
974 parserp->mp_gotbyte1 = 0;
975 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
976 break;
977 case MIDIPROGRAMCHANGE:
978 inmidi_programchange(portno, chan, byte);
979 break;
980 case MIDICHANNELTOUCH:
981 inmidi_aftertouch(portno, chan, byte);
982 break;
983 case MIDIPITCHBEND:
984 if (gotbyte1)
985 inmidi_pitchbend(portno, chan, ((byte << 7) + byte1)),
986 parserp->mp_gotbyte1 = 0;
987 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
988 break;
989 case MIDISTARTSYSEX:
990 inmidi_sysex(portno, byte);
991 break;
992
993 /* other kinds of messages are just dropped here. We'll
994 need another status byte before we start letting MIDI in
995 again (no running status across "system" messages). */
996 case MIDITIMECODE: /* 1 data byte*/
997 break;
998 case MIDISONGPOS: /* 2 */
999 break;
1000 case MIDISONGSELECT: /* 1 */
1001 break;
1002 }
1003 }
1004 }
1005 midi_intail = (midi_intail + 1 == MIDIQSIZE ? 0 : midi_intail + 1);
1006}
1007
1008void sys_pollmidiinqueue( void)
1009{
1010#ifdef TEST_DEJITTER
1011 static int db = 0;
1012#endif
1013 double logicaltime = .001 * clock_gettimesince(sys_midiinittime);
1014#ifdef TEST_DEJITTER
1015 if (midi_inhead == midi_intail)
1016 db = 0;
1017#endif
1018 while (midi_inhead != midi_intail)
1019 {
1020#ifdef TEST_DEJITTER
1021 if (!db)
1022 {
1023 post("in del %f, logicaltime %f, RT %f adcminusRT %f",
1024 (midi_inqueue[midi_intail].q_time - logicaltime),
1025 logicaltime, sys_getrealtime(), sys_adctimeminusrealtime);
1026 db = 1;
1027 }
1028#endif
1029#if 0
1030 if (midi_inqueue[midi_intail].q_time <= logicaltime - 0.007)
1031 post("late %f",
1032 1000 * (logicaltime - midi_inqueue[midi_intail].q_time));
1033#endif
1034 if (midi_inqueue[midi_intail].q_time <= logicaltime)
1035 {
1036#if 0
1037 post("diff %f",
1038 1000* (logicaltime - midi_inqueue[midi_intail].q_time));
1039#endif
1040 sys_dispatchnextmidiin();
1041 }
1042 else break;
1043 }
1044}
1045
1046 /* this should be called from the system dependent MIDI code when a byte
1047 comes in, as a result of our calling sys_poll_midi. We stick it on a
1048 timetag queue and dispatch it at the appropriate logical time. */
1049
1050
1051void sys_midibytein(int portno, int byte)
1052{
1053 static int warned = 0;
1054 t_midiqelem *midiqelem;
1055 int newhead = midi_inhead +1;
1056 if (newhead == MIDIQSIZE)
1057 newhead = 0;
1058 /* if FIFO is full flush an element to make room */
1059 if (newhead == midi_intail)
1060 {
1061 if (!warned)
1062 {
1063 post("warning: MIDI timing FIFO overflowed");
1064 warned = 1;
1065 }
1066 sys_dispatchnextmidiin();
1067 }
1068 midi_inqueue[midi_inhead].q_portno = portno;
1069 midi_inqueue[midi_inhead].q_onebyte = 1;
1070 midi_inqueue[midi_inhead].q_byte1 = byte;
1071 midi_inqueue[midi_inhead].q_time = sys_getmidiinrealtime();
1072 midi_inhead = newhead;
1073 sys_pollmidiinqueue();
1074}
1075
1076void sys_pollmidiqueue( void)
1077{
1078#if 0
1079 static double lasttime;
1080 double newtime = sys_getrealtime();
1081 if (newtime - lasttime > 0.007)
1082 post("delay %d", (int)(1000 * (newtime - lasttime)));
1083 lasttime = newtime;
1084#endif
1085 sys_poll_midi(); /* OS dependent poll for MIDI input */
1086 sys_pollmidioutqueue();
1087 sys_pollmidiinqueue();
1088}
1089
1090/******************** dialog window and device listing ********************/
1091
1092#ifdef USEAPI_OSS
1093void midi_oss_init( void);
1094#endif
1095
1096 /* last requested parameters */
1097static int midi_nmidiindev;
1098static int midi_midiindev[MAXMIDIINDEV];
1099static int midi_nmidioutdev;
1100static int midi_midioutdev[MAXMIDIOUTDEV];
1101
1102static void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
1103 int *pnmidioutdev, int *pmidioutdev)
1104{
1105 int i;
1106 *pnmidiindev = midi_nmidiindev;
1107 for (i = 0; i < MAXMIDIINDEV; i++)
1108 pmidiindev[i] = midi_midiindev[i];
1109 *pnmidioutdev = midi_nmidioutdev;
1110 for (i = 0; i < MAXMIDIOUTDEV; i++)
1111 pmidioutdev[i] = midi_midioutdev[i];
1112}
1113
1114static void sys_save_midi_params(
1115 int nmidiindev, int *midiindev,
1116 int nmidioutdev, int *midioutdev)
1117{
1118 int i;
1119 midi_nmidiindev = nmidiindev;
1120 for (i = 0; i < MAXMIDIINDEV; i++)
1121 midi_midiindev[i] = midiindev[i];
1122 midi_nmidioutdev = nmidioutdev;
1123 for (i = 0; i < MAXMIDIOUTDEV; i++)
1124 midi_midioutdev[i] = midioutdev[i];
1125}
1126
1127void sys_open_midi(int nmidiindev, int *midiindev,
1128 int nmidioutdev, int *midioutdev)
1129{
1130#ifdef USEAPI_OSS
1131 midi_oss_init();
1132#endif
1133 sys_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
1134 sys_save_midi_params(nmidiindev, midiindev,
1135 nmidioutdev, midioutdev);
1136}
1137
1138 /* open midi using whatever parameters were last used */
1139void sys_reopen_midi( void)
1140{
1141 int nmidiindev, midiindev[MAXMIDIINDEV];
1142 int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
1143 sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev);
1144 sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
1145}
1146
1147#define MAXNDEV 20
1148#define DEVDESCSIZE 80
1149
1150#ifdef MSW
1151#define DEVONSET 0 /* microsoft device list starts at 0 (the "mapper"). */
1152#else /* (see also MSW ifdef in sys_parsedevlist(), s_main.c) */
1153#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */
1154#endif
1155
1156void sys_listmididevs(void )
1157{
1158 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
1159 int nindevs = 0, noutdevs = 0, i;
1160
1161 midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
1162 MAXNDEV, DEVDESCSIZE);
1163
1164 if (!nindevs)
1165 post("no midi input devices found");
1166 else
1167 {
1168 post("input devices:");
1169 for (i = 0; i < nindevs; i++)
1170 post("%d. %s", i+1, indevlist + i * DEVDESCSIZE);
1171 }
1172 if (!noutdevs)
1173 post("no midi output devices found");
1174 else
1175 {
1176 post("output devices:");
1177 for (i = 0; i < noutdevs; i++)
1178 post("%d. %s", i+DEVONSET, outdevlist + i * DEVDESCSIZE);
1179 }
1180}
1181
1182extern t_class *glob_pdobject;
1183
1184 /* start an midi settings dialog window */
1185void glob_midi_properties(t_pd *dummy, t_floatarg flongform)
1186{
1187 char buf[1024 + 2 * MAXNDEV*(DEVDESCSIZE+4)];
1188 /* these are the devices you're using: */
1189 int nindev, midiindev[MAXMIDIINDEV];
1190 int noutdev, midioutdev[MAXMIDIOUTDEV];
1191 int midiindev1, midiindev2, midiindev3, midiindev4,
1192 midioutdev1, midioutdev2, midioutdev3, midioutdev4;
1193
1194 /* these are all the devices on your system: */
1195 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
1196 int nindevs = 0, noutdevs = 0, i;
1197
1198 char indevliststring[MAXNDEV*(DEVDESCSIZE+4)+80],
1199 outdevliststring[MAXNDEV*(DEVDESCSIZE+4)+80];
1200
1201 midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
1202 MAXNDEV, DEVDESCSIZE);
1203
1204 strcpy(indevliststring, "{ {none} ");
1205 for (i = 0; i < nindevs; i++)
1206 {
1207 strcat(indevliststring, "\"");
1208 strcat(indevliststring, indevlist + i * DEVDESCSIZE);
1209 strcat(indevliststring, "\" ");
1210 }
1211 strcat(indevliststring, "}");
1212
1213 strcpy(outdevliststring, "{ {none} ");
1214 for (i = 0; i < noutdevs; i++)
1215 {
1216 strcat(outdevliststring, "\"");
1217 strcat(outdevliststring, outdevlist + i * DEVDESCSIZE);
1218 strcat(outdevliststring, "\" ");
1219 }
1220 strcat(outdevliststring, "}");
1221
1222 sys_get_midi_params(&nindev, midiindev, &noutdev, midioutdev);
1223
1224 if (nindev > 1 || noutdev > 1)
1225 flongform = 1;
1226
1227 midiindev1 = (nindev > 0 && midiindev[0]>= 0 ? midiindev[0]+1 : 0);
1228 midiindev2 = (nindev > 1 && midiindev[1]>= 0 ? midiindev[1]+1 : 0);
1229 midiindev3 = (nindev > 2 && midiindev[2]>= 0 ? midiindev[2]+1 : 0);
1230 midiindev4 = (nindev > 3 && midiindev[3]>= 0 ? midiindev[3]+1 : 0);
1231 midioutdev1 = (noutdev > 0 && midioutdev[0]>=0 ? midioutdev[0]+1 : 0);
1232 midioutdev2 = (noutdev > 1 && midioutdev[1]>=0 ? midioutdev[1]+1 : 0);
1233 midioutdev3 = (noutdev > 2 && midioutdev[2]>=0 ? midioutdev[2]+1 : 0);
1234 midioutdev4 = (noutdev > 3 && midioutdev[3]>=0 ? midioutdev[3]+1 : 0);
1235
1236 sprintf(buf,
1237"pdtk_midi_dialog %%s \
1238%s %d %d %d %d %s %d %d %d %d \
1239%d\n",
1240 indevliststring,
1241 midiindev1, midiindev2, midiindev3, midiindev4,
1242 outdevliststring,
1243 midioutdev1, midioutdev2, midioutdev3, midioutdev4,
1244 (flongform != 0));
1245 gfxstub_deleteforkey(0);
1246 gfxstub_new(&glob_pdobject, glob_midi_properties, buf);
1247}
1248
1249 /* new values from dialog window */
1250void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
1251{
1252 int nmidiindev, midiindev[MAXMIDIINDEV];
1253 int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
1254 int i, nindev, noutdev;
1255 int newmidiindev[4], newmidioutdev[4];
1256
1257 for (i = 0; i < 4; i++)
1258 {
1259 newmidiindev[i] = atom_getintarg(i, argc, argv);
1260 newmidioutdev[i] = atom_getintarg(i+4, argc, argv);
1261 }
1262 642
1263 for (i = 0, nindev = 0; i < 4; i++)
1264 {
1265 if (newmidiindev[i] > 0)
1266 {
1267 newmidiindev[nindev] = newmidiindev[i]-1;
1268 nindev++;
1269 }
1270 }
1271 for (i = 0, noutdev = 0; i < 4; i++)
1272 {
1273 if (newmidioutdev[i] > 0)
1274 {
1275 newmidioutdev[noutdev] = newmidioutdev[i]-1;
1276 noutdev++;
1277 }
1278 }
1279
1280 sys_close_midi();
1281 sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev);
1282}