1 
2 /*
3 #    Sfront, a SAOL to C translator
4 #    This file: Network library -- receiver journal functions
5 #
6 # Copyright (c) 2000-2006, Regents of the University of California
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 #  Redistributions of source code must retain the above copyright
14 #  notice, this list of conditions and the following disclaimer.
15 #
16 #  Redistributions in binary form must reproduce the above copyright
17 #  notice, this list of conditions and the following disclaimer in the
18 #  documentation and/or other materials provided with the distribution.
19 #
20 #  Neither the name of the University of California, Berkeley nor the
21 #  names of its contributors may be used to endorse or promote products
22 #  derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #
36 #    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
37 */
38 
39 
40 #ifndef NSYS_NET
41 #include "net_include.h"
42 #endif
43 
44 
45 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
46 /*     high-level functions: receiving recovery journals        */
47 /*______________________________________________________________*/
48 
49 
50 /****************************************************************/
51 /*          main routine for parsing recovery journal           */
52 /****************************************************************/
53 
nsys_netin_journal_recovery(nsys_source * sptr,int rtpcode,unsigned char * packet,int numbytes,unsigned char * buff,long * fill,long size)54 int nsys_netin_journal_recovery(nsys_source * sptr, int rtpcode,
55 				unsigned char * packet,
56 				int numbytes, unsigned char * buff,
57 				long * fill, long size)
58 
59 {
60   nsys_netout_jrecv_state * jrecv;
61   nsys_netout_jrecv_system_state * jrecvsys;
62   int numchan, bflag, i, j;
63   short chanlen, syslen, loglen, cmdlen, paramlen;
64   unsigned char chan, low, high, many, sysj, chanj;
65   unsigned char chapters, schapters, dchapters;
66   unsigned char * checkptr, * p, * ps;
67 
68   if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
69     {
70       printf("\ndoing recovery for mset%i (fill: %i)\n", sptr->mset,
71 	     (j = (*fill)));
72 
73 #if (NSYS_LATENOTES_DEBUG == NSYS_LATENOTES_DEBUG_ON)
74       if (sptr->tm_margin)
75 	printf("Time: %f\n", (nsys_netout_tstamp - sptr->tm_first)/EV(ARATE));
76 #endif
77 
78       fflush(stdout);
79     }
80 
81   if ((numbytes -= 1) < NSYS_SM_JH_SIZE)
82     return NSYS_JOURNAL_CORRUPTED;
83 
84   cmdlen = (*packet) & NSYS_SM_MLENMASK;
85 
86   if ((*packet) & NSYS_SM_CHKB)
87     {
88       if ((numbytes -= 1) < NSYS_SM_JH_SIZE)
89 	return NSYS_JOURNAL_CORRUPTED;
90 
91       cmdlen = packet[1] + (cmdlen << 8);
92       packet += 1;
93     }
94 
95   if ((numbytes -= cmdlen) < NSYS_SM_JH_SIZE)
96     return NSYS_JOURNAL_CORRUPTED;
97 
98   packet += 1 + cmdlen;
99   many = (rtpcode == NSYS_RTPCODE_LOSTMANY);
100 
101   sysj = (packet[NSYS_SM_JH_LOC_FLAGS] & NSYS_SM_JH_CHKY);
102   chanj = (packet[NSYS_SM_JH_LOC_FLAGS] & NSYS_SM_JH_CHKA);
103 
104   if ((!sysj && !chanj) ||
105       ((packet[NSYS_SM_JH_LOC_FLAGS] & NSYS_SM_CHKS) && (!many)))
106     return NSYS_JOURNAL_RECOVERED;
107 
108   numchan = chanj ? (packet[NSYS_SM_JH_LOC_FLAGS] & NSYS_SM_JH_CHANMASK) + 1 : 0;
109   checkptr = &(packet[NSYS_SM_JH_LOC_CHECK]);
110 
111   numbytes -= NSYS_SM_JH_SIZE;
112   packet += NSYS_SM_JH_SIZE;
113 
114   if (sysj)
115     {
116       if (numbytes < NSYS_SM_SH_SIZE)
117 	return NSYS_JOURNAL_CORRUPTED;
118 
119       if ((jrecvsys = sptr->jrecvsys) == NULL)
120 	jrecvsys = sptr->jrecvsys = nsys_netin_newrecvsys();
121 
122       schapters = packet[NSYS_SM_SH_LOC_FLAGS];
123       syslen = packet[NSYS_SM_SH_LOC_LENLSB] + ((schapters & NSYS_SM_SH_MSBMASK) << 8);
124 
125       if ((numbytes -= syslen) < 0)
126 	return NSYS_JOURNAL_CORRUPTED;
127 
128       ps = packet + NSYS_SM_SH_SIZE;
129       packet += syslen;
130       syslen -= NSYS_SM_SH_SIZE;
131 
132       /*************************************/
133       /* chapter D: Simple System Commands */
134       /*************************************/
135 
136       if (schapters & NSYS_SM_SH_CHKD)
137 	{
138 	  if ((syslen -= NSYS_SM_CD_SIZE_TOC) < 0)
139 	    return NSYS_JOURNAL_CORRUPTED;
140 
141 	  dchapters = ps[NSYS_SM_CD_LOC_TOC];
142 	  ps += NSYS_SM_CD_SIZE_TOC;
143 
144 	  if (dchapters & NSYS_SM_CD_TOC_CHKB)
145 	    {
146 	      if ((syslen -= NSYS_SM_CD_SIZE_RESET) < 0)
147 		return NSYS_JOURNAL_CORRUPTED;
148 
149 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
150 		  nsys_netin_jrec_reset(sptr, ps, jrecvsys, buff, fill, size))
151 		return NSYS_JOURNAL_FILLEDBUFF;
152 
153 	      ps += NSYS_SM_CD_SIZE_RESET;
154 	    }
155 
156 	  if (dchapters & NSYS_SM_CD_TOC_CHKG)
157 	    {
158 	      if ((syslen -= NSYS_SM_CD_SIZE_TUNE) < 0)
159 		return NSYS_JOURNAL_CORRUPTED;
160 
161 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
162 		  nsys_netin_jrec_tune(sptr, ps, jrecvsys, buff, fill, size))
163 		return NSYS_JOURNAL_FILLEDBUFF;
164 
165 	      ps += NSYS_SM_CD_SIZE_TUNE;
166 	    }
167 
168 	  if (dchapters & NSYS_SM_CD_TOC_CHKH)
169 	    {
170 	      if ((syslen -= NSYS_SM_CD_SIZE_SONG) < 0)
171 		return NSYS_JOURNAL_CORRUPTED;
172 
173 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
174 		  nsys_netin_jrec_song(sptr, ps, jrecvsys, buff, fill, size))
175 		return NSYS_JOURNAL_FILLEDBUFF;
176 
177 	      ps += NSYS_SM_CD_SIZE_SONG;
178 	    }
179 
180 	  if (dchapters & NSYS_SM_CD_TOC_CHKJ)
181 	    {
182 	      if ((syslen -= (NSYS_SM_CD_COMMON_TOC_SIZE +
183 			      NSYS_SM_CD_COMMON_LENGTH_SIZE)) < 0)
184 		return NSYS_JOURNAL_CORRUPTED;
185 
186 	      loglen = ps[1] + ((ps[0] & NSYS_SM_CD_COMMON_LENMSB_MASK) << 8);
187 
188 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
189 		  nsys_netin_jrec_scj(sptr, ps, jrecvsys, buff, fill, size))
190 		return NSYS_JOURNAL_FILLEDBUFF;
191 
192 	      syslen -= (loglen - (NSYS_SM_CD_COMMON_TOC_SIZE +
193 				   NSYS_SM_CD_COMMON_LENGTH_SIZE));
194 	      ps += loglen;
195 	    }
196 
197 	  if (dchapters & NSYS_SM_CD_TOC_CHKK)
198 	    {
199 	      if ((syslen -= (NSYS_SM_CD_COMMON_TOC_SIZE +
200 			      NSYS_SM_CD_COMMON_LENGTH_SIZE)) < 0)
201 		return NSYS_JOURNAL_CORRUPTED;
202 
203 	      loglen = ps[1] + ((ps[0] & NSYS_SM_CD_COMMON_LENMSB_MASK) << 8);
204 
205 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
206 		  nsys_netin_jrec_sck(sptr, ps, jrecvsys, buff, fill, size))
207 		return NSYS_JOURNAL_FILLEDBUFF;
208 
209 	      syslen -= (loglen - (NSYS_SM_CD_COMMON_TOC_SIZE +
210 				   NSYS_SM_CD_COMMON_LENGTH_SIZE));
211 	      ps += loglen;
212 	    }
213 
214 	  if (dchapters & NSYS_SM_CD_TOC_CHKY)
215 	    {
216 	      if ((syslen -= NSYS_SM_CD_REALTIME_TOC_SIZE) < 0)
217 		return NSYS_JOURNAL_CORRUPTED;
218 
219 	      loglen = ps[0] & NSYS_SM_CD_REALTIME_LENGTH_MASK;
220 
221 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
222 		  nsys_netin_jrec_rty(sptr, ps, jrecvsys, buff, fill, size))
223 		return NSYS_JOURNAL_FILLEDBUFF;
224 
225 	      syslen -= (loglen - NSYS_SM_CD_REALTIME_TOC_SIZE);
226 	      ps += loglen;
227 	    }
228 
229 	  if (dchapters & NSYS_SM_CD_TOC_CHKZ)
230 	    {
231 	      if ((syslen -= NSYS_SM_CD_REALTIME_TOC_SIZE) < 0)
232 		return NSYS_JOURNAL_CORRUPTED;
233 
234 	      loglen = ps[0] & NSYS_SM_CD_REALTIME_LENGTH_MASK;
235 
236 	      if (((!(ps[0] & NSYS_SM_CHKS)) || many) &&
237 		  nsys_netin_jrec_rtz(sptr, ps, jrecvsys, buff, fill, size))
238 		return NSYS_JOURNAL_FILLEDBUFF;
239 
240 	      syslen -= (loglen - NSYS_SM_CD_REALTIME_TOC_SIZE);
241 	      ps += loglen;
242 	    }
243 	}
244 
245       /***************************/
246       /* chapter V: Active Sense */
247       /***************************/
248 
249       if (schapters & NSYS_SM_SH_CHKV)
250 	{
251 	  if ((syslen -= NSYS_SM_CV_SIZE) < 0)
252 	    return NSYS_JOURNAL_CORRUPTED;
253 
254 	  if (((!(ps[NSYS_SM_CV_LOC_COUNT] & NSYS_SM_CHKS)) || many) &&
255 	      nsys_netin_jrec_sense(sptr, ps, jrecvsys, buff, fill, size))
256 	    return NSYS_JOURNAL_FILLEDBUFF;
257 
258 	  ps += NSYS_SM_CV_SIZE;
259 	}
260 
261       /************************/
262       /* chapter Q: Sequencer */
263       /************************/
264 
265       if (schapters & NSYS_SM_SH_CHKQ)
266 	{
267 	  if ((syslen -= NSYS_SM_CQ_SIZE_HDR) < 0)
268 	    return NSYS_JOURNAL_CORRUPTED;
269 
270 	  loglen = 0;
271 
272 	  if (ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC)
273 	    loglen += NSYS_SM_CQ_SIZE_CLOCK;
274 
275 	  if (ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKT)
276 	    loglen += NSYS_SM_CQ_SIZE_TIMETOOLS;
277 
278 	  if ((syslen -= loglen) < 0)
279 	    return NSYS_JOURNAL_CORRUPTED;
280 
281 	  loglen += NSYS_SM_CQ_SIZE_HDR;
282 
283 	  if (((!(ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CHKS)) || many) &&
284 	      nsys_netin_jrec_sequence(sptr, ps, jrecvsys, buff, fill, size))
285 	    return NSYS_JOURNAL_FILLEDBUFF;
286 
287 	  ps += loglen;
288 	}
289 
290       /*****************************/
291       /* chapter F: MIDI Time Code */
292       /*****************************/
293 
294       if (schapters & NSYS_SM_SH_CHKF)
295 	{
296 	  if ((syslen -= NSYS_SM_CF_SIZE_HDR) < 0)
297 	    return NSYS_JOURNAL_CORRUPTED;
298 
299 	  loglen = 0;
300 
301 	  if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC)
302 	    loglen += NSYS_SM_CF_SIZE_COMPLETE;
303 
304 	  if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKP)
305 	    loglen += NSYS_SM_CF_SIZE_PARTIAL;
306 
307 	  if ((syslen -= loglen) < 0)
308 	    return NSYS_JOURNAL_CORRUPTED;
309 
310 	  loglen += NSYS_SM_CF_SIZE_HDR;
311 
312 	  if (((!(ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CHKS)) || many) &&
313 	      nsys_netin_jrec_timecode(sptr, ps, jrecvsys, buff, fill, size))
314 	    return NSYS_JOURNAL_FILLEDBUFF;
315 
316 	  ps += loglen;
317 	}
318 
319       /*******************************/
320       /* chapter X: System Exclusive */
321       /*******************************/
322 
323       if ((schapters & NSYS_SM_SH_CHKX) && syslen &&
324 	  (!(ps[NSYS_SM_CX_LOC_HDR] & NSYS_SM_CHKS) || many))
325 	{
326 	  if (nsys_netin_jrec_sysex(sptr, ps, syslen, jrecvsys, buff, fill, size))
327 	    return NSYS_JOURNAL_FILLEDBUFF;
328 	}
329     }
330 
331   while (numchan--)
332     {
333       if (numbytes < NSYS_SM_CH_SIZE)
334 	return NSYS_JOURNAL_CORRUPTED;
335 
336       chan = ((packet[NSYS_SM_CH_LOC_FLAGS] & NSYS_SM_CH_CHANMASK)
337 	      >> NSYS_SM_CH_CHANSHIFT);
338 
339       if ((jrecv = sptr->jrecv[chan]) == NULL)
340 	jrecv = sptr->jrecv[chan] = nsys_netin_newrecv(chan);
341 
342       chapters = packet[NSYS_SM_CH_LOC_TOC];
343       chanlen = *((short *)&(packet[NSYS_SM_CH_LOC_FLAGS]));
344       chanlen = ntohs((unsigned short)chanlen) & NSYS_SM_CH_LENMASK;
345 
346       if ((numbytes -= chanlen) < 0)
347 	return NSYS_JOURNAL_CORRUPTED;
348 
349       p = packet + NSYS_SM_CH_SIZE;
350       packet += chanlen;
351 
352       /*****************************/
353       /* chapter P: Program Change */
354       /*****************************/
355 
356       if (chapters & NSYS_SM_CH_TOC_SETP)
357 	{
358 	  if ((chanlen -= NSYS_SM_CP_SIZE) < 0)
359 	    return NSYS_JOURNAL_CORRUPTED;
360 
361 	  if (((!(p[NSYS_SM_CP_LOC_PROGRAM] & NSYS_SM_CHKS)) || many) &&
362 	      nsys_netin_jrec_program(sptr, p, jrecv, buff, fill, size))
363 	    return NSYS_JOURNAL_FILLEDBUFF;
364 
365 	  p += NSYS_SM_CP_SIZE;
366 	}
367 
368       /**************************/
369       /* chapter C: Controllers */
370       /**************************/
371 
372       if (chapters & NSYS_SM_CH_TOC_SETC)
373 	{
374 	  if ((chanlen -= NSYS_SM_CC_HDRSIZE) < 0)
375 	    return NSYS_JOURNAL_CORRUPTED;
376 
377 	  loglen = (p[NSYS_SM_CC_LOC_LENGTH] & NSYS_SM_CLRS) + 1;
378 
379 	  if ((chanlen -= loglen*NSYS_SM_CC_LOGSIZE) < 0)
380 	    return NSYS_JOURNAL_CORRUPTED;
381 
382 	  if (((!(p[NSYS_SM_CC_LOC_LENGTH] & NSYS_SM_CHKS)) || many) &&
383 	      nsys_netin_jrec_control(sptr, p, jrecv, loglen, many,
384 				      buff, fill, size))
385 	    return NSYS_JOURNAL_FILLEDBUFF;
386 
387 	  p += (NSYS_SM_CC_HDRSIZE + loglen*NSYS_SM_CC_LOGSIZE);
388 	}
389 
390       /*******************************/
391       /* chapter M: Parameter System */
392       /*******************************/
393 
394       if (chapters & NSYS_SM_CH_TOC_SETM)
395 	{
396 	  if (chanlen < NSYS_SM_CM_HDRSIZE)
397 	    return NSYS_JOURNAL_CORRUPTED;
398 
399 	  memcpy(&(paramlen), &(p[NSYS_SM_CM_LOC_HDR]), sizeof(short));
400 	  paramlen = ntohs(paramlen) & NSYS_SM_CM_LENMASK;
401 
402 	  if ((chanlen -= paramlen) < 0)
403 	    return NSYS_JOURNAL_CORRUPTED;
404 
405 	  if (((!(p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CHKS)) || many) &&
406 	      nsys_netin_jrec_param(sptr, p, jrecv, paramlen, many,
407 				    buff, fill, size))
408 	    return NSYS_JOURNAL_FILLEDBUFF;
409 
410 	  p += paramlen;
411 	}
412 
413       /**************************/
414       /* chapter W: Pitch Wheel */
415       /**************************/
416 
417       if (chapters & NSYS_SM_CH_TOC_SETW)
418 	{
419 	  if ((chanlen -= NSYS_SM_CW_SIZE) < 0)
420 	    return NSYS_JOURNAL_CORRUPTED;
421 
422 	  if (((!(p[NSYS_SM_CW_LOC_FIRST] & NSYS_SM_CHKS)) || many) &&
423 	      nsys_netin_jrec_wheel(sptr, p, jrecv, buff, fill, size))
424 	    return NSYS_JOURNAL_FILLEDBUFF;
425 
426 	  p += NSYS_SM_CW_SIZE;
427 	}
428 
429       /**************************/
430       /* chapter N: Note On/Off */
431       /**************************/
432 
433       if (chapters & NSYS_SM_CH_TOC_SETN)
434 	{
435 	  if ((chanlen -= NSYS_SM_CN_HDRSIZE) < 0)
436 	    return NSYS_JOURNAL_CORRUPTED;
437 
438 	  loglen = p[NSYS_SM_CN_LOC_LENGTH] & NSYS_SM_CN_CLRB;
439 	  bflag = !(p[NSYS_SM_CN_LOC_LENGTH] & NSYS_SM_CN_CHKB);
440 	  low = ((p[NSYS_SM_CN_LOC_LOWHIGH] & NSYS_SM_CN_LOWMASK) >>
441 		 NSYS_SM_CN_LOWSHIFT);
442 	  high = (p[NSYS_SM_CN_LOC_LOWHIGH] & NSYS_SM_CN_HIGHMASK);
443 
444 	  if ((loglen == 127) && (low == 15) && (high == 0))
445 	    loglen = 128;
446 
447 	  if ((chanlen -= (loglen*NSYS_SM_CN_LOGSIZE +
448 			   ((low <= high) ? (high - low + 1) : 0))) < 0)
449 	    return NSYS_JOURNAL_CORRUPTED;
450 
451 	  p += NSYS_SM_CN_HDRSIZE;
452 
453 	  if (loglen)
454 	    {
455 	      if (nsys_netin_jrec_notelog(sptr, p, jrecv, many, loglen,
456 					  checkptr, buff, fill, size))
457 		return NSYS_JOURNAL_FILLEDBUFF;
458 	      p += loglen*NSYS_SM_CN_LOGSIZE;
459 	    }
460 	  if ((bflag || many) && (low <= high))
461 	    {
462 	      if (nsys_netin_jrec_bitfield(sptr, p, jrecv, low, high,
463 					   buff, fill, size))
464 		return NSYS_JOURNAL_FILLEDBUFF;
465 	    }
466 
467 	  p += (low <= high) ? (high - low + 1) : 0;
468 	}
469 
470       /**************************/
471       /* chapter E: Note Extras */
472       /**************************/
473 
474       if (chapters & NSYS_SM_CH_TOC_SETE)
475 	{
476 	  if ((chanlen -= NSYS_SM_CE_HDRSIZE) < 0)
477 	    return NSYS_JOURNAL_CORRUPTED;
478 
479 	  loglen = (p[NSYS_SM_CE_LOC_LENGTH] & NSYS_SM_CLRS) + 1;
480 
481 	  if ((chanlen -= loglen*NSYS_SM_CE_LOGSIZE) < 0)
482 	    return NSYS_JOURNAL_CORRUPTED;
483 
484 	  p += (NSYS_SM_CE_HDRSIZE + loglen*NSYS_SM_CE_LOGSIZE);
485 	}
486 
487       /****************************/
488       /* chapter T: Channel Touch */
489       /****************************/
490 
491       if (chapters & NSYS_SM_CH_TOC_SETT)
492 	{
493 	  if ((chanlen -= NSYS_SM_CT_SIZE) < 0)
494 	    return NSYS_JOURNAL_CORRUPTED;
495 
496 	  if (((!(p[NSYS_SM_CT_LOC_PRESSURE] & NSYS_SM_CHKS)) || many) &&
497 	      nsys_netin_jrec_ctouch(sptr, p, jrecv, buff, fill, size))
498 	    return NSYS_JOURNAL_FILLEDBUFF;
499 
500 	  p += NSYS_SM_CT_SIZE;
501 	}
502 
503       /**************************/
504       /* chapter A: Poly Touch */
505       /**************************/
506 
507       if (chapters & NSYS_SM_CH_TOC_SETA)
508 	{
509 	  if ((chanlen -= NSYS_SM_CA_HDRSIZE) < 0)
510 	    return NSYS_JOURNAL_CORRUPTED;
511 
512 	  loglen = (p[NSYS_SM_CA_LOC_LENGTH] & NSYS_SM_CLRS) + 1;
513 
514 	  if ((chanlen -= loglen*NSYS_SM_CA_LOGSIZE) < 0)
515 	    return NSYS_JOURNAL_CORRUPTED;
516 
517 	  if (((!(p[NSYS_SM_CA_LOC_LENGTH] & NSYS_SM_CHKS)) || many) &&
518 	      nsys_netin_jrec_ptouch(sptr, p, jrecv, loglen, many,
519 				     buff, fill, size))
520 	    return NSYS_JOURNAL_FILLEDBUFF;
521 
522 	  p += (NSYS_SM_CA_HDRSIZE + loglen*NSYS_SM_CA_LOGSIZE);
523 	}
524     }
525 
526   if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
527     {
528       printf("recovery (fill: %li):", (*fill));
529       for (i = 0; j + i < (*fill); i++)
530 	printf(" %hhu", buff[j + i]);
531       printf("\n");
532       fflush(stdout);
533     }
534 
535   return NSYS_JOURNAL_RECOVERED;
536 }
537 
538 /****************************************************************/
539 /*            receiver state: add a new MIDI event              */
540 /****************************************************************/
541 
nsys_netin_journal_trackstate(nsys_source * sptr,unsigned char cmd,unsigned char ndata,unsigned char vdata)542 void nsys_netin_journal_trackstate(nsys_source * sptr, unsigned char cmd,
543 				   unsigned char ndata, unsigned char vdata)
544 
545 {
546   nsys_netout_jrecv_state * jrecv;
547   nsys_netout_jrecv_system_state * jrecvsys;
548   long song_pp;
549 
550   if (cmd < CSYS_MIDI_NOTEOFF)      /* SysEx */
551     {
552       if ((jrecvsys = sptr->jrecvsys) == NULL)
553 	jrecvsys = sptr->jrecvsys = nsys_netin_newrecvsys();
554 
555       switch (cmd) {
556       case CSYS_MIDI_GMRESET:
557 	nsys_netin_journal_clear_active(cmd);
558 	jrecvsys->chapterx_gmreset = ndata | NSYS_SM_RV_SETF;
559 	if (ndata == NSYS_SM_CX_GMRESET_ONVAL)
560 	  jrecvsys->chapterx_gmreset_on_count++;
561 	else
562 	  jrecvsys->chapterx_gmreset_off_count++;
563 	break;
564       case CSYS_MIDI_MVOLUME:
565 	jrecvsys->chapterx_mvolume_lsb = ndata | NSYS_SM_RV_SETF;
566 	jrecvsys->chapterx_mvolume_msb = vdata;
567 	break;
568       }
569       return;
570     }
571 
572   if (cmd < ((unsigned char) CSYS_MIDI_SYSTEM))
573     {
574       if ((jrecv = sptr->jrecv[cmd & 0x0F]) == NULL)
575 	jrecv = sptr->jrecv[cmd & 0x0F] = nsys_netin_newrecv(cmd & 0x0F);
576 
577       switch (cmd & 0xF0) {
578 
579       case CSYS_MIDI_PROGRAM:
580 	jrecv->chapterp_program = vdata | NSYS_SM_RV_SETF;
581 	jrecv->chapterp_bank_msb = NSYS_SM_RV_CLRF &
582 	  jrecv->chapterc_value[CSYS_MIDI_CC_BANKSELECT_MSB];
583 	jrecv->chapterp_bank_lsb = NSYS_SM_RV_CLRF &
584 	  jrecv->chapterc_value[CSYS_MIDI_CC_BANKSELECT_LSB];
585 	break;
586 
587       case CSYS_MIDI_CC:
588 	switch (ndata) {
589 	case CSYS_MIDI_CC_ALLSOUNDOFF:
590 	case CSYS_MIDI_CC_ALLNOTESOFF:
591 	case CSYS_MIDI_CC_RESETALLCONTROL:
592 	case CSYS_MIDI_CC_OMNI_OFF:
593 	case CSYS_MIDI_CC_OMNI_ON:
594 	case CSYS_MIDI_CC_MONOMODE:
595 	case CSYS_MIDI_CC_POLYMODE:
596 	  jrecv->chapterc_value[ndata] = NSYS_SM_RV_SETF |
597 	    (((jrecv->chapterc_value[ndata] & NSYS_SM_CC_ALTMOD) + 1)
598 	     & NSYS_SM_CC_ALTMOD);
599 	  switch (ndata) {
600 	  case CSYS_MIDI_CC_ALLSOUNDOFF:
601 	  case CSYS_MIDI_CC_ALLNOTESOFF:
602 	  case CSYS_MIDI_CC_OMNI_OFF:
603 	  case CSYS_MIDI_CC_OMNI_ON:
604 	  case CSYS_MIDI_CC_MONOMODE:
605 	  case CSYS_MIDI_CC_POLYMODE:
606 	    memset(jrecv->chaptern_ref, 0, NSYS_SM_CN_ARRAYSIZE);
607 	    jrecv->chaptert_pressure = 0;
608 	    break;
609 	  case CSYS_MIDI_CC_RESETALLCONTROL:
610 
611 	    /* Chapter C -- update pedal count */
612 
613 	    jrecv->chapterc_value[CSYS_MIDI_CC_SUSTAIN] = NSYS_SM_RV_SETF |
614 	      (((jrecv->chapterc_value[CSYS_MIDI_CC_SUSTAIN] & NSYS_SM_CC_ALTMOD) + 1)
615 	       & NSYS_SM_CC_ALTMOD);
616 
617 	    /* Clear parameter transaction system */
618 
619 	    jrecv->chapterm_nrpn_msb = jrecv->chapterm_nrpn_lsb = 0;
620 	    jrecv->chapterm_rpn_msb = jrecv->chapterm_rpn_lsb = 0;
621 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_OFF;
622 
623 	    /* Clear parameter system C-BUTTON counts */
624 
625 	    memset(jrecv->chapterm_cbutton, 0, sizeof(short)*NSYS_SM_CM_ARRAYSIZE);
626 
627 	    /* C-active Chapters:  W, T, and A */
628 
629 	    jrecv->chapterw_first = 0;
630 	    jrecv->chapterw_second = 0;
631 	    memset(jrecv->chaptera_pressure, 0, NSYS_SM_CA_ARRAYSIZE);
632 	    jrecv->chaptert_pressure = 0;
633 	    break;
634 	  }
635 	  break;
636 	case CSYS_MIDI_CC_SUSTAIN:
637 	  if (((vdata >= 64) && !(jrecv->chapterc_value[ndata] & 0x01))
638 	      || ((vdata < 64) && (jrecv->chapterc_value[ndata] & 0x01)))
639 	    {
640 	      jrecv->chapterc_value[ndata] = NSYS_SM_RV_SETF |
641 		(((jrecv->chapterc_value[ndata] & NSYS_SM_CC_ALTMOD) + 1)
642 		 & NSYS_SM_CC_ALTMOD);
643 	    }
644 	  break;
645 	case CSYS_MIDI_CC_RPN_MSB:
646 	  jrecv->chapterm_state = NSYS_SM_CM_STATE_PENDING_RPN;
647 	  jrecv->chapterm_rpn_msb = vdata;
648 	  jrecv->chapterm_rpn_lsb = 0;
649 	  break;
650 	case CSYS_MIDI_CC_NRPN_MSB:
651 	  jrecv->chapterm_state = NSYS_SM_CM_STATE_PENDING_NRPN;
652 	  jrecv->chapterm_nrpn_msb = vdata;
653 	  jrecv->chapterm_nrpn_lsb = 0;
654 	  break;
655 	case CSYS_MIDI_CC_RPN_LSB:
656 	  if ((jrecv->chapterm_rpn_msb == CSYS_MIDI_RPN_NULL_MSB) &&
657 	      (vdata == CSYS_MIDI_RPN_NULL_LSB))
658 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_OFF;
659 	  else
660 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_RPN;
661 	  jrecv->chapterm_rpn_lsb = vdata;
662 	  break;
663 	case CSYS_MIDI_CC_NRPN_LSB:
664 	  if ((jrecv->chapterm_nrpn_msb == CSYS_MIDI_NRPN_NULL_MSB) &&
665 	      (vdata == CSYS_MIDI_NRPN_NULL_LSB))
666 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_OFF;
667 	  else
668 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_NRPN;
669 	  jrecv->chapterm_nrpn_lsb = vdata;
670 	  break;
671 	case CSYS_MIDI_CC_DATAENTRY_MSB:
672 	case CSYS_MIDI_CC_DATAENTRY_LSB:
673 	  switch(jrecv->chapterm_state) {
674 	  case NSYS_SM_CM_STATE_OFF:
675 	    jrecv->chapterc_value[ndata] = vdata | NSYS_SM_RV_SETF;
676 	    break;
677 	  case NSYS_SM_CM_STATE_PENDING_NRPN:
678 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_NRPN;
679 	    break;
680 	  case NSYS_SM_CM_STATE_NRPN:
681 	    break;
682 	  case NSYS_SM_CM_STATE_PENDING_RPN:
683 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_RPN; /* fall through */
684 	  case NSYS_SM_CM_STATE_RPN:
685 	    if ((jrecv->chapterm_rpn_msb == 0) &&
686 		(jrecv->chapterm_rpn_lsb < NSYS_SM_CM_ARRAYSIZE))
687 	      {
688 		if (ndata == CSYS_MIDI_CC_DATAENTRY_LSB)
689 		  jrecv->chapterm_value_lsb[jrecv->chapterm_rpn_lsb] = vdata;
690 		else
691 		  {
692 		    jrecv->chapterm_value_msb[jrecv->chapterm_rpn_lsb] = vdata;
693 		    jrecv->chapterm_value_lsb[jrecv->chapterm_rpn_lsb] = 0;
694 		  }
695 		jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb] = 0;
696 	      }
697 	    break;
698 	  }
699 	  break;
700 	case CSYS_MIDI_CC_DATAENTRYPLUS:
701 	case CSYS_MIDI_CC_DATAENTRYMINUS:
702 	  switch(jrecv->chapterm_state) {
703 	  case NSYS_SM_CM_STATE_OFF:
704 	    jrecv->chapterc_value[ndata] = vdata | NSYS_SM_RV_SETF;
705 	    break;
706 	  case NSYS_SM_CM_STATE_PENDING_NRPN:
707 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_NRPN;
708 	    break;
709 	  case NSYS_SM_CM_STATE_NRPN:
710 	    break;
711 	  case NSYS_SM_CM_STATE_PENDING_RPN:
712 	    jrecv->chapterm_state = NSYS_SM_CM_STATE_RPN;  /* fall through */
713 	    break;
714 	  case NSYS_SM_CM_STATE_RPN:
715 	    if ((jrecv->chapterm_rpn_msb == 0) &&
716 		(jrecv->chapterm_rpn_lsb < NSYS_SM_CM_ARRAYSIZE))
717 	      {
718 		if (ndata == CSYS_MIDI_CC_DATAENTRYPLUS)
719 		  jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb]++;
720 		else
721 		  jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb]--;
722 
723 		if (jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb] >
724 		    NSYS_SM_CM_BUTTON_LIMIT)
725 		  jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb] =
726 		    NSYS_SM_CM_BUTTON_LIMIT;
727 		else
728 		  {
729 		    if (jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb] <
730 			- NSYS_SM_CM_BUTTON_LIMIT)
731 		      jrecv->chapterm_cbutton[jrecv->chapterm_rpn_lsb] =
732 			- NSYS_SM_CM_BUTTON_LIMIT;
733 		  }
734 	      }
735 	    break;
736 	  }
737 	  break;
738 	default:
739 	  jrecv->chapterc_value[ndata] = vdata | NSYS_SM_RV_SETF;
740 	  break;
741 	}
742 	break;
743 
744       case CSYS_MIDI_WHEEL:
745 	jrecv->chapterw_first = ndata | NSYS_SM_RV_SETF;
746 	jrecv->chapterw_second = vdata;
747 	break;
748 
749       case CSYS_MIDI_NOTEOFF:
750 	if (jrecv->chaptern_ref[ndata])
751 	  {
752 	    jrecv->chaptern_ref[ndata]--;
753 	    jrecv->chaptern_vel[ndata] = 0;
754 	  }
755 	break;
756 
757       case CSYS_MIDI_NOTEON:
758 	if (vdata)
759 	  {
760 	    if ((++(jrecv->chaptern_ref[ndata])) == 1)
761 	      {
762 		jrecv->chaptern_vel[ndata] = vdata;
763 		jrecv->chaptern_tstamp[ndata] = nsys_netout_tstamp;
764 		jrecv->chaptern_extseq[ndata] = sptr->hi_ext;
765 	      }
766 	    else
767 	      {
768 		jrecv->chaptern_vel[ndata] = 0;
769 
770 		if ((jrecv->chaptern_ref[ndata]) == 0)
771 		  jrecv->chaptern_ref[ndata] = 255;
772 	      }
773 	  }
774 	else
775 	  if (jrecv->chaptern_ref[ndata])
776 	    {
777 	      jrecv->chaptern_ref[ndata]--;
778 	      jrecv->chaptern_vel[ndata] = 0;
779 	    }
780 	break;
781 
782       case CSYS_MIDI_CTOUCH:
783 	jrecv->chaptert_pressure = ndata | NSYS_SM_RV_SETF;
784 	break;
785 
786       case CSYS_MIDI_PTOUCH:
787 	jrecv->chaptera_pressure[ndata] = vdata | NSYS_SM_RV_SETF;
788 	break;
789       }
790     }
791   else
792     {
793       if ((jrecvsys = sptr->jrecvsys) == NULL)
794 	jrecvsys = sptr->jrecvsys = nsys_netin_newrecvsys();
795 
796       switch (cmd) {
797       case CSYS_MIDI_SYSTEM_RESET:
798 	nsys_netin_journal_clear_active(cmd);
799 	jrecvsys->chapterd_reset = NSYS_SM_RV_CLRF & (jrecvsys->chapterd_reset + 1);
800 	break;
801       case CSYS_MIDI_SYSTEM_TUNE_REQUEST:
802 	jrecvsys->chapterd_tune = NSYS_SM_RV_CLRF & (jrecvsys->chapterd_tune + 1);
803 	break;
804       case CSYS_MIDI_SYSTEM_SONG_SELECT:
805 	jrecvsys->chapterd_song = ndata;
806 	break;
807       case CSYS_MIDI_SYSTEM_TICK:
808 	jrecvsys->chapterd_rty++;
809 	break;
810       case CSYS_MIDI_SYSTEM_UNUSED3:
811 	jrecvsys->chapterd_rtz++;
812 	break;
813       case CSYS_MIDI_SYSTEM_QFRAME:
814 	nsys_netin_track_timecode(jrecvsys, ndata);
815 	break;
816       case CSYS_MIDI_SYSTEM_UNUSED1:
817 	jrecvsys->chapterd_scj_count++;
818 	jrecvsys->chapterd_scj_data1 = ndata;
819 	jrecvsys->chapterd_scj_data2 = vdata;
820 	break;
821       case CSYS_MIDI_SYSTEM_UNUSED2:
822 	jrecvsys->chapterd_sck_count++;
823 	jrecvsys->chapterd_sck_data1 = ndata;
824 	jrecvsys->chapterd_sck_data2 = vdata;
825 	break;
826       case CSYS_MIDI_SYSTEM_CLOCK:
827 	if (!(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKD))
828 	  jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= NSYS_SM_CQ_HDR_SETD;
829 	else
830 	  {
831 	    if (!(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC))
832 	      {
833 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= NSYS_SM_CQ_HDR_SETC;
834 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1] = 0;
835 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS] = 0;
836 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= ~(NSYS_SM_CQ_TOP_MASK);
837 	      }
838 	    if (!(++(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1])))
839 	      if (!(++(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS])))
840 		{
841 		  if ((jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR]
842 		       & NSYS_SM_CQ_TOP_MASK) != NSYS_SM_CQ_TOP_MASK)
843 		    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR]++;
844 		  else
845 		    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &=
846 		      ~(NSYS_SM_CQ_TOP_MASK);
847 		}
848 	  }
849 	break;
850       case CSYS_MIDI_SYSTEM_START:
851 	jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] = NSYS_SM_CQ_HDR_SETN;  /* C=D=0 */
852 	break;
853       case CSYS_MIDI_SYSTEM_CONTINUE:
854 	jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= NSYS_SM_CQ_HDR_SETN;
855 	if (jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKD)
856 	  {
857 	    if (!(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC))
858 	      {
859 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= NSYS_SM_CQ_HDR_SETC;
860 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1] = 0;
861 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS] = 0;
862 		jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= ~(NSYS_SM_CQ_TOP_MASK);
863 	      }
864 	    if (!(++(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1])))
865 	      if (!(++(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS])))
866 		{
867 		  if ((jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR]
868 		       & NSYS_SM_CQ_TOP_MASK) != NSYS_SM_CQ_TOP_MASK)
869 		    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR]++;
870 		  else
871 		    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &=
872 		      ~(NSYS_SM_CQ_TOP_MASK);
873 		}
874 	    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= NSYS_SM_CQ_HDR_CLRD;
875 	  }
876 	break;
877       case CSYS_MIDI_SYSTEM_STOP:
878 	jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= NSYS_SM_CQ_HDR_CLRN;
879 	break;
880       case CSYS_MIDI_SYSTEM_SONG_PP:
881 	if ((song_pp = 6*((vdata << 7) + ndata)))
882 	  {
883 	    if (!(jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC))
884 	      jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= NSYS_SM_CQ_HDR_SETC;
885 	    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1] =
886 	      (unsigned char) (song_pp & 0x000000FF);
887 	    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS] =
888 	      (unsigned char) ((song_pp >> 8) & 0x000000FF);
889 	    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= ~(NSYS_SM_CQ_TOP_MASK);
890 	    if (song_pp > NSYS_SM_CQ_BOTTOM_MASK)
891 	      jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] |= 0x01;  /* range limit */
892 	  }
893 	else
894 	  if ((jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC))
895 	    jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= NSYS_SM_CQ_HDR_CLRC;
896 	jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] &= NSYS_SM_CQ_HDR_CLRD;
897 	break;
898       case CSYS_MIDI_SYSTEM_SENSE:
899 	jrecvsys->chapterv_count = NSYS_SM_RV_CLRF & (jrecvsys->chapterv_count + 1);
900 	break;
901       }
902     }
903 }
904 
905 
906 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
907 /*                 second-level receiver functions              */
908 /*______________________________________________________________*/
909 
910 /****************************************************************/
911 /*               process chapter P (program change)             */
912 /****************************************************************/
913 
914 
nsys_netin_jrec_program(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,unsigned char * buff,long * fill,long size)915 int nsys_netin_jrec_program(nsys_source * sptr, unsigned char * p,
916 			  nsys_netout_jrecv_state * jrecv,
917 			  unsigned char * buff,
918 			  long * fill, long size)
919 
920 {
921   unsigned char newx, newy, vel, yflag;
922 
923   vel = (p[NSYS_SM_CP_LOC_PROGRAM] & NSYS_SM_CLRS);
924   newx = (p[NSYS_SM_CP_LOC_BANKMSB] & NSYS_SM_CP_CLRB);
925   newy = (p[NSYS_SM_CP_LOC_BANKLSB] & NSYS_SM_CP_CLRX);
926 
927   if ((jrecv->chapterp_program == 0) ||
928       (newx != jrecv->chapterp_bank_msb) ||
929       (newy != jrecv->chapterp_bank_lsb) ||
930       (vel != (jrecv->chapterp_program & NSYS_SM_RV_CLRF)))
931     {
932       yflag = ((newx != (NSYS_SM_CLRS & jrecv->chapterc_value
933 			 [CSYS_MIDI_CC_BANKSELECT_MSB])) ||
934 	       (newy != (NSYS_SM_CLRS & jrecv->chapterc_value
935 			 [CSYS_MIDI_CC_BANKSELECT_LSB])) ||
936 	       (jrecv->chapterc_value
937 		[CSYS_MIDI_CC_BANKSELECT_MSB] == 0) ||
938 	       (jrecv->chapterc_value
939 		[CSYS_MIDI_CC_BANKSELECT_LSB] == 0));
940 
941       /* if needed, change bank-switch values */
942 
943       if (yflag)
944 	{
945 	  if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
946 					jrecv->chan | CSYS_MIDI_CC,
947 					CSYS_MIDI_CC_BANKSELECT_MSB
948 					, newx))
949 	    return NSYS_JOURNAL_FILLEDBUFF;
950 	  if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
951 					jrecv->chan | CSYS_MIDI_CC,
952 					CSYS_MIDI_CC_BANKSELECT_LSB
953 					, newy))
954 	    return NSYS_JOURNAL_FILLEDBUFF;
955 	}
956 
957       /* do program change */
958 
959       if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
960 					jrecv->chan | CSYS_MIDI_PROGRAM, vel))
961 	return NSYS_JOURNAL_FILLEDBUFF;
962 
963       /* if changed, reset bank-switch values */
964 
965       if (yflag)
966 	{
967 	  if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
968 					jrecv->chan | CSYS_MIDI_CC,
969 					CSYS_MIDI_CC_BANKSELECT_MSB
970 					, jrecv->chapterc_value
971 					[CSYS_MIDI_CC_BANKSELECT_MSB]))
972 	    return NSYS_JOURNAL_FILLEDBUFF;
973 	  if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
974 					jrecv->chan | CSYS_MIDI_CC,
975 					CSYS_MIDI_CC_BANKSELECT_LSB
976 					, jrecv->chapterc_value
977 					[CSYS_MIDI_CC_BANKSELECT_LSB]))
978 	    return NSYS_JOURNAL_FILLEDBUFF;
979 	}
980 
981       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
982 	printf("PChange %hhu [%hhu,%hhu] --> %hhu [%hhu, %hhu]\n",
983 	       jrecv->chapterp_program & NSYS_SM_RV_CLRF,
984 	       jrecv->chapterp_bank_msb, jrecv->chapterp_bank_lsb,
985 	       vel, newx, newy);
986 
987       jrecv->chapterp_program = vel | NSYS_SM_RV_SETF;
988       jrecv->chapterp_bank_msb = newx ;
989       jrecv->chapterp_bank_lsb = newy ;
990     }
991 
992   return NSYS_JOURNAL_RECOVERED;
993 }
994 
995 /****************************************************************/
996 /*               process chapter C (controllers)                */
997 /****************************************************************/
998 
nsys_netin_jrec_control(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,short loglen,unsigned char many,unsigned char * buff,long * fill,long size)999 int nsys_netin_jrec_control(nsys_source * sptr, unsigned char * p,
1000 			    nsys_netout_jrecv_state * jrecv, short loglen,
1001 			    unsigned char many, unsigned char * buff,
1002 			    long * fill, long size)
1003 
1004 {
1005   unsigned char newx, newy, cancel;
1006   int unexpected = 0;
1007   int update = 0;
1008 
1009   p += NSYS_SM_CC_HDRSIZE;
1010   while (loglen)
1011     {
1012       if ((!(p[NSYS_SM_CC_LOC_LNUM] & NSYS_SM_CHKS)) || many)
1013 	{
1014 	  newx = p[NSYS_SM_CC_LOC_LNUM] & NSYS_SM_CLRS;
1015 	  newy = p[NSYS_SM_CC_LOC_LVAL];
1016 
1017 	  switch (newx) {
1018 	  case CSYS_MIDI_CC_ALLSOUNDOFF:
1019 	  case CSYS_MIDI_CC_ALLNOTESOFF:
1020 	  case CSYS_MIDI_CC_RESETALLCONTROL:
1021 	  case CSYS_MIDI_CC_OMNI_OFF:
1022 	  case CSYS_MIDI_CC_OMNI_ON:
1023 	  case CSYS_MIDI_CC_MONOMODE:
1024 	  case CSYS_MIDI_CC_POLYMODE:
1025 	    if ((newy & NSYS_SM_CC_CHKA) && !(newy & NSYS_SM_CC_CHKT))
1026 	      {
1027 		update = ((jrecv->chapterc_value[newx] == 0) ||
1028 			  ((jrecv->chapterc_value[newx] & NSYS_SM_RV_CLRF) !=
1029 			   (newy & NSYS_SM_CC_ALTMOD)));
1030 
1031 		if (update)
1032 		  {
1033 		    jrecv->chapterc_value[newx] = ((newy & NSYS_SM_CC_ALTMOD)
1034 						   | NSYS_SM_RV_SETF);
1035 		    newy = 0;
1036 
1037 		    switch (newx) {
1038 		    case CSYS_MIDI_CC_ALLSOUNDOFF:
1039 		    case CSYS_MIDI_CC_ALLNOTESOFF:
1040 		    case CSYS_MIDI_CC_OMNI_OFF:
1041 		    case CSYS_MIDI_CC_OMNI_ON:
1042 		    case CSYS_MIDI_CC_MONOMODE:
1043 		    case CSYS_MIDI_CC_POLYMODE:
1044 		      memset(jrecv->chaptern_ref, 0, NSYS_SM_CN_ARRAYSIZE);
1045 		      jrecv->chaptert_pressure = 0;
1046 		      break;
1047 		    case CSYS_MIDI_CC_RESETALLCONTROL:
1048 
1049 		      /* Chapter C -- update pedal count */
1050 
1051 		      jrecv->chapterc_value[CSYS_MIDI_CC_SUSTAIN] = NSYS_SM_RV_SETF |
1052 			(((jrecv->chapterc_value[CSYS_MIDI_CC_SUSTAIN]
1053 			   & NSYS_SM_CC_ALTMOD) + 1) & NSYS_SM_CC_ALTMOD);
1054 
1055 		      /* Clear parameter transaction system */
1056 
1057 		      jrecv->chapterm_nrpn_msb = jrecv->chapterm_nrpn_lsb = 0;
1058 		      jrecv->chapterm_rpn_msb = jrecv->chapterm_rpn_lsb = 0;
1059 		      jrecv->chapterm_state = NSYS_SM_CM_STATE_OFF;
1060 
1061 		      /* Clear parameter system C-BUTTON counts */
1062 
1063 		      memset(jrecv->chapterm_cbutton, 0,
1064 			     sizeof(short)*NSYS_SM_CM_ARRAYSIZE);
1065 
1066 		      /* C-active Chapters:  W, T, and A */
1067 
1068 		      jrecv->chapterw_first = 0;
1069 		      jrecv->chapterw_second = 0;
1070 		      memset(jrecv->chaptera_pressure, 0, NSYS_SM_CA_ARRAYSIZE);
1071 		      jrecv->chaptert_pressure = 0;
1072 		      break;
1073 		    }
1074 		  }
1075 	      }
1076 	    else
1077 	      unexpected = 1;
1078 	    break;
1079 	  case CSYS_MIDI_CC_SUSTAIN:
1080 	    if ((newy & NSYS_SM_CC_CHKA) && (newy & NSYS_SM_CC_CHKT))
1081 	      {
1082 		update = ((jrecv->chapterc_value[newx] == 0) ||
1083 			  ((jrecv->chapterc_value[newx] & NSYS_SM_RV_CLRF) !=
1084 			   (newy & NSYS_SM_CC_ALTMOD)));
1085 
1086 		if (update)
1087 		  {
1088 		    cancel = (newy & 0x01) & (jrecv->chapterc_value[newx] & 1);
1089 
1090 		    jrecv->chapterc_value[newx] = ((newy & NSYS_SM_CC_ALTMOD)
1091 						   | NSYS_SM_RV_SETF);
1092 		    newy = (newy & 0x01) ? 64 : 0;
1093 
1094 		    if (cancel)
1095 		      {
1096 			if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1097 						      jrecv->chan | CSYS_MIDI_CC,
1098 						      newx, 0))
1099 			  return NSYS_JOURNAL_FILLEDBUFF;
1100 
1101 			if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1102 			  printf("CntrlLog %hhu: cancel sustain pedal\n", newx);
1103 		      }
1104 		  }
1105 	      }
1106 	    else
1107 	      unexpected = 1;
1108 	    break;
1109 	  default:
1110 	    if (!(newy & NSYS_SM_CC_CHKA))
1111 	      {
1112 		update = (jrecv->chapterc_value[newx] == 0) ||
1113 		  ((jrecv->chapterc_value[newx] & NSYS_SM_RV_CLRF) != newy);
1114 
1115 		if (update)
1116 		  jrecv->chapterc_value[newx] = newy | NSYS_SM_RV_SETF;
1117 	      }
1118 	    else
1119 	      unexpected = 1;
1120 	    break;
1121 	  }
1122 
1123 	  if (update && unexpected)
1124 	    unexpected = update = 0;   /* unexpected log format -- do later */
1125 
1126 	  if (update)
1127 	    {
1128 	      update = 0;
1129 
1130 	      if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1131 					    jrecv->chan | CSYS_MIDI_CC,
1132 					    newx, newy))
1133 		  return NSYS_JOURNAL_FILLEDBUFF;
1134 
1135 	      if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1136 		printf("CntrlLog %hhu: --> %hhu\n", newx, newy);
1137 	    }
1138 	}
1139       loglen--;
1140       p += NSYS_SM_CC_LOGSIZE;
1141     }
1142 
1143   return NSYS_JOURNAL_RECOVERED;
1144 }
1145 
1146 /****************************************************************/
1147 /*               process chapter M (parameters)                 */
1148 /****************************************************************/
1149 
nsys_netin_jrec_param(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,short paramlen,unsigned char many,unsigned char * buff,long * fill,long size)1150 int nsys_netin_jrec_param(nsys_source * sptr, unsigned char * p,
1151 			  nsys_netout_jrecv_state * jrecv,
1152 			  short paramlen, unsigned char many,
1153 			  unsigned char * buff, long * fill,
1154 			  long size)
1155 
1156 {
1157   unsigned char msb_num, lsb_num, msb_val, lsb_val, toc;
1158   int has_j, has_k, has_l, has_m, has_n;
1159   short cbutton;
1160   int i, rpnlog, rpnlast, final_state, skip, adjust, val_eq, button_eq;
1161   int repair = 0;
1162 
1163   /*~~~~~~~~~~~~~~~~~~~*/
1164   /* repair RTP values */
1165   /*___________________*/
1166 
1167   rpnlast = NSYS_SM_CM_TRANS_NONE;
1168   msb_num = lsb_num = 0;
1169   adjust = 0;
1170 
1171   if (p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKP)
1172     i = NSYS_SM_CM_HDRSIZE + NSYS_SM_CM_PENDINGSIZE;
1173   else
1174     i = NSYS_SM_CM_HDRSIZE;
1175 
1176   if ((p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKZ) &&
1177       ((p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKU) ||
1178        (p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKW)))
1179     adjust = 1;
1180 
1181   rpnlast = (p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKU) ?
1182     NSYS_SM_CM_TRANS_RPN : NSYS_SM_CM_TRANS_NRPN;
1183 
1184   while (i + NSYS_SM_CM_LOGHDRSIZE - adjust <= paramlen)
1185     {
1186       skip = (p[i + NSYS_SM_CM_LOC_PNUMLSB] & NSYS_SM_CHKS) && !many;
1187       lsb_num = p[i + NSYS_SM_CM_LOC_PNUMLSB] & NSYS_SM_CLRS;
1188 
1189       if (!adjust)
1190 	{
1191 	  msb_num = p[i + NSYS_SM_CM_LOC_PNUMMSB] & NSYS_SM_CM_CLRQ;
1192 	  rpnlast = (p[i + NSYS_SM_CM_LOC_PNUMMSB] & NSYS_SM_CM_CHKQ) ?
1193 	    NSYS_SM_CM_TRANS_NRPN : NSYS_SM_CM_TRANS_RPN;
1194 	}
1195 
1196       toc = p[i + NSYS_SM_CM_LOC_TOC - adjust];
1197 
1198       has_j = toc & NSYS_SM_CM_TOC_CHKJ;
1199       has_k = toc & NSYS_SM_CM_TOC_CHKK;
1200       has_l = toc & NSYS_SM_CM_TOC_CHKL;
1201       has_m = toc & NSYS_SM_CM_TOC_CHKM;
1202       has_n = toc & NSYS_SM_CM_TOC_CHKN;
1203 
1204       i += (NSYS_SM_CM_LOGHDRSIZE - adjust);
1205 
1206       if (skip || (rpnlast != NSYS_SM_CM_TRANS_RPN) || msb_num
1207 	  || (lsb_num >= NSYS_SM_CM_ARRAYSIZE) ||
1208 	  ! (has_j || has_k || has_m))
1209 	{
1210 	  i += ((has_j ? NSYS_SM_CM_ENTRYMSB_SIZE : 0) +
1211 		(has_k ? NSYS_SM_CM_ENTRYLSB_SIZE : 0) +
1212 		(has_l ? NSYS_SM_CM_ABUTTON_SIZE  : 0) +
1213 		(has_m ? NSYS_SM_CM_CBUTTON_SIZE  : 0) +
1214 		(has_n ? NSYS_SM_CM_COUNT_SIZE    : 0));
1215 	  continue;
1216 	}
1217 
1218       msb_val = jrecv->chapterm_value_msb[lsb_num];
1219       lsb_val = jrecv->chapterm_value_lsb[lsb_num];
1220       cbutton = jrecv->chapterm_cbutton[lsb_num];
1221 
1222       if (has_j)
1223 	{
1224 	  if (i < paramlen)
1225 	    {
1226 	      msb_val = p[i] & NSYS_SM_CM_CLRX;
1227 	      if (!has_k)
1228 		lsb_val = 0;
1229 	      if (!has_m)
1230 		cbutton = 0;
1231 	      i += NSYS_SM_CM_ENTRYMSB_SIZE;
1232 	    }
1233 	  else
1234 	    return NSYS_JOURNAL_CORRUPTED; /* add state repairs */
1235 	}
1236 
1237       if (has_k)
1238 	{
1239 	  if (i < paramlen)
1240 	    {
1241 	      lsb_val = p[i] & NSYS_SM_CM_CLRX;
1242 	      if (!has_m)
1243 		cbutton = 0;
1244 	      i += NSYS_SM_CM_ENTRYLSB_SIZE;
1245 	    }
1246 	  else
1247 	    return NSYS_JOURNAL_CORRUPTED; /* add state repairs */
1248 	}
1249 
1250       if (has_l)
1251 	i += NSYS_SM_CM_ABUTTON_SIZE;
1252 
1253       if (has_m)
1254 	{
1255 	  if ((i + 1) < paramlen)
1256 	    {
1257 	      cbutton = p[i] & (NSYS_SM_CM_BUTTON_CLRX & NSYS_SM_CM_BUTTON_CLRG);
1258 	      cbutton = (cbutton << 8) + p[i+1];
1259 	      if (p[i] & NSYS_SM_CM_BUTTON_CHKG)
1260 		cbutton = - cbutton;
1261 	      i += NSYS_SM_CM_CBUTTON_SIZE;
1262 	    }
1263 	  else
1264 	    return NSYS_JOURNAL_CORRUPTED; /* add state repairs */
1265 	}
1266 
1267       if (has_n)
1268 	i += NSYS_SM_CM_COUNT_SIZE;
1269 
1270       if (i > paramlen)
1271 	return NSYS_JOURNAL_CORRUPTED; /* add state repairs */
1272 
1273       val_eq = ((msb_val == jrecv->chapterm_value_msb[lsb_num]) &&
1274 		(lsb_val == jrecv->chapterm_value_lsb[lsb_num]));
1275 
1276       button_eq = (cbutton == jrecv->chapterm_cbutton[lsb_num]);
1277 
1278       if (val_eq && button_eq)
1279 	continue;
1280 
1281       repair = 1;
1282 
1283       if (!val_eq)
1284 	{
1285 	  if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1286 				       rpnlast, msb_num, lsb_num, msb_val, lsb_val))
1287 	    return NSYS_JOURNAL_FILLEDBUFF;  /* add state repairs */
1288 
1289 	  if (has_m && cbutton)
1290 	    {
1291 	      if (nsys_netin_journal_button_trans(sptr, buff, fill, size, jrecv->chan,
1292 						  rpnlast, msb_num, lsb_num, cbutton))
1293 		return NSYS_JOURNAL_FILLEDBUFF;  /* add state repairs */
1294 
1295 	    if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1296 	      printf("RPN-Log %hhu: --> (%hhu, %hhu) delta %hi\n", lsb_num,
1297 		     msb_val, lsb_val, cbutton);
1298 	    }
1299 	  else
1300 	    if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1301 	      printf("RPN-Log %hhu: --> (%hhu, %hhu)\n", lsb_num, msb_val, lsb_val);
1302 	}
1303       else
1304 	{
1305 	  if (nsys_netin_journal_button_trans(sptr, buff, fill, size, jrecv->chan,
1306 					      rpnlast, msb_num, lsb_num, cbutton -
1307 					      jrecv->chapterm_cbutton[lsb_num]))
1308 	    return NSYS_JOURNAL_FILLEDBUFF;  /* add state repairs */
1309 
1310 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1311 	    printf("RPN-Log %hhu: --> delta %hi\n", lsb_num,
1312 		   cbutton - jrecv->chapterm_cbutton[lsb_num]);
1313 	}
1314     }
1315 
1316   /*~~~~~~~~~~~~~~~~~~~~~~~*/
1317   /* determine final state */
1318   /*_______________________*/
1319 
1320   if (p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKP)
1321     {
1322       if (p[NSYS_SM_CM_LOC_PENDING] & NSYS_SM_CM_PENDING_CHKQ)
1323 	final_state = NSYS_SM_CM_STATE_PENDING_NRPN;
1324       else
1325 	final_state = NSYS_SM_CM_STATE_PENDING_RPN;
1326     }
1327   else
1328     {
1329       if (p[NSYS_SM_CM_LOC_HDR] & NSYS_SM_CM_HDR_CHKE)
1330 	{
1331 	  switch (rpnlast) {
1332 	    case NSYS_SM_CM_TRANS_RPN:
1333 	      final_state = NSYS_SM_CM_STATE_RPN;
1334 	      break;
1335 	    case NSYS_SM_CM_TRANS_NRPN:
1336 	      final_state = NSYS_SM_CM_STATE_NRPN;
1337 	      break;
1338 	  default:
1339 	    switch (jrecv->chapterm_state) {    /* should never run */
1340 	    case NSYS_SM_CM_STATE_PENDING_NRPN:
1341 	    case NSYS_SM_CM_STATE_NRPN:
1342 	      final_state = NSYS_SM_CM_STATE_NRPN;
1343 	      lsb_num = jrecv->chapterm_nrpn_lsb;
1344 	      msb_num = jrecv->chapterm_nrpn_msb;
1345 	      break;
1346 	    default:
1347 	      final_state = NSYS_SM_CM_STATE_RPN;
1348 	      lsb_num = jrecv->chapterm_rpn_lsb;
1349 	      msb_num = jrecv->chapterm_rpn_msb;
1350 	      break;
1351 	    }
1352 	  }
1353 	}
1354       else
1355 	final_state = NSYS_SM_CM_STATE_OFF;
1356     }
1357 
1358   /*~~~~~~~~~~~~~~~~~~~~*/
1359   /* exit if no changes */
1360   /*____________________*/
1361 
1362   if ((repair == 0) && (final_state == jrecv->chapterm_state))
1363     {
1364       switch (final_state) {
1365       case NSYS_SM_CM_STATE_OFF:
1366 	return NSYS_JOURNAL_RECOVERED;
1367       case NSYS_SM_CM_STATE_RPN:
1368 	if ((lsb_num == jrecv->chapterm_rpn_lsb)
1369 	    && (msb_num == jrecv->chapterm_rpn_msb))
1370 	  return NSYS_JOURNAL_RECOVERED;
1371 	break;
1372       case NSYS_SM_CM_STATE_PENDING_RPN:
1373 	if ((p[NSYS_SM_CM_LOC_PENDING] & NSYS_SM_CM_PENDING_CLRQ)
1374 	    == jrecv->chapterm_rpn_msb)
1375 	  return NSYS_JOURNAL_RECOVERED;
1376 	break;
1377       case NSYS_SM_CM_STATE_NRPN:
1378 	if ((lsb_num == jrecv->chapterm_nrpn_lsb)
1379 	    && (msb_num == jrecv->chapterm_nrpn_msb))
1380 	  return NSYS_JOURNAL_RECOVERED;
1381 	break;
1382       case NSYS_SM_CM_STATE_PENDING_NRPN:
1383 	if ((p[NSYS_SM_CM_LOC_PENDING] & NSYS_SM_CM_PENDING_CLRQ)
1384 	    == jrecv->chapterm_rpn_msb)
1385 	  return NSYS_JOURNAL_RECOVERED;
1386 	break;
1387       }
1388     }
1389 
1390   /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1391   /* do transaction repairs for each state */
1392   /*_______________________________________*/
1393 
1394   switch (final_state) {
1395   case NSYS_SM_CM_STATE_OFF:
1396     jrecv->chapterm_state = NSYS_SM_CM_STATE_OFF;
1397     if (!repair)
1398       {
1399 	rpnlog = (NSYS_SM_CM_TRANS_RPN | NSYS_SM_CM_TRANS_NO_OPEN
1400 		  | NSYS_SM_CM_TRANS_NO_SET);
1401 	if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1402 				     rpnlog, 0, 0, 0, 0))
1403 	  return NSYS_JOURNAL_FILLEDBUFF;   /* add state repairs */
1404       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1405 	printf("ParamLog  --> off-state\n");
1406       }
1407     break;
1408   case NSYS_SM_CM_STATE_RPN:
1409     jrecv->chapterm_state = NSYS_SM_CM_STATE_RPN;
1410     jrecv->chapterm_rpn_lsb = lsb_num;
1411     jrecv->chapterm_rpn_msb = msb_num;
1412     rpnlog = (NSYS_SM_CM_TRANS_RPN | NSYS_SM_CM_TRANS_NO_SET
1413 	      | NSYS_SM_CM_TRANS_NO_CLOSE);
1414     if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1415 				 rpnlog, msb_num, lsb_num, 0, 0))
1416       return NSYS_JOURNAL_FILLEDBUFF;  /* add state repairs */
1417     if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1418       printf("ParamLog: --> rpn-state (%hhu, %hhu)\n", msb_num, lsb_num);
1419     break;
1420   case NSYS_SM_CM_STATE_NRPN:
1421     jrecv->chapterm_state = NSYS_SM_CM_STATE_NRPN;
1422     jrecv->chapterm_nrpn_lsb = lsb_num;
1423     jrecv->chapterm_nrpn_msb = msb_num;
1424     rpnlog = (NSYS_SM_CM_TRANS_NRPN | NSYS_SM_CM_TRANS_NO_SET
1425 	      | NSYS_SM_CM_TRANS_NO_CLOSE);
1426     if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1427 				 rpnlog, msb_num, lsb_num, 0, 0))
1428       return NSYS_JOURNAL_FILLEDBUFF;  /* add state repairs */
1429     if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1430       printf("ParamLog: --> nrpn-state (%hhu, %hhu)\n", msb_num, lsb_num);
1431     break;
1432   case NSYS_SM_CM_STATE_PENDING_RPN:
1433     if (!repair && (jrecv->chapterm_state != NSYS_SM_CM_STATE_OFF))
1434       {
1435 	if ((jrecv->chapterm_state == NSYS_SM_CM_STATE_PENDING_RPN) ||
1436 	    (jrecv->chapterm_state == NSYS_SM_CM_STATE_RPN))
1437 	  rpnlog = (NSYS_SM_CM_TRANS_RPN | NSYS_SM_CM_TRANS_NO_OPEN
1438 		    | NSYS_SM_CM_TRANS_NO_SET);
1439 	else
1440 	  rpnlog = (NSYS_SM_CM_TRANS_NRPN | NSYS_SM_CM_TRANS_NO_OPEN
1441 		    | NSYS_SM_CM_TRANS_NO_SET);
1442 
1443 	if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1444 				     rpnlog, 0, 0, 0, 0))
1445 	  return NSYS_JOURNAL_FILLEDBUFF;   /* add state repairs */
1446       }
1447       jrecv->chapterm_state = NSYS_SM_CM_STATE_PENDING_RPN;
1448       jrecv->chapterm_rpn_msb = p[NSYS_SM_CM_LOC_PENDING] & NSYS_SM_CM_PENDING_CLRQ;
1449       jrecv->chapterm_rpn_lsb = 0;
1450       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1451 				    jrecv->chan | CSYS_MIDI_CC,
1452 				    CSYS_MIDI_CC_RPN_MSB
1453 				    , jrecv->chapterm_rpn_msb))
1454 	    return NSYS_JOURNAL_FILLEDBUFF; /* add state repairs */
1455       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1456 	printf("ParamLog: --> rpn-pending (%hhu, 0)\n", jrecv->chapterm_rpn_msb);
1457       break;
1458   case NSYS_SM_CM_STATE_PENDING_NRPN:
1459     if (!repair && (jrecv->chapterm_state != NSYS_SM_CM_STATE_OFF))
1460       {
1461 	if ((jrecv->chapterm_state == NSYS_SM_CM_STATE_PENDING_RPN) ||
1462 	    (jrecv->chapterm_state == NSYS_SM_CM_STATE_RPN))
1463 	  rpnlog = (NSYS_SM_CM_TRANS_RPN | NSYS_SM_CM_TRANS_NO_OPEN
1464 		    | NSYS_SM_CM_TRANS_NO_SET);
1465 	else
1466 	  rpnlog = (NSYS_SM_CM_TRANS_NRPN | NSYS_SM_CM_TRANS_NO_OPEN
1467 		    | NSYS_SM_CM_TRANS_NO_SET);
1468 
1469 	if (nsys_netin_journal_trans(sptr, buff, fill, size, jrecv->chan,
1470 				     rpnlog, 0, 0, 0, 0))
1471 	  return NSYS_JOURNAL_FILLEDBUFF;   /* add state repairs */
1472       }
1473       jrecv->chapterm_state = NSYS_SM_CM_STATE_PENDING_NRPN;
1474       jrecv->chapterm_nrpn_msb = p[NSYS_SM_CM_LOC_PENDING] & NSYS_SM_CM_PENDING_CLRQ;
1475       jrecv->chapterm_nrpn_lsb = 0;
1476       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1477 				    jrecv->chan | CSYS_MIDI_CC,
1478 				    CSYS_MIDI_CC_NRPN_MSB,
1479 				    jrecv->chapterm_nrpn_msb))
1480 	return NSYS_JOURNAL_FILLEDBUFF; /* add state repairs */
1481       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1482 	printf("ParamLog: --> nrpn-pending (%hhu, 0)\n", jrecv->chapterm_nrpn_msb);
1483       break;
1484   }
1485 
1486   return NSYS_JOURNAL_RECOVERED;
1487 }
1488 
1489 /****************************************************************/
1490 /*               process chapter W (pitch wheel)                */
1491 /****************************************************************/
1492 
1493 
nsys_netin_jrec_wheel(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,unsigned char * buff,long * fill,long size)1494 int nsys_netin_jrec_wheel(nsys_source * sptr, unsigned char * p,
1495 			  nsys_netout_jrecv_state * jrecv,
1496 			  unsigned char * buff,
1497 			  long * fill, long size)
1498 
1499 {
1500   unsigned char newx, newy;
1501 
1502   newx = p[NSYS_SM_CW_LOC_FIRST] & NSYS_SM_CLRS;
1503   newy = p[NSYS_SM_CW_LOC_SECOND] & NSYS_SM_CLRS;
1504 
1505   if ((newx != (jrecv->chapterw_first & NSYS_SM_RV_CLRF)) ||
1506       (newy != jrecv->chapterw_second) ||
1507       (jrecv->chapterw_first == 0))
1508     {
1509       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1510 				    jrecv->chan | CSYS_MIDI_WHEEL,
1511 				    newx, newy))
1512 	return NSYS_JOURNAL_FILLEDBUFF;
1513 
1514       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1515 	printf("PWheel (%hhu, %hhu) --> (%hhu, %hhu)\n",
1516 	       jrecv->chapterw_first & NSYS_SM_CLRS,
1517 	       jrecv->chapterw_second, newx, newy);
1518 
1519       jrecv->chapterw_first = newx | NSYS_SM_RV_SETF;
1520       jrecv->chapterw_second = newy;
1521     }
1522 
1523   return NSYS_JOURNAL_RECOVERED;
1524 }
1525 
1526 
1527 
1528 
1529 /****************************************************************/
1530 /*               process Note Logs of chapter N                 */
1531 /****************************************************************/
1532 
nsys_netin_jrec_notelog(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,unsigned char many,short loglen,unsigned char * checkptr,unsigned char * buff,long * fill,long size)1533 int nsys_netin_jrec_notelog(nsys_source * sptr, unsigned char * p,
1534 			    nsys_netout_jrecv_state * jrecv, unsigned char many,
1535 			    short loglen, unsigned char * checkptr,
1536 			    unsigned char * buff,
1537 			    long * fill, long size)
1538 
1539 {
1540   unsigned char newx, newy, vel, i;
1541   int yflag, noteon, noteoff, dated, predate;
1542   unsigned long check_ext;
1543 
1544   /*********************************************/
1545   /* prepare extended checkpoint packet number */
1546   /*********************************************/
1547 
1548   check_ext = ntohs(*((unsigned short *)checkptr));
1549 
1550   if (check_ext < sptr->hi_lobits)
1551     check_ext |= (sptr->hi_ext & NSYS_RTPSEQ_EXMASK);
1552   else
1553     check_ext |= ((sptr->hi_ext & NSYS_RTPSEQ_EXMASK)
1554 		  - NSYS_RTPSEQ_EXINCR);
1555 
1556   /**************************/
1557   /* loop through note logs */
1558   /**************************/
1559 
1560   while (loglen)
1561     {
1562       if ((!(p[NSYS_SM_CN_LOC_NUM] & NSYS_SM_CHKS)) || many)
1563 	{
1564 	  newx = p[NSYS_SM_CN_LOC_NUM] & NSYS_SM_CLRS;
1565 	  newy = p[NSYS_SM_CN_LOC_VEL] & NSYS_SM_CN_CLRY;
1566 	  yflag = (p[NSYS_SM_CN_LOC_VEL] & NSYS_SM_CN_CHKY);
1567 	  vel = jrecv->chaptern_vel[newx];
1568 
1569 	  /**************************************/
1570 	  /* by default, turn off all notes ... */
1571 	  /**************************************/
1572 
1573 	  noteoff = jrecv->chaptern_ref[newx];
1574 
1575 	  /******************************************************/
1576 	  /* ... and play the new NoteOn if it won't sound late */
1577 	  /******************************************************/
1578 
1579 	  noteon = (newy != 0) && yflag && sptr->ontime;
1580 
1581 	  /*************************************/
1582 	  /* exceptions for the ambigious case */
1583 	  /*************************************/
1584 
1585 	  if ((noteoff == 1)  &&               /* one note is playing */
1586 	      (vel && newy && (vel == newy)))  /* unchanged velocity  */
1587 	    {
1588 	      /* has old note been playing a long time? */
1589 
1590 	      dated = NSYS_SM_CN_RECDELAY < (nsys_netout_tstamp -
1591 					     jrecv->chaptern_tstamp[newx]);
1592 
1593 	      /* does playing note predate checkpoint? (if so, different) */
1594 
1595 	      predate = (jrecv->chaptern_extseq[newx] < check_ext);
1596 
1597 	      if (noteon)
1598 		{
1599 		  /* noteon = 1 because new note is recent. if the evidence */
1600 		  /* indicates old note is recent too, then let note ring   */
1601 
1602 		  if ((!predate) && (!dated))
1603 		      noteon = noteoff = 0;
1604 
1605 		  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1606 		    printf(" -EX1- ");
1607 		}
1608 	      else
1609 		{
1610 		  /* noteon = 0 because we think new note is old. if the   */
1611 		  /* old note appears old too, then let the note ring      */
1612 
1613 		  if (predate || dated)
1614 		    noteoff = 0;
1615 
1616 		  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1617 		    printf(" -EX2- ");
1618 		}
1619 	    }
1620 
1621 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1622 	    {
1623 	      printf("NoteLog %hhu: %s(%hhu, %hhu); Actions: ",
1624 		     newx, (p[NSYS_SM_CN_LOC_VEL] & NSYS_SM_CN_CHKY)
1625 		     ? "#" : "-", vel, newy);
1626 
1627 	      if (noteoff)
1628 		printf(" NoteOff ");
1629 
1630 	      if (noteoff > 1)
1631 		printf( "(%i) ", noteoff);
1632 
1633 	      if (noteon)
1634 		printf(" NoteOn");
1635 
1636 	      printf("\n");
1637 	    }
1638 
1639 	  /* do NoteOff, then NoteOn, then update state */
1640 
1641 	  for (i = 0; i < noteoff; i++)
1642 	    if ((nsys_netin_journal_addcmd_three
1643 		 (sptr, buff, fill, size,
1644 		  jrecv->chan | CSYS_MIDI_NOTEOFF, newx, 64)))
1645 	      return NSYS_JOURNAL_FILLEDBUFF;
1646 
1647 	  if (noteon && (nsys_netin_journal_addcmd_three
1648 			 (sptr, buff, fill, size,
1649 			  jrecv->chan | CSYS_MIDI_NOTEON, newx, newy)))
1650 	    return NSYS_JOURNAL_FILLEDBUFF;
1651 
1652 	  if (noteoff || noteon)
1653 	    {
1654 	      jrecv->chaptern_ref[newx] -= (noteoff - noteon);
1655 
1656 	      if (noteon)
1657 		{
1658 		  jrecv->chaptern_vel[newx] = newy;
1659 		  jrecv->chaptern_tstamp[newx] = nsys_netout_tstamp;
1660 		  jrecv->chaptern_extseq[newx] = sptr->hi_ext;
1661 		}
1662 	      else
1663 		if (jrecv->chaptern_ref[newx] == 0)
1664 		  jrecv->chaptern_vel[newx] = 0;
1665 	    }
1666 	}
1667       loglen--;
1668       p += NSYS_SM_CN_LOGSIZE;
1669     }
1670 
1671   return NSYS_JOURNAL_RECOVERED;
1672 }
1673 
1674 
1675 
1676 /****************************************************************/
1677 /*               process bitfields of chapter N                */
1678 /****************************************************************/
1679 
nsys_netin_jrec_bitfield(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,unsigned char low,unsigned char high,unsigned char * buff,long * fill,long size)1680 int nsys_netin_jrec_bitfield(nsys_source * sptr, unsigned char * p,
1681 			     nsys_netout_jrecv_state * jrecv, unsigned char low,
1682 			     unsigned char high, unsigned char * buff,
1683 			     long * fill, long size)
1684 {
1685   int i, first;
1686   unsigned char newx, bitfield;
1687 
1688   while (low <= high)
1689     {
1690       i = 0;
1691       bitfield = 128;
1692       while (bitfield)
1693 	{
1694 	  if ((*p) & bitfield)
1695 	    {
1696 	      newx = (low << NSYS_SM_CN_BFSHIFT) + i;
1697 
1698 	      if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1699 		printf("Bitfield %hhu: (%hhu); ", newx,
1700 		       jrecv->chaptern_vel[newx]);
1701 
1702 	      first = 1;
1703 
1704 	      while (jrecv->chaptern_ref[newx])
1705 		{
1706 		  if (nsys_netin_journal_addcmd_three
1707 		      (sptr, buff, fill, size,
1708 		       jrecv->chan | CSYS_MIDI_NOTEOFF, newx, 64))
1709 		    return NSYS_JOURNAL_FILLEDBUFF;
1710 
1711 		  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1712 		    if (first)
1713 		      {
1714 			first = 0;
1715 			printf(" Actions: Noteoff (%hhu) ",
1716 			       jrecv->chaptern_ref[newx]);
1717 		      }
1718 
1719 		  jrecv->chaptern_ref[newx]--;
1720 		}
1721 
1722 	      if (jrecv->chaptern_vel[newx])
1723 		jrecv->chaptern_vel[newx] = 0;
1724 
1725 	      if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1726 		printf("\n");
1727 	    }
1728 	  bitfield >>= 1;
1729 	  i++;
1730 	}
1731       low++;
1732       p++;
1733     }
1734 
1735   return NSYS_JOURNAL_RECOVERED;
1736 }
1737 
1738 /****************************************************************/
1739 /*               process chapter T (channel touch)              */
1740 /****************************************************************/
1741 
nsys_netin_jrec_ctouch(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,unsigned char * buff,long * fill,long size)1742 int nsys_netin_jrec_ctouch(nsys_source * sptr, unsigned char * p,
1743 			   nsys_netout_jrecv_state * jrecv,
1744 			   unsigned char * buff,
1745 			   long * fill, long size)
1746 
1747 {
1748   unsigned char newx;
1749 
1750   newx = p[NSYS_SM_CT_LOC_PRESSURE] & NSYS_SM_CLRS;
1751   if ((newx != (jrecv->chaptert_pressure & NSYS_SM_RV_CLRF)) ||
1752       (jrecv->chaptert_pressure == 0))
1753     {
1754       if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
1755 				    jrecv->chan | CSYS_MIDI_CTOUCH, newx))
1756 	  return NSYS_JOURNAL_FILLEDBUFF;
1757 
1758       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1759 	printf("CTouch (%hhu) --> (%hhu)\n",
1760 	       jrecv->chaptert_pressure & NSYS_SM_RV_CLRF, newx);
1761 
1762       jrecv->chaptert_pressure = newx | NSYS_SM_RV_SETF;
1763     }
1764 
1765   return NSYS_JOURNAL_RECOVERED;
1766 }
1767 
1768 /****************************************************************/
1769 /*               process chapter P (poly touch)                 */
1770 /****************************************************************/
1771 
nsys_netin_jrec_ptouch(nsys_source * sptr,unsigned char * p,nsys_netout_jrecv_state * jrecv,short loglen,unsigned char many,unsigned char * buff,long * fill,long size)1772 int nsys_netin_jrec_ptouch(nsys_source * sptr, unsigned char * p,
1773 			   nsys_netout_jrecv_state * jrecv, short loglen,
1774 			   unsigned char many, unsigned char * buff,
1775 			   long * fill, long size)
1776 
1777 {
1778   unsigned char newx, newy;
1779 
1780   p += NSYS_SM_CA_HDRSIZE;
1781   while (loglen)
1782     {
1783       if ((!(p[NSYS_SM_CA_LOC_NUM] & NSYS_SM_CHKS)) || many)
1784 	{
1785 	  newx = p[NSYS_SM_CA_LOC_NUM] & NSYS_SM_CLRS;
1786 	  newy = p[NSYS_SM_CA_LOC_PRESSURE] & NSYS_SM_CA_CLRX;
1787 	  if (((jrecv->chaptera_pressure[newx] & NSYS_SM_RV_CLRF)
1788 	       != newy) || (jrecv->chaptera_pressure[newx] == 0))
1789 	    {
1790 	      if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1791 					    jrecv->chan | CSYS_MIDI_PTOUCH,
1792 					    newx, newy))
1793 		  return NSYS_JOURNAL_FILLEDBUFF;
1794 
1795 	      if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1796 		printf("PTouchLog %hhu: %hhu --> %hhu\n", newx,
1797 		       jrecv->chaptera_pressure[newx] &
1798 		       NSYS_SM_RV_CLRF, newy);
1799 
1800 	      jrecv->chaptera_pressure[newx] = (newy |
1801 						NSYS_SM_RV_SETF);
1802 	    }
1803 	}
1804       loglen--;
1805       p += NSYS_SM_CA_LOGSIZE;
1806     }
1807 
1808   return NSYS_JOURNAL_RECOVERED;
1809 }
1810 
1811 /****************************************************************/
1812 /*              process System Chapter D/B (Reset)              */
1813 /****************************************************************/
1814 
1815 
nsys_netin_jrec_reset(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)1816 int nsys_netin_jrec_reset(nsys_source * sptr, unsigned char * ps,
1817 			  nsys_netout_jrecv_system_state * jrecvsys,
1818 			  unsigned char * buff,
1819 			  long * fill, long size)
1820 
1821 {
1822   unsigned char reset;
1823 
1824   reset = ps[0] & NSYS_SM_CLRS;
1825 
1826   if (reset != jrecvsys->chapterd_reset)
1827     {
1828       nsys_netin_journal_clear_active(CSYS_MIDI_SYSTEM_RESET);
1829 
1830       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size, CSYS_MIDI_SYSTEM_RESET))
1831 	  return NSYS_JOURNAL_FILLEDBUFF;
1832 
1833       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1834 	printf("System Reset (%hhu) --> (%hhu)\n", jrecvsys->chapterd_reset, reset);
1835 
1836       jrecvsys->chapterd_reset = reset;
1837     }
1838 
1839   return NSYS_JOURNAL_RECOVERED;
1840 }
1841 
1842 
1843 /****************************************************************/
1844 /*           process System Chapter D/G (Tune Request)          */
1845 /****************************************************************/
1846 
1847 
nsys_netin_jrec_tune(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)1848 int nsys_netin_jrec_tune(nsys_source * sptr, unsigned char * ps,
1849 			 nsys_netout_jrecv_system_state * jrecvsys,
1850 			 unsigned char * buff,
1851 			 long * fill, long size)
1852 
1853 {
1854   unsigned char tune;
1855 
1856   tune = ps[0] & NSYS_SM_CLRS;
1857 
1858   if (tune != jrecvsys->chapterd_tune)
1859     {
1860       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
1861 					CSYS_MIDI_SYSTEM_TUNE_REQUEST))
1862 	  return NSYS_JOURNAL_FILLEDBUFF;
1863 
1864       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1865 	printf("Tune Request (%hhu) --> (%hhu)\n", jrecvsys->chapterd_tune, tune);
1866 
1867       jrecvsys->chapterd_tune = tune;
1868     }
1869 
1870   return NSYS_JOURNAL_RECOVERED;
1871 }
1872 
1873 
1874 /****************************************************************/
1875 /*           process System Chapter D/H (Song Select)           */
1876 /****************************************************************/
1877 
1878 
nsys_netin_jrec_song(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)1879 int nsys_netin_jrec_song(nsys_source * sptr, unsigned char * ps,
1880 			 nsys_netout_jrecv_system_state * jrecvsys,
1881 			 unsigned char * buff,
1882 			 long * fill, long size)
1883 
1884 {
1885   unsigned char song;
1886 
1887   song = ps[0] & NSYS_SM_CLRS;
1888 
1889   if (song != jrecvsys->chapterd_song)
1890     {
1891       if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
1892 					CSYS_MIDI_SYSTEM_SONG_SELECT, song))
1893 	  return NSYS_JOURNAL_FILLEDBUFF;
1894 
1895       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1896 	printf("Song Select (%hhu) --> (%hhu)\n", jrecvsys->chapterd_song, song);
1897 
1898       jrecvsys->chapterd_song = song;
1899     }
1900 
1901   return NSYS_JOURNAL_RECOVERED;
1902 }
1903 
1904 /****************************************************************/
1905 /*           process System Chapter D/J (unused Common)        */
1906 /****************************************************************/
1907 
1908 
nsys_netin_jrec_scj(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)1909 int nsys_netin_jrec_scj(nsys_source * sptr, unsigned char * ps,
1910 			nsys_netout_jrecv_system_state * jrecvsys,
1911 			unsigned char * buff,
1912 			long * fill, long size)
1913 
1914 {
1915   unsigned char ndata = CSYS_MIDI_SYSTEM_SYSEX_END;
1916   unsigned char vdata = CSYS_MIDI_SYSTEM_SYSEX_END;
1917   unsigned char count = 0;
1918   int has_count = 0;
1919   int dstart, dsize, update;
1920 
1921   dstart = NSYS_SM_CD_COMMON_LOC_FIELDS;
1922 
1923   if ((has_count = (ps[NSYS_SM_CD_COMMON_LOC_TOC] & NSYS_SM_CD_COMMON_TOC_CHKC)))
1924     {
1925       count = ps[NSYS_SM_CD_COMMON_LOC_FIELDS];
1926       dstart++;
1927     }
1928 
1929   if (ps[NSYS_SM_CD_COMMON_LOC_TOC] & NSYS_SM_CD_COMMON_TOC_CHKV)
1930     {
1931       ndata = ps[dstart] & NSYS_SM_RV_CLRF;
1932       if (ps[dstart] & NSYS_SM_RV_CHKF)
1933 	vdata = ps[dstart + 1] & NSYS_SM_RV_CLRF;
1934     }
1935 
1936   dsize = ((ndata != CSYS_MIDI_SYSTEM_SYSEX_END) +
1937 	   (vdata != CSYS_MIDI_SYSTEM_SYSEX_END));
1938 
1939   if (has_count)
1940     {
1941       if ((update = (count != jrecvsys->chapterd_scj_count)))
1942 	jrecvsys->chapterd_scj_count = count;
1943     }
1944   else
1945     update = ((ndata != jrecvsys->chapterd_scj_data1) ||
1946 	      (vdata != jrecvsys->chapterd_scj_data2));
1947 
1948   if (update)
1949     switch (dsize) {
1950     case 0:
1951       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
1952 					CSYS_MIDI_SYSTEM_UNUSED1))
1953 	return NSYS_JOURNAL_FILLEDBUFF;
1954 
1955       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1956 	printf("Common %hhu\n", CSYS_MIDI_SYSTEM_UNUSED1);
1957       break;
1958     case 1:
1959       if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
1960 					CSYS_MIDI_SYSTEM_UNUSED1,
1961 					ndata))
1962 	return NSYS_JOURNAL_FILLEDBUFF;
1963 
1964       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1965 	printf("Common %hhu (%hhu) --> (%hhu)\n",
1966 	       CSYS_MIDI_SYSTEM_UNUSED1,
1967 	       jrecvsys->chapterd_scj_data1, ndata);
1968       break;
1969     case 2:
1970       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
1971 					  CSYS_MIDI_SYSTEM_UNUSED1,
1972 					  ndata, vdata))
1973 	return NSYS_JOURNAL_FILLEDBUFF;
1974 
1975       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
1976 	printf("Common %hhu (%hhu %hhu) --> (%hhu %hhu)\n",
1977 	       CSYS_MIDI_SYSTEM_UNUSED1,
1978 	       jrecvsys->chapterd_scj_data1,
1979 	       jrecvsys->chapterd_scj_data2,
1980 	       ndata, vdata);
1981       break;
1982     }
1983 
1984   if (ndata != jrecvsys->chapterd_scj_data1)
1985     jrecvsys->chapterd_scj_data1 = ndata;
1986 
1987   if (ndata != jrecvsys->chapterd_scj_data2)
1988     jrecvsys->chapterd_scj_data2 = vdata;
1989 
1990   return NSYS_JOURNAL_RECOVERED;
1991 }
1992 
1993 /****************************************************************/
1994 /*           process System Chapter D/K (unused Common)        */
1995 /****************************************************************/
1996 
1997 
nsys_netin_jrec_sck(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)1998 int nsys_netin_jrec_sck(nsys_source * sptr, unsigned char * ps,
1999 			nsys_netout_jrecv_system_state * jrecvsys,
2000 			unsigned char * buff,
2001 			long * fill, long size)
2002 {
2003   unsigned char ndata = CSYS_MIDI_SYSTEM_SYSEX_END;
2004   unsigned char vdata = CSYS_MIDI_SYSTEM_SYSEX_END;
2005   unsigned char count = 0;
2006   int has_count = 0;
2007   int dstart, dsize, update;
2008 
2009   dstart = NSYS_SM_CD_COMMON_LOC_FIELDS;
2010 
2011   if ((has_count = (ps[NSYS_SM_CD_COMMON_LOC_TOC] & NSYS_SM_CD_COMMON_TOC_CHKC)))
2012     {
2013       count = ps[NSYS_SM_CD_COMMON_LOC_FIELDS];
2014       dstart++;
2015     }
2016 
2017   if (ps[NSYS_SM_CD_COMMON_LOC_TOC] & NSYS_SM_CD_COMMON_TOC_CHKV)
2018     {
2019       ndata = ps[dstart] & NSYS_SM_RV_CLRF;
2020       if (ps[dstart] & NSYS_SM_RV_CHKF)
2021 	vdata = ps[dstart + 1] & NSYS_SM_RV_CLRF;
2022     }
2023 
2024   dsize = ((ndata != CSYS_MIDI_SYSTEM_SYSEX_END) +
2025 	   (vdata != CSYS_MIDI_SYSTEM_SYSEX_END));
2026 
2027   if (has_count)
2028     {
2029       if ((update = (count != jrecvsys->chapterd_sck_count)))
2030 	jrecvsys->chapterd_sck_count = count;
2031     }
2032   else
2033     update = ((ndata != jrecvsys->chapterd_sck_data1) ||
2034 	      (vdata != jrecvsys->chapterd_sck_data2));
2035 
2036   if (update)
2037     switch (dsize) {
2038     case 0:
2039       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2040 					CSYS_MIDI_SYSTEM_UNUSED2))
2041 	return NSYS_JOURNAL_FILLEDBUFF;
2042 
2043       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2044 	printf("Common %hhu\n", CSYS_MIDI_SYSTEM_UNUSED2);
2045       break;
2046     case 1:
2047       if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
2048 					CSYS_MIDI_SYSTEM_UNUSED2,
2049 					ndata))
2050 	return NSYS_JOURNAL_FILLEDBUFF;
2051 
2052       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2053 	printf("Common %hhu (%hhu) --> (%hhu)\n",
2054 	       CSYS_MIDI_SYSTEM_UNUSED2,
2055 	       jrecvsys->chapterd_sck_data1, ndata);
2056       break;
2057     case 2:
2058       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2059 					  CSYS_MIDI_SYSTEM_UNUSED2,
2060 					  ndata, vdata))
2061 	return NSYS_JOURNAL_FILLEDBUFF;
2062 
2063       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2064 	printf("Common %hhu (%hhu %hhu) --> (%hhu %hhu)\n",
2065 	       CSYS_MIDI_SYSTEM_UNUSED2,
2066 	       jrecvsys->chapterd_sck_data1,
2067 	       jrecvsys->chapterd_sck_data2,
2068 	       ndata, vdata);
2069       break;
2070     }
2071 
2072   if (ndata != jrecvsys->chapterd_sck_data1)
2073     jrecvsys->chapterd_sck_data1 = ndata;
2074 
2075   if (ndata != jrecvsys->chapterd_sck_data2)
2076     jrecvsys->chapterd_sck_data2 = vdata;
2077 
2078   return NSYS_JOURNAL_RECOVERED;
2079 }
2080 
2081 /****************************************************************/
2082 /*           process System Chapter D/Y (unused RealTime)       */
2083 /****************************************************************/
2084 
2085 
nsys_netin_jrec_rty(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2086 int nsys_netin_jrec_rty(nsys_source * sptr, unsigned char * ps,
2087 			nsys_netout_jrecv_system_state * jrecvsys,
2088 			unsigned char * buff,
2089 			long * fill, long size)
2090 
2091 {
2092   unsigned char rty;
2093 
2094   if (ps[NSYS_SM_CD_REALTIME_LOC_TOC] & NSYS_SM_CD_REALTIME_TOC_CHKC)
2095     {
2096       rty = ps[NSYS_SM_CD_REALTIME_LOC_FIELDS];
2097 
2098       if (rty != jrecvsys->chapterd_rty)
2099 	{
2100 	  if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2101 					    CSYS_MIDI_SYSTEM_TICK))
2102 	    return NSYS_JOURNAL_FILLEDBUFF;
2103 
2104 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2105 	    printf("RealTime 0xF9 (%hhu) --> (%hhu)\n", jrecvsys->chapterd_rty, rty);
2106 
2107 	  jrecvsys->chapterd_rty = rty;
2108 	}
2109     }
2110 
2111   return NSYS_JOURNAL_RECOVERED;
2112 }
2113 
2114 /****************************************************************/
2115 /*           process System Chapter D/Z (unused RealTime)       */
2116 /****************************************************************/
2117 
2118 
nsys_netin_jrec_rtz(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2119 int nsys_netin_jrec_rtz(nsys_source * sptr, unsigned char * ps,
2120 			nsys_netout_jrecv_system_state * jrecvsys,
2121 			unsigned char * buff,
2122 			long * fill, long size)
2123 
2124 {
2125   unsigned char rtz;
2126 
2127   if (ps[NSYS_SM_CD_REALTIME_LOC_TOC] & NSYS_SM_CD_REALTIME_TOC_CHKC)
2128     {
2129       rtz = ps[NSYS_SM_CD_REALTIME_LOC_FIELDS];
2130 
2131       if (rtz != jrecvsys->chapterd_rtz)
2132 	{
2133 	  if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2134 					    CSYS_MIDI_SYSTEM_UNUSED3))
2135 	    return NSYS_JOURNAL_FILLEDBUFF;
2136 
2137 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2138 	    printf("RealTime 0xFD (%hhu) --> (%hhu)\n", jrecvsys->chapterd_rtz, rtz);
2139 
2140 	  jrecvsys->chapterd_rtz = rtz;
2141 	}
2142     }
2143 
2144   return NSYS_JOURNAL_RECOVERED;
2145 }
2146 
2147 /****************************************************************/
2148 /*           process System Chapter V (active sense)            */
2149 /****************************************************************/
2150 
2151 
nsys_netin_jrec_sense(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2152 int nsys_netin_jrec_sense(nsys_source * sptr, unsigned char * ps,
2153 			  nsys_netout_jrecv_system_state * jrecvsys,
2154 			  unsigned char * buff,
2155 			  long * fill, long size)
2156 
2157 {
2158   unsigned char count;
2159 
2160   count = (ps[NSYS_SM_CV_LOC_COUNT] & NSYS_SM_CLRS);
2161 
2162   if (count != jrecvsys->chapterv_count)
2163     {
2164       /* a simple-minded repair approach -- later, consider sensing */
2165       /* the disappearance of active sense commands in the stream,  */
2166       /* and synthesizing them on the fly.                          */
2167 
2168       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size, CSYS_MIDI_SYSTEM_SENSE))
2169 	  return NSYS_JOURNAL_FILLEDBUFF;
2170 
2171       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2172 	printf("Active Sense (%hhu) --> (%hhu)\n", jrecvsys->chapterv_count, count);
2173 
2174       jrecvsys->chapterv_count = count;
2175     }
2176 
2177   return NSYS_JOURNAL_RECOVERED;
2178 }
2179 
2180 /****************************************************************/
2181 /*           process System Chapter Q (sequencer)               */
2182 /****************************************************************/
2183 
2184 
nsys_netin_jrec_sequence(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2185 int nsys_netin_jrec_sequence(nsys_source * sptr, unsigned char * ps,
2186 			     nsys_netout_jrecv_system_state * jrecvsys,
2187 			     unsigned char * buff,
2188 			     long * fill, long size)
2189 
2190 {
2191   long chapter_clocks, nearest_pp;
2192   int chapter_running, shadow_running;
2193   int chapter_downbeat, chapter_size;
2194 
2195   /*****************************************************/
2196   /* leave quickly if chapter and shadow are identical */
2197   /*****************************************************/
2198 
2199   chapter_size = (ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC) ? 3 : 1;
2200 
2201   if ((ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CLRS) ==
2202       jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR])
2203     {
2204       if (chapter_size == 3)
2205 	{
2206 	  if ((ps[NSYS_SM_CQ_LOC_FIELDS] ==
2207 	       jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS]) &&
2208 	      (ps[NSYS_SM_CQ_LOC_FIELDS + 1] ==
2209 	       jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_FIELDS + 1]))
2210 	    return NSYS_JOURNAL_RECOVERED;
2211 	}
2212       else
2213 	return NSYS_JOURNAL_RECOVERED;
2214     }
2215 
2216   /********************************************************/
2217   /* extract chapter and shadow state, then update shadow */
2218   /********************************************************/
2219 
2220   shadow_running = jrecvsys->chapterq_shadow[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKN;
2221   memcpy(jrecvsys->chapterq_shadow, ps, chapter_size);
2222 
2223   chapter_running = ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKN;
2224   chapter_downbeat = ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKD;
2225 
2226   if (ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_HDR_CHKC)
2227     chapter_clocks = (ps[NSYS_SM_CQ_LOC_FIELDS + 1] +
2228 		      (ps[NSYS_SM_CQ_LOC_FIELDS] << 8) +
2229 		      ((ps[NSYS_SM_CQ_LOC_HDR] & NSYS_SM_CQ_TOP_MASK) << 16));
2230   else
2231     chapter_clocks = 0;
2232 
2233   /******************************************************************/
2234   /* Do repairs -- artifact-laden repairs done here for simplicity. */
2235   /*   A production implementation would do incremental updating.   */
2236   /******************************************************************/
2237 
2238   if (shadow_running)
2239     {
2240       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2241 					CSYS_MIDI_SYSTEM_STOP))
2242 	return NSYS_JOURNAL_FILLEDBUFF;
2243 
2244       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2245 	printf("Sequencer STOP issued.\n");
2246     }
2247 
2248   nearest_pp = chapter_clocks / 6;
2249 
2250   if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2251 				      CSYS_MIDI_SYSTEM_SONG_PP, (unsigned char)
2252 				      (nearest_pp & 0x007F), (unsigned char)
2253 				      ((nearest_pp >> 7) & 0x007F)))
2254     return NSYS_JOURNAL_FILLEDBUFF;
2255 
2256   if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2257     printf("Song Position moved to %li clocks.\n", nearest_pp*6);
2258 
2259   if (chapter_downbeat)
2260     {
2261       if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2262 					CSYS_MIDI_SYSTEM_CONTINUE))
2263 	return NSYS_JOURNAL_FILLEDBUFF;
2264 
2265       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2266 	printf("Sequencer CONTINUE issued.\n");
2267 
2268       chapter_clocks -=  nearest_pp*6 - 1;
2269 
2270       while (chapter_clocks--)
2271 	if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2272 					  CSYS_MIDI_SYSTEM_CLOCK))
2273 	  return NSYS_JOURNAL_FILLEDBUFF;
2274 	else
2275 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2276 	    printf("Sequencer CLOCK issued.\n");
2277 
2278       if (!chapter_running)
2279 	{
2280 	  if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2281 					    CSYS_MIDI_SYSTEM_STOP))
2282 	    return NSYS_JOURNAL_FILLEDBUFF;
2283 
2284 	  if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2285 	    printf("Sequencer STOP issued.\n");
2286 	}
2287     }
2288   else
2289     if (chapter_running)
2290       {
2291 	if (nsys_netin_journal_addcmd_one(sptr, buff, fill, size,
2292 					  CSYS_MIDI_SYSTEM_CONTINUE))
2293 	  return NSYS_JOURNAL_FILLEDBUFF;
2294 
2295 	if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2296 	  printf("Sequencer CONTINUE issued.\n");
2297       }
2298 
2299   return NSYS_JOURNAL_RECOVERED;
2300 }
2301 
2302 /****************************************************************/
2303 /*           process System Chapter F (MIDI Time Code)          */
2304 /****************************************************************/
2305 
2306 
nsys_netin_jrec_timecode(nsys_source * sptr,unsigned char * ps,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2307 int nsys_netin_jrec_timecode(nsys_source * sptr, unsigned char * ps,
2308 			     nsys_netout_jrecv_system_state * jrecvsys,
2309 			     unsigned char * buff,
2310 			     long * fill, long size)
2311 
2312 {
2313   int complete_equal, partial_equal;
2314 
2315   /* fast path checks: breaks denote cases that may need repair */
2316 
2317   complete_equal = partial_equal = 0;
2318 
2319   do {
2320 
2321     if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC)
2322       {
2323 	if (!jrecvsys->chapterf_has_complete)
2324 	  break;
2325 
2326 	if ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKQ) ?
2327 	    !jrecvsys->chapterf_quarter : jrecvsys->chapterf_quarter)
2328 	  break;
2329 
2330 	if (memcmp(&(ps[NSYS_SM_CF_LOC_FIELDS]), jrecvsys->chapterf_complete,
2331 		   NSYS_SM_CF_SIZE_COMPLETE))
2332 	  break;
2333 
2334 	complete_equal = 1;
2335       }
2336 
2337     if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKP)
2338       {
2339 	if (!jrecvsys->chapterf_has_partial)
2340 	  break;
2341 
2342 	if ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKD) ?
2343 	    !jrecvsys->chapterf_direction : jrecvsys->chapterf_direction)
2344 	  break;
2345 
2346 	if ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_POINT_MASK) != jrecvsys->chapterf_point)
2347 	  break;
2348 
2349 	if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC)
2350 	  {
2351 	    if (memcmp(&(ps[NSYS_SM_CF_LOC_FIELDS + NSYS_SM_CF_SIZE_COMPLETE]),
2352 		       jrecvsys->chapterf_partial, NSYS_SM_CF_SIZE_PARTIAL))
2353 	      break;
2354 	  }
2355 	else
2356 	  {
2357 	    if (memcmp(&(ps[NSYS_SM_CF_LOC_FIELDS]), jrecvsys->chapterf_partial,
2358 		       NSYS_SM_CF_SIZE_PARTIAL))
2359 	      break;
2360 	  }
2361 
2362 	partial_equal = 1;
2363       }
2364     else
2365       if (jrecvsys->chapterf_has_partial)
2366 	break;
2367 
2368     return NSYS_JOURNAL_RECOVERED;   /* no repairs or state updates are needed */
2369 
2370   } while (0);
2371 
2372   /* repairs start here */
2373 
2374   if ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC) && !complete_equal)
2375     {
2376       jrecvsys->chapterf_has_complete = 1;
2377       memcpy(jrecvsys->chapterf_complete, &(ps[NSYS_SM_CF_LOC_FIELDS]),
2378 	     NSYS_SM_CF_SIZE_COMPLETE);
2379       jrecvsys->chapterf_quarter = ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKQ)
2380 				    ? 1 : 0);
2381 
2382       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2383 	  printf("Time Code COMPLETE repair.\n");
2384 
2385       /*
2386        * Later, add commands to gracefully issue Full Frame or QF command(s)
2387        */
2388     }
2389 
2390   if ((ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKP) && !partial_equal)
2391     {
2392       jrecvsys->chapterf_has_partial = 1;
2393       jrecvsys->chapterf_point = ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_POINT_MASK;
2394       jrecvsys->chapterf_direction =
2395 	(ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKD) ? 1 : 0;
2396 
2397       if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC)
2398 	memcpy(jrecvsys->chapterf_partial,
2399 	       &(ps[NSYS_SM_CF_LOC_FIELDS + NSYS_SM_CF_SIZE_COMPLETE]),
2400 	       NSYS_SM_CF_SIZE_PARTIAL);
2401       else
2402 	memcpy(jrecvsys->chapterf_partial, &(ps[NSYS_SM_CF_LOC_FIELDS]),
2403 	       NSYS_SM_CF_SIZE_PARTIAL);
2404 
2405       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2406 	  printf("Time Code PARTIAL repair.\n");
2407 
2408       /*
2409        * Later, add commands to gracefully issue QF command(s)
2410        */
2411     }
2412 
2413   if (!(ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKP))
2414     {
2415       jrecvsys->chapterf_has_partial = 0;
2416 
2417       if (ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKC)
2418 	jrecvsys->chapterf_point = ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_POINT_MASK;
2419 
2420       jrecvsys->chapterf_direction =
2421 	(ps[NSYS_SM_CF_LOC_HDR] & NSYS_SM_CF_HDR_CHKD) ? 1 : 0;
2422 
2423       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2424 	  printf("Time Code PARTIAL zeroing.\n");
2425     }
2426 
2427   return NSYS_JOURNAL_RECOVERED;
2428 }
2429 
2430 
2431 /****************************************************************/
2432 /*      track commands for System Chapter F (MIDI Time Code)    */
2433 /****************************************************************/
2434 
nsys_netin_track_timecode(nsys_netout_jrecv_system_state * jrecvsys,unsigned char ndata)2435 void nsys_netin_track_timecode(nsys_netout_jrecv_system_state *
2436 			       jrecvsys, unsigned char ndata)
2437 
2438 {
2439   unsigned char frames, seconds, minutes, hours, type, typeframe;
2440   unsigned char point, direction, idnum;
2441   unsigned char * p;
2442 
2443   point = jrecvsys->chapterf_point;
2444   direction = jrecvsys->chapterf_direction;
2445   jrecvsys->chapterf_point = (idnum = (ndata & NSYS_SM_CF_IDNUM_MASK) >> 4);
2446 
2447   /* handle QF commands with expected idnums */
2448 
2449   if ((!direction && (((point + 1) & NSYS_SM_CF_POINT_MASK) == idnum)) ||
2450       (direction && (((point - 1) & NSYS_SM_CF_POINT_MASK) == idnum)))
2451     {
2452       switch (idnum) {
2453       case NSYS_SM_CF_IDNUM_FR_LSN:
2454       case NSYS_SM_CF_IDNUM_HR_MSN:
2455 	if ((direction && (idnum == NSYS_SM_CF_IDNUM_FR_LSN)) ||
2456 	    (!direction && (idnum == NSYS_SM_CF_IDNUM_HR_MSN)))
2457 	  {
2458 	    /* handle QF commands that end the frame */
2459 
2460 	    if (jrecvsys->chapterf_has_partial)
2461 	      {
2462 		jrecvsys->chapterf_has_partial = 0;
2463 		jrecvsys->chapterf_has_complete = 1;
2464 		jrecvsys->chapterf_quarter = 1;
2465 
2466 		memcpy(jrecvsys->chapterf_complete, jrecvsys->chapterf_partial,
2467 		       NSYS_SM_CF_SIZE_PARTIAL);
2468 
2469 		if (!direction)
2470 		  {
2471 		    p = &(jrecvsys->chapterf_complete[NSYS_SM_CF_QF_LOC_HR_MSN]);
2472 		    (*p) &= NSYS_SM_CF_ODD_CLR;
2473 		    (*p) |= (ndata & NSYS_SM_CF_PAYLOAD_MASK);
2474 		  }
2475 		else
2476 		  {
2477 		    p = &(jrecvsys->chapterf_complete[NSYS_SM_CF_QF_LOC_FR_LSN]);
2478 		    (*p) &= NSYS_SM_CF_EVEN_CLR;
2479 		    (*p) |= (ndata << 4);
2480 		  }
2481 
2482 		/* for forward tape motion, adjust complete by two frames */
2483 
2484 		if (!direction)
2485 		  {
2486 		    p = jrecvsys->chapterf_complete;
2487 
2488 		    frames = ((p[0] >> 4) & 0x0F) + ((p[0] & 0x01) << 4);
2489 		    if ((type = p[3] & 0x06))
2490 		      typeframe = (type == 2) ? 25 : 30;
2491 		    else
2492 		      typeframe = 24;
2493 
2494 		    if ((frames += 2) >= typeframe)
2495 		      {
2496 			frames -= typeframe;
2497 			seconds = ((p[1] >> 4) & 0x0F) + ((p[1] & 0x03) << 4);
2498 			if ((++seconds) >= 60)
2499 			  {
2500 			    seconds -= 60;
2501 			    minutes = ((p[2] >> 4) & 0x0F) + ((p[2] & 0x03) << 4);
2502 			    if ((++minutes) >= 60)
2503 			      {
2504 				minutes -= 60;
2505 				hours = ((p[3] >> 4) & 0x0F) + ((p[3] & 0x01) << 4);
2506 				if ((++hours) >= 24)
2507 				  hours -= 24;
2508 				p[3] = ((0x0F & hours) << 4)  | (hours >> 4) | type;
2509 			      }
2510 			    p[2] = ((0x0F & minutes) << 4) | (minutes >> 4);
2511 			  }
2512 			p[1] = ((0x0F & seconds) << 4) | (seconds >> 4);
2513 		      }
2514 		    p[0] = ((0x0F & frames) << 4)  | (frames >> 4);
2515 		  }
2516 
2517 	      }
2518 	    return;
2519 	  }
2520 
2521 	/* handle QF commands that start a frame */
2522 
2523 	if (!(jrecvsys->chapterf_has_partial))
2524 	  {
2525 	    jrecvsys->chapterf_has_partial = 1;
2526 	    memset(jrecvsys->chapterf_partial, 0, NSYS_SM_CF_SIZE_PARTIAL);
2527 	  }
2528       default:           /* handle all expected non-frame-ending MT values */
2529 	if (jrecvsys->chapterf_has_partial)
2530 	  {
2531 	    p = &(jrecvsys->chapterf_partial[idnum >> 1]);
2532 	    if (idnum & 0x01)
2533 	      {
2534 		(*p) &= NSYS_SM_CF_ODD_CLR;
2535 		(*p) |= (ndata & NSYS_SM_CF_PAYLOAD_MASK);
2536 	      }
2537 	    else
2538 	      {
2539 		(*p) &= NSYS_SM_CF_EVEN_CLR;
2540 		(*p) |= (ndata << 4);
2541 	      }
2542 	  }
2543 	return;
2544       }
2545     }
2546 
2547   /* handle tape direction change that happens in a legal way */
2548 
2549   if ((idnum == NSYS_SM_CF_IDNUM_FR_LSN) || (idnum == NSYS_SM_CF_IDNUM_HR_MSN))
2550     {
2551       jrecvsys->chapterf_has_partial = 1;
2552 
2553       if (idnum == NSYS_SM_CF_IDNUM_FR_LSN)
2554 	jrecvsys->chapterf_direction = 0;
2555       else
2556 	jrecvsys->chapterf_direction = 1;
2557 
2558       memset((p = jrecvsys->chapterf_partial), 0, NSYS_SM_CF_SIZE_PARTIAL);
2559 
2560       if (idnum == NSYS_SM_CF_IDNUM_FR_LSN)
2561 	{
2562 	  (*p) &= NSYS_SM_CF_EVEN_CLR;
2563 	  (*p) |= (ndata << 4);
2564 	}
2565       else
2566 	{
2567 	  p += (NSYS_SM_CF_SIZE_PARTIAL - 1);
2568 	  (*p) &= NSYS_SM_CF_ODD_CLR;
2569 	  (*p) |= (ndata & NSYS_SM_CF_PAYLOAD_MASK);
2570 	}
2571       return;
2572     }
2573 
2574   /* handle "wrong direction guess" for an earlier unexpected QF command */
2575 
2576   if (!direction && (((point - 1) & NSYS_SM_CF_POINT_MASK) == idnum))
2577     {
2578       jrecvsys->chapterf_direction = 1;
2579       return;
2580     }
2581 
2582   /* handle unexpected QF commands */
2583 
2584   jrecvsys->chapterf_has_partial = jrecvsys->chapterf_direction = 0;
2585 }
2586 
2587 
2588 /****************************************************************/
2589 /*          process System Chapter X (System Exclusive)         */
2590 /*  (does not process unfinished command logs and other items)  */
2591 /****************************************************************/
2592 
nsys_netin_jrec_sysex(nsys_source * sptr,unsigned char * ps,int syslen,nsys_netout_jrecv_system_state * jrecvsys,unsigned char * buff,long * fill,long size)2593 int nsys_netin_jrec_sysex(nsys_source * sptr, unsigned char * ps,
2594 			  int syslen,
2595 			  nsys_netout_jrecv_system_state * jrecvsys,
2596 			  unsigned char * buff,
2597 			  long * fill, long size)
2598 
2599 {
2600   int sysex_len;
2601   unsigned char sysex_hdr;
2602   unsigned char gmreset_state, mvolume_lsb_state, mvolume_msb_state;
2603   unsigned char gmreset_has_tcount, gmreset_tcount;
2604   unsigned char sysex_has_tcount, sysex_tcount;
2605   unsigned char sysex_has_first, sysex_first;
2606   unsigned char sysexbuff[NSYS_SM_CX_SIZE_MAXLOG - 1];
2607 
2608   gmreset_state = gmreset_tcount = gmreset_has_tcount = 0;
2609   mvolume_lsb_state = mvolume_msb_state = 0;
2610 
2611   /* parse each log in list */
2612 
2613   do
2614     {
2615       sysex_has_tcount = sysex_has_first = sysex_first = 0;
2616 
2617       /* parse log header */
2618 
2619       if ((syslen -= NSYS_SM_CX_SIZE_HDR) < 0)
2620 	return NSYS_JOURNAL_CORRUPTED;
2621 
2622       if ((sysex_hdr = *(ps++)) & NSYS_SM_CX_HDR_CHKT)
2623 	{
2624 	  if ((syslen -= NSYS_SM_CX_SIZE_TCOUNT) < 0)
2625 	    return NSYS_JOURNAL_CORRUPTED;
2626 	  sysex_has_tcount = 1;
2627 	  sysex_tcount = ps[0];
2628 	  ps += NSYS_SM_CX_SIZE_TCOUNT;
2629 	}
2630 
2631       if (sysex_hdr & NSYS_SM_CX_HDR_CHKC)
2632 	{
2633 	  if ((syslen -= NSYS_SM_CX_SIZE_COUNT) < 0)
2634 	    return NSYS_JOURNAL_CORRUPTED;
2635 	  ps += NSYS_SM_CX_SIZE_COUNT;
2636 	}
2637 
2638       if (sysex_hdr & NSYS_SM_CX_HDR_CHKF)
2639 	{
2640 	  if ((--syslen) >= 0)
2641 	    sysex_first = NSYS_SM_CX_DATA_MASK & ps[0];
2642 	  else
2643 	    return NSYS_JOURNAL_CORRUPTED;
2644 
2645 	  while (NSYS_SM_CX_DATA_CHKEND & ps[0])
2646 	    if ((--syslen) >= 0)
2647 	      sysex_first = ((sysex_first << 7) +
2648 			     (NSYS_SM_CX_DATA_MASK & (++ps)[0]));
2649 	    else
2650 	      return NSYS_JOURNAL_CORRUPTED;
2651 
2652 	  sysex_has_first = 1;
2653 	  ps++;
2654 	}
2655 
2656       if ((!syslen) && (sysex_hdr & NSYS_SM_CX_HDR_CHKD))
2657 	return NSYS_JOURNAL_CORRUPTED;
2658 
2659       sysex_len = 0;
2660 
2661       if (sysex_hdr & NSYS_SM_CX_HDR_CHKD)
2662 	do
2663 	  {
2664 	    if (sysex_len < (NSYS_SM_CX_SIZE_MAXLOG - 1))
2665 	      sysexbuff[sysex_len++] = (*ps) & NSYS_SM_CX_DATA_CLREND;
2666 
2667 	    syslen--;
2668 
2669 	    if ((*(ps++)) & NSYS_SM_CX_DATA_CHKEND)
2670 	      break;
2671 
2672 	    if (!syslen)
2673 	      return NSYS_JOURNAL_CORRUPTED;
2674 
2675 	  } while (1);
2676 
2677       /* skip processing for unimplemented features, cancelled commands */
2678 
2679       if ((sysex_has_first && sysex_first) /* windowed data */ ||
2680 	  ((sysex_hdr & NSYS_SM_CX_STA_MASK) == NSYS_SM_CX_STA_UNFINISHED) ||
2681 	  ((sysex_hdr & NSYS_SM_CX_STA_MASK) == NSYS_SM_CX_STA_CANCELLED))
2682 	{
2683 	  if (syslen)
2684 	    continue;
2685 	  break;
2686 	}
2687 
2688       /* update GMRESET, MVOLUME state for log */
2689 
2690       if ((sysex_len == (NSYS_SM_CX_SIZE_GMRESET - 1)) &&
2691 	  (!memcmp(&(nsys_netout_sysconst_gmreset[1]), sysexbuff, 3)) &&
2692 	  ((sysexbuff[3] == NSYS_SM_CX_GMRESET_ONVAL) ||
2693 	   (sysexbuff[3] == NSYS_SM_CX_GMRESET_OFFVAL)))
2694 	{
2695 	  gmreset_state = sysexbuff[3] | NSYS_SM_RV_SETF;
2696 	  if (sysex_has_tcount)
2697 	    {
2698 	      gmreset_tcount = sysex_tcount;
2699 	      gmreset_has_tcount = 1;
2700 	    }
2701 	  else
2702 	    gmreset_has_tcount = 0;
2703 	}
2704 
2705       if ((sysex_len == NSYS_SM_CX_SIZE_MVOLUME - 1) &&
2706 	  !memcmp(&(nsys_netout_sysconst_mvolume[1]), sysexbuff, 4))
2707 	{
2708 	  mvolume_lsb_state = sysexbuff[4] | NSYS_SM_RV_SETF;
2709 	  mvolume_msb_state = sysexbuff[5];
2710 	}
2711 
2712     } while (syslen);
2713 
2714   /* do MVOLUME repairs */
2715 
2716   if (mvolume_lsb_state &&
2717       ((mvolume_lsb_state != jrecvsys->chapterx_mvolume_lsb) ||
2718        (mvolume_msb_state != jrecvsys->chapterx_mvolume_msb)))
2719     {
2720       if (nsys_netin_journal_addcmd_three
2721 	  (sptr, buff, fill, size, CSYS_MIDI_MVOLUME,
2722 	   mvolume_lsb_state & NSYS_SM_RV_CLRF, mvolume_msb_state))
2723 	return NSYS_JOURNAL_FILLEDBUFF;
2724 
2725       if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2726 	printf("MVOLUME (%hhu, %hhu) --> (%hhu, %hhu)\n",
2727 	       jrecvsys->chapterx_mvolume_lsb & NSYS_SM_RV_CLRF,
2728 	       jrecvsys->chapterx_mvolume_msb,
2729 	       mvolume_lsb_state & NSYS_SM_RV_CLRF, mvolume_msb_state);
2730 
2731       jrecvsys->chapterx_mvolume_lsb = mvolume_lsb_state;
2732       jrecvsys->chapterx_mvolume_msb = mvolume_msb_state;
2733     }
2734 
2735   /* do GMRESET repairs */
2736 
2737   do {
2738 
2739     if (jrecvsys->chapterx_gmreset == gmreset_state)
2740       {
2741 	if (!gmreset_has_tcount)
2742 	  break;
2743 
2744 	if (gmreset_state == (NSYS_SM_RV_SETF | NSYS_SM_CX_GMRESET_ONVAL))
2745 	  {
2746 	    if (jrecvsys->chapterx_gmreset_on_count == gmreset_state)
2747 	      break;
2748 	  }
2749 	else
2750 	  if (jrecvsys->chapterx_gmreset_off_count == gmreset_state)
2751 	    break;
2752       }
2753     else
2754       jrecvsys->chapterx_gmreset = gmreset_state;
2755 
2756     if (gmreset_has_tcount)
2757       {
2758 	if (gmreset_state == (NSYS_SM_RV_SETF | NSYS_SM_CX_GMRESET_ONVAL))
2759 	  {
2760 	    if (jrecvsys->chapterx_gmreset_on_count != gmreset_state)
2761 	      jrecvsys->chapterx_gmreset_on_count = gmreset_state;
2762 	  }
2763 	else
2764 	  if (jrecvsys->chapterx_gmreset_off_count != gmreset_state)
2765 	    jrecvsys->chapterx_gmreset_off_count = gmreset_state;
2766       }
2767 
2768     if (nsys_netin_journal_addcmd_two(sptr, buff, fill, size,
2769 				      CSYS_MIDI_GMRESET,
2770 				      gmreset_state & NSYS_SM_RV_CLRF))
2771       return NSYS_JOURNAL_FILLEDBUFF;
2772 
2773     if (NSYS_JOURNAL_DEBUG == NSYS_JOURNAL_DEBUG_ON)
2774       printf("GMRESET %s \n",
2775 	     (gmreset_state == (NSYS_SM_RV_SETF | NSYS_SM_CX_GMRESET_ONVAL))
2776 	     ? "On" : "Off");
2777 
2778     nsys_netin_journal_clear_active(CSYS_MIDI_GMRESET);
2779 
2780   }
2781   while (0);
2782 
2783   return NSYS_JOURNAL_RECOVERED;
2784 }
2785 
2786 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2787 /*                  low-level journal functions                 */
2788 /*______________________________________________________________*/
2789 
2790 /****************************************************************/
2791 /*           adds a 3-octet MIDI command to the buffer          */
2792 /****************************************************************/
2793 
nsys_netin_journal_addcmd_three(nsys_source * sptr,unsigned char * buff,long * fill,long size,unsigned char cmd,unsigned char ndata,unsigned char vdata)2794 int nsys_netin_journal_addcmd_three(nsys_source * sptr, unsigned char * buff,
2795 				    long * fill, long size,
2796 				    unsigned char cmd, unsigned char ndata,
2797 				    unsigned char vdata)
2798 
2799 {
2800   long idx;
2801 
2802   if ((size - (*fill)) < 4)           /* 3 octets + mset */
2803     return NSYS_JOURNAL_FILLEDBUFF;
2804 
2805   idx = *fill;
2806 
2807   buff[idx++] = cmd;
2808   buff[idx++] = ndata;
2809   buff[idx++] = vdata;
2810   buff[idx++] = (unsigned char)(sptr->mset);
2811 
2812   *fill = idx;
2813 
2814   return NSYS_JOURNAL_RECOVERED;
2815 }
2816 
2817 /****************************************************************/
2818 /*           adds a 2-octet MIDI command to the buffer          */
2819 /****************************************************************/
2820 
nsys_netin_journal_addcmd_two(nsys_source * sptr,unsigned char * buff,long * fill,long size,unsigned char cmd,unsigned char ndata)2821 int nsys_netin_journal_addcmd_two(nsys_source * sptr, unsigned char * buff,
2822 				    long * fill, long size,
2823 				    unsigned char cmd, unsigned char ndata)
2824 
2825 {
2826   long idx;
2827 
2828   if ((size - (*fill)) < 3)           /* 2 octets + mset */
2829     return NSYS_JOURNAL_FILLEDBUFF;
2830 
2831   idx = *fill;
2832 
2833   buff[idx++] = cmd;
2834   buff[idx++] = ndata;
2835   buff[idx++] = (unsigned char)(sptr->mset);
2836 
2837   *fill = idx;
2838 
2839   return NSYS_JOURNAL_RECOVERED;
2840 }
2841 
2842 /****************************************************************/
2843 /*           adds a 1-octet MIDI command to the buffer          */
2844 /****************************************************************/
2845 
nsys_netin_journal_addcmd_one(nsys_source * sptr,unsigned char * buff,long * fill,long size,unsigned char cmd)2846 int nsys_netin_journal_addcmd_one(nsys_source * sptr, unsigned char * buff,
2847 				  long * fill, long size, unsigned char cmd)
2848 
2849 {
2850   long idx;
2851 
2852   if ((size - (*fill)) < 2)           /* 1 octet + mset */
2853     return NSYS_JOURNAL_FILLEDBUFF;
2854 
2855   idx = *fill;
2856 
2857   buff[idx++] = cmd;
2858   buff[idx++] = (unsigned char)(sptr->mset);
2859 
2860   *fill = idx;
2861 
2862   return NSYS_JOURNAL_RECOVERED;
2863 }
2864 
2865 /****************************************************************/
2866 /*           adds a parameter transaction to the buffer         */
2867 /****************************************************************/
2868 
nsys_netin_journal_trans(nsys_source * sptr,unsigned char * buff,long * fill,long size,unsigned char chan,int flags,unsigned char msb_num,unsigned char lsb_num,unsigned char msb_val,unsigned char lsb_val)2869 int nsys_netin_journal_trans(nsys_source * sptr, unsigned char * buff,
2870 			     long * fill, long size, unsigned char chan,
2871 			     int flags, unsigned char msb_num,
2872 			     unsigned char lsb_num, unsigned char msb_val,
2873 			     unsigned char lsb_val)
2874 
2875 {
2876   unsigned char msb_cmd, lsb_cmd;
2877 
2878   msb_cmd = ((flags & NSYS_SM_CM_TRANS_RPN) ? CSYS_MIDI_CC_RPN_MSB :
2879 	     CSYS_MIDI_CC_NRPN_MSB);
2880   lsb_cmd = ((flags & NSYS_SM_CM_TRANS_RPN) ? CSYS_MIDI_CC_RPN_LSB :
2881 	     CSYS_MIDI_CC_NRPN_LSB);
2882 
2883   if (!(flags & NSYS_SM_CM_TRANS_NO_OPEN))
2884     {
2885       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2886 				    chan | CSYS_MIDI_CC, msb_cmd, msb_num))
2887 	return NSYS_JOURNAL_FILLEDBUFF;
2888 
2889       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2890 				    chan | CSYS_MIDI_CC, lsb_cmd, lsb_num))
2891 	return NSYS_JOURNAL_FILLEDBUFF;
2892     }
2893 
2894   if (!(flags & NSYS_SM_CM_TRANS_NO_SET))
2895     {
2896       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2897 				    CSYS_MIDI_CC_DATAENTRY_MSB, msb_val))
2898 	return NSYS_JOURNAL_FILLEDBUFF;
2899 
2900       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2901 				    CSYS_MIDI_CC_DATAENTRY_LSB, lsb_val))
2902 	return NSYS_JOURNAL_FILLEDBUFF;
2903     }
2904 
2905   if (!(flags & NSYS_SM_CM_TRANS_NO_CLOSE))
2906     {
2907       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2908 				    msb_cmd, CSYS_MIDI_RPN_NULL_MSB))
2909 	return NSYS_JOURNAL_FILLEDBUFF;
2910 
2911       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2912 				    lsb_cmd, CSYS_MIDI_RPN_NULL_LSB))
2913 	return NSYS_JOURNAL_FILLEDBUFF;
2914     }
2915 
2916   return NSYS_JOURNAL_RECOVERED;
2917 }
2918 /*************************************************************/
2919 /*           adds a button transaction to the buffer         */
2920 /*************************************************************/
2921 
nsys_netin_journal_button_trans(nsys_source * sptr,unsigned char * buff,long * fill,long size,unsigned char chan,int flags,unsigned char msb_num,unsigned char lsb_num,short count)2922 int nsys_netin_journal_button_trans(nsys_source * sptr, unsigned char * buff,
2923 				    long * fill, long size,
2924 				    unsigned char chan, int flags,
2925 				    unsigned char msb_num,
2926 				    unsigned char lsb_num, short count)
2927 
2928 {
2929   unsigned char msb_cmd, lsb_cmd, minus;
2930 
2931   if ((minus = (count < 0)))
2932     count = - count;
2933 
2934   msb_cmd = ((flags & NSYS_SM_CM_TRANS_RPN) ? CSYS_MIDI_CC_RPN_MSB :
2935 	     CSYS_MIDI_CC_NRPN_MSB);
2936   lsb_cmd = ((flags & NSYS_SM_CM_TRANS_RPN) ? CSYS_MIDI_CC_RPN_LSB :
2937 	     CSYS_MIDI_CC_NRPN_LSB);
2938 
2939   if (!(flags & NSYS_SM_CM_TRANS_NO_OPEN))
2940     {
2941       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2942 					  chan | CSYS_MIDI_CC, msb_cmd, msb_num))
2943 	return NSYS_JOURNAL_FILLEDBUFF;
2944 
2945       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size,
2946 					  chan | CSYS_MIDI_CC, lsb_cmd, lsb_num))
2947 	return NSYS_JOURNAL_FILLEDBUFF;
2948     }
2949 
2950   if (!(flags & NSYS_SM_CM_TRANS_NO_SET))
2951     {
2952       while (count--)
2953 	if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2954 					    minus ? CSYS_MIDI_CC_DATAENTRYMINUS :
2955 					    CSYS_MIDI_CC_DATAENTRYPLUS, 0))
2956 	  return NSYS_JOURNAL_FILLEDBUFF;
2957     }
2958 
2959   if (!(flags & NSYS_SM_CM_TRANS_NO_CLOSE))
2960     {
2961       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2962 					  msb_cmd, CSYS_MIDI_RPN_NULL_MSB))
2963 	return NSYS_JOURNAL_FILLEDBUFF;
2964 
2965       if (nsys_netin_journal_addcmd_three(sptr, buff, fill, size, chan | CSYS_MIDI_CC,
2966 					  lsb_cmd, CSYS_MIDI_RPN_NULL_LSB))
2967 	return NSYS_JOURNAL_FILLEDBUFF;
2968     }
2969 
2970   return NSYS_JOURNAL_RECOVERED;
2971 }
2972 
2973 /****************************************************************/
2974 /*            sender state:  clear all active state             */
2975 /****************************************************************/
2976 
nsys_netin_journal_clear_active(unsigned char cmd)2977 void nsys_netin_journal_clear_active(unsigned char cmd)
2978 
2979 {
2980   /* to do
2981    *
2982    * cmd codes CSYS_MIDI_SYSTEM_RESET or CSYS_MIDI_GMRESET
2983    *
2984    * clear journal state defined as "active"
2985    *
2986    */
2987 }
2988 
2989 /* end Network library -- receiver journal functions */
2990 
2991