1 
2 /*
3  *  Diverse Bristol midi routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*#define DEBUG */
23 
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 
28 #include <sys/poll.h>
29 
30 #include "bristol.h"
31 #include "bristolmidi.h"
32 
33 extern int acceptConnection();
34 extern int bristolMidiDevRead();
35 extern int checkcallbacks();
36 
37 int midiMode;
38 
39 /*bristolMidiMsg msg; */
40 
41 static fd_set Input_fds;
42 static struct timeval waittime;
43 
44 extern bristolMidiMain bmidi;
45 
46 /*
47  * This needs to go into a separate midi management interface.
48  */
49 int
midiCheck()50 midiCheck()
51 {
52 	int i, max = 0, opens = 0, count = 0;
53 
54 #ifdef DEBUG
55 	printf("midiCheck()\n");
56 #endif
57 
58 	/*
59 	 * This should go into select() over any opened devices.
60 	 */
61 	while (~bmidi.flags & BRISTOL_MIDI_TERMINATE)
62 	{
63 		FD_ZERO(&Input_fds);
64 		count = 0, max = 0;
65 
66 		for (i = 0; i < BRISTOL_MIDI_DEVCOUNT; i++)
67 			if (bmidi.dev[i].fd > 0)
68 			{
69 				/*
70 				 * We will poll for the control socket, and select for the
71 				 * rest.
72 				 */
73 				FD_SET(bmidi.dev[i].fd, &Input_fds);
74 				if (bmidi.dev[i].fd > max)
75 					max = bmidi.dev[i].fd;
76 				count++;
77 			}
78 
79 		if (count == 0) {
80 			usleep(100000);
81 			continue;
82 		}
83 
84 		/*
85 		 * We could wait forever, but use 1 second for now.
86 		 */
87 		waittime.tv_sec = 1;
88 		waittime.tv_usec = 0;
89 
90 		if (select(max + 1, &Input_fds, NULL, NULL, &waittime) > 0)
91 		{
92 			for (i = 0; i < BRISTOL_MIDI_DEVCOUNT; i++)
93 			{
94 				if ((bmidi.dev[i].fd > 0) &&
95 					(FD_ISSET(bmidi.dev[i].fd, &Input_fds)))
96 				{
97 					if (bmidi.dev[i].flags & BRISTOL_ACCEPT_SOCKET)
98 					{
99 						if (acceptConnection(i) >= 0)
100 							opens++;
101 					} else {
102 						if (bristolMidiDevRead(i, &bmidi.dev[i].msg) < 0)
103 						{
104 							if (--opens == 0)
105 							{
106 								/*
107 								 * This should be an optional flag.
108 								 */
109 								if (bmidi.flags & BRISTOL_MIDI_WAIT)
110 								{
111 									printf("Last open conn, exiting\n");
112 									_exit(0);
113 								}
114 							}
115 
116 							/*
117 							 * The next issue we should take care of is the
118 							 * fact that this link has closed. If we had a
119 							 * synth active on this link it will hang around.
120 							 * Unfortunately we can't really do this since
121 							 * there could be multiple registrations for the
122 							 * given channel. Definately for future study. If
123 							 * in doubt, use the '-T' flag to bristol to have
124 							 * it terminate on last close.
125 							bmidi.dev[i].msg.command = MIDI_SYSTEM;
126 							bmidi.dev[i].msg.channel = bmidi.dev[i].lastchan;
127 
128 							bmidi.dev[i].msg.params.bristol.SysID = 83;
129 							bmidi.dev[i].msg.params.bristol.L = 76;
130 							bmidi.dev[i].msg.params.bristol.a = 97;
131 							bmidi.dev[i].msg.params.bristol.b = 98;
132 							bmidi.dev[i].msg.params.bristol.msgLen
133 								= sizeof(bristolMsg);
134 
135 							bmidi.dev[i].msg.params.bristol.msgType =
136 								MSG_TYPE_PARAM;
137 							bmidi.dev[i].msg.params.bristol.operator = 127;
138 							bmidi.dev[i].msg.params.bristol.controller = 0;
139 							bmidi.dev[i].msg.params.bristol.valueLSB =
140 								BRISTOL_EXIT_ALGO & 0x7f;
141 							bmidi.dev[i].msg.params.bristol.valueMSB =
142 								(BRISTOL_EXIT_ALGO >> 7) & 0x7f;
143 							bmidi.dev[i].msg.params.bristol.from = i;
144 							 */
145 
146 							FD_CLR(bmidi.dev[i].fd, &Input_fds);
147 							close(bmidi.dev[i].fd);
148 							bmidi.dev[i].fd = -1;
149 							bmidi.dev[i].state = -1;
150 
151 							//checkcallbacks(&bmidi.dev[i].msg);
152 						}
153 					}
154 				}
155 			}
156 		}
157 	}
158 
159 	return(0);
160 }
161 
162