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