1 module pxtone.evelist; 2 3 import pxtone.descriptor; 4 import pxtone.error; 5 import pxtone.util; 6 7 /////////////////////// 8 // global 9 /////////////////////// 10 11 bool Evelist_Kind_IsTail(int kind) nothrow @safe { 12 if (kind == EVENTKIND.ON || kind == EVENTKIND.PORTAMENT) { 13 return true; 14 } 15 return false; 16 } 17 18 enum EVENTKIND { 19 NULL = 0, // 0 20 21 ON, // 1 22 KEY, // 2 23 PAN_VOLUME, // 3 24 VELOCITY, // 4 25 VOLUME, // 5 26 PORTAMENT, // 6 27 BEATCLOCK, // 7 28 BEATTEMPO, // 8 29 BEATNUM, // 9 30 REPEAT, // 10 31 LAST, // 11 32 VOICENO, // 12 33 GROUPNO, // 13 34 TUNING, // 14 35 PAN_TIME, // 15 36 37 NUM, // 16 38 } 39 40 enum EVENTDEFAULT_VOLUME = 104; 41 enum EVENTDEFAULT_VELOCITY = 104; 42 enum EVENTDEFAULT_PAN_VOLUME = 64; 43 enum EVENTDEFAULT_PAN_TIME = 64; 44 enum EVENTDEFAULT_PORTAMENT = 0; 45 enum EVENTDEFAULT_VOICENO = 0; 46 enum EVENTDEFAULT_GROUPNO = 0; 47 enum EVENTDEFAULT_KEY = 0x6000; 48 enum EVENTDEFAULT_BASICKEY = 0x4500; // 4A(440Hz?) 49 enum EVENTDEFAULT_TUNING = 1.0f; 50 51 enum EVENTDEFAULT_BEATNUM = 4; 52 enum EVENTDEFAULT_BEATTEMPO = 120; 53 enum EVENTDEFAULT_BEATCLOCK = 480; 54 55 struct EVERECORD { 56 ubyte kind; 57 ubyte unit_no; 58 ubyte reserve1; 59 ubyte reserve2; 60 int value; 61 int clock; 62 EVERECORD* prev; 63 EVERECORD* next; 64 } 65 66 int _DefaultKindValue(ubyte kind) nothrow @safe { 67 switch (kind) { 68 // case EVENTKIND.ON : return ; 69 case EVENTKIND.KEY: 70 return EVENTDEFAULT_KEY; 71 case EVENTKIND.PAN_VOLUME: 72 return EVENTDEFAULT_PAN_VOLUME; 73 case EVENTKIND.VELOCITY: 74 return EVENTDEFAULT_VELOCITY; 75 case EVENTKIND.VOLUME: 76 return EVENTDEFAULT_VOLUME; 77 case EVENTKIND.PORTAMENT: 78 return EVENTDEFAULT_PORTAMENT; 79 case EVENTKIND.BEATCLOCK: 80 return EVENTDEFAULT_BEATCLOCK; 81 case EVENTKIND.BEATTEMPO: 82 return EVENTDEFAULT_BEATTEMPO; 83 case EVENTKIND.BEATNUM: 84 return EVENTDEFAULT_BEATNUM; 85 // case EVENTKIND.REPEAT : return ; 86 // case EVENTKIND.LAST : return ; 87 case EVENTKIND.VOICENO: 88 return EVENTDEFAULT_VOICENO; 89 case EVENTKIND.GROUPNO: 90 return EVENTDEFAULT_GROUPNO; 91 case EVENTKIND.TUNING: 92 return reinterpretFloat(EVENTDEFAULT_TUNING); 93 case EVENTKIND.PAN_TIME: 94 return EVENTDEFAULT_PAN_TIME; 95 default: 96 break; 97 } 98 return 0; 99 } 100 101 int _ComparePriority(ubyte kind1, ubyte kind2) nothrow @safe { 102 static immutable int[EVENTKIND.NUM] priority_table = [0, // EVENTKIND.NULL = 0 103 50, // EVENTKIND.ON 104 40, // EVENTKIND.KEY 105 60, // EVENTKIND.PAN_VOLUME 106 70, // EVENTKIND.VELOCITY 107 80, // EVENTKIND.VOLUME 108 30, // EVENTKIND.PORTAMENT 109 0, // EVENTKIND.BEATCLOCK 110 0, // EVENTKIND.BEATTEMPO 111 0, // EVENTKIND.BEATNUM 112 0, // EVENTKIND.REPEAT 113 255, // EVENTKIND.LAST 114 10, // EVENTKIND.VOICENO 115 20, // EVENTKIND.GROUPNO 116 90, // EVENTKIND.TUNING 117 100, // EVENTKIND.PAN_TIME 118 ]; 119 120 return priority_table[kind1] - priority_table[kind2]; 121 } 122 123 // event struct(12byte) ================= 124 struct _x4x_EVENTSTRUCT { 125 ushort unit_index; 126 ushort event_kind; 127 ushort data_num; // 1イベントのデータ数。現在は 2 ( clock / volume ) 128 ushort rrr; 129 uint event_num; 130 } 131 132 //-------------------------------- 133 134 struct pxtnEvelist { 135 136 private: 137 138 int _eve_allocated_num; 139 EVERECORD[] _eves; 140 EVERECORD* _start; 141 int _linear; 142 143 EVERECORD* _p_x4x_rec; 144 145 void _rec_set(EVERECORD* p_rec, EVERECORD* prev, EVERECORD* next, int clock, ubyte unit_no, ubyte kind, int value) nothrow @safe { 146 if (prev) { 147 prev.next = p_rec; 148 } else { 149 _start = p_rec; 150 } 151 if (next) { 152 next.prev = p_rec; 153 } 154 155 p_rec.next = next; 156 p_rec.prev = prev; 157 p_rec.clock = clock; 158 p_rec.kind = kind; 159 p_rec.unit_no = unit_no; 160 p_rec.value = value; 161 } 162 163 void _rec_cut(EVERECORD* p_rec) nothrow @safe { 164 if (p_rec.prev) { 165 p_rec.prev.next = p_rec.next; 166 } else { 167 _start = p_rec.next; 168 } 169 if (p_rec.next) { 170 p_rec.next.prev = p_rec.prev; 171 } 172 p_rec.kind = EVENTKIND.NULL; 173 } 174 175 public: 176 177 void Release() nothrow @system { 178 _eves = null; 179 _start = null; 180 _eve_allocated_num = 0; 181 } 182 183 void Clear() nothrow @system { 184 if (_eves) { 185 _eves[0 .. _eve_allocated_num] = EVERECORD.init; 186 } 187 _start = null; 188 } 189 190 ~this() nothrow @system { 191 Release(); 192 } 193 194 void Allocate(int max_event_num) @system { 195 Release(); 196 _eves = new EVERECORD[](max_event_num); 197 if (!(_eves)) { 198 throw new PxtoneException("Unable to allocate memory"); 199 } 200 _eves[0 .. max_event_num] = EVERECORD.init; 201 _eve_allocated_num = max_event_num; 202 } 203 204 int get_Num_Max() const nothrow @safe { 205 if (!_eves) { 206 return 0; 207 } 208 return _eve_allocated_num; 209 } 210 211 int get_Max_Clock() const nothrow @safe { 212 int max_clock = 0; 213 int clock; 214 215 for (const(EVERECORD)* p = _start; p; p = p.next) { 216 if (Evelist_Kind_IsTail(p.kind)) { 217 clock = p.clock + p.value; 218 } else { 219 clock = p.clock; 220 } 221 if (clock > max_clock) { 222 max_clock = clock; 223 } 224 } 225 226 return max_clock; 227 228 } 229 230 int get_Count() const nothrow @safe { 231 if (!_eves || !_start) { 232 return 0; 233 } 234 235 int count = 0; 236 for (const(EVERECORD)* p = _start; p; p = p.next) { 237 count++; 238 } 239 return count; 240 } 241 242 int get_Count(ubyte kind, int value) const nothrow @safe { 243 if (!_eves) { 244 return 0; 245 } 246 247 int count = 0; 248 for (const(EVERECORD)* p = _start; p; p = p.next) { 249 if (p.kind == kind && p.value == value) { 250 count++; 251 } 252 } 253 return count; 254 } 255 256 int get_Count(ubyte unit_no) const nothrow @safe { 257 if (!_eves) { 258 return 0; 259 } 260 261 int count = 0; 262 for (const(EVERECORD)* p = _start; p; p = p.next) { 263 if (p.unit_no == unit_no) { 264 count++; 265 } 266 } 267 return count; 268 } 269 270 int get_Count(ubyte unit_no, ubyte kind) const nothrow @safe { 271 if (!_eves) { 272 return 0; 273 } 274 275 int count = 0; 276 for (const(EVERECORD)* p = _start; p; p = p.next) { 277 if (p.unit_no == unit_no && p.kind == kind) { 278 count++; 279 } 280 } 281 return count; 282 } 283 284 int get_Count(int clock1, int clock2, ubyte unit_no) const nothrow @safe { 285 if (!_eves) { 286 return 0; 287 } 288 289 const(EVERECORD)* p; 290 for (p = _start; p; p = p.next) { 291 if (p.unit_no == unit_no) { 292 if (p.clock >= clock1) { 293 break; 294 } 295 if (Evelist_Kind_IsTail(p.kind) && p.clock + p.value > clock1) { 296 break; 297 } 298 } 299 } 300 301 int count = 0; 302 for (; p; p = p.next) { 303 if (p.clock != clock1 && p.clock >= clock2) { 304 break; 305 } 306 if (p.unit_no == unit_no) { 307 count++; 308 } 309 } 310 return count; 311 } 312 313 int get_Value(int clock, ubyte unit_no, ubyte kind) const nothrow @system { 314 if (!_eves) { 315 return 0; 316 } 317 318 const(EVERECORD)* p; 319 int val = _DefaultKindValue(kind); 320 321 for (p = _start; p; p = p.next) { 322 if (p.clock > clock) { 323 break; 324 } 325 if (p.unit_no == unit_no && p.kind == kind) { 326 val = p.value; 327 } 328 } 329 330 return val; 331 } 332 333 const(EVERECORD)* get_Records() const nothrow @safe { 334 if (!_eves) { 335 return null; 336 } 337 return _start; 338 } 339 340 bool Record_Add_i(int clock, ubyte unit_no, ubyte kind, int value) nothrow @system { 341 if (!_eves) { 342 return false; 343 } 344 345 EVERECORD* p_new = null; 346 EVERECORD* p_prev = null; 347 EVERECORD* p_next = null; 348 349 // 空き検索 350 for (int r = 0; r < _eve_allocated_num; r++) { 351 if (_eves[r].kind == EVENTKIND.NULL) { 352 p_new = &_eves[r]; 353 break; 354 } 355 } 356 if (!p_new) { 357 return false; 358 } 359 360 // first. 361 if (!_start) { 362 } // top. 363 else if (clock < _start.clock) { 364 p_next = _start; 365 } else { 366 367 for (EVERECORD* p = _start; p; p = p.next) { 368 // 同時 369 if (p.clock == clock) { 370 for (; true; p = p.next) { 371 if (p.clock != clock) { 372 p_prev = p.prev; 373 p_next = p; 374 break; 375 } 376 if (unit_no == p.unit_no && kind == p.kind) { 377 p_prev = p.prev; 378 p_next = p.next; 379 p.kind = EVENTKIND.NULL; 380 break; 381 } // 置き換え 382 if (_ComparePriority(kind, p.kind) < 0) { 383 p_prev = p.prev; 384 p_next = p; 385 break; 386 } // プライオリティを検査 387 if (!p.next) { 388 p_prev = p; 389 break; 390 } // 末端 391 } 392 break; 393 } else if (p.clock > clock) { 394 p_prev = p.prev; 395 p_next = p; 396 break; 397 } // 追い越した 398 else if (!p.next) { 399 p_prev = p; 400 break; 401 } // 末端 402 } 403 } 404 405 _rec_set(p_new, p_prev, p_next, clock, unit_no, kind, value); 406 407 // cut prev tail 408 if (Evelist_Kind_IsTail(kind)) { 409 for (EVERECORD* p = p_new.prev; p; p = p.prev) { 410 if (p.unit_no == unit_no && p.kind == kind) { 411 if (clock < p.clock + p.value) { 412 p.value = clock - p.clock; 413 } 414 break; 415 } 416 } 417 } 418 419 // delete next 420 if (Evelist_Kind_IsTail(kind)) { 421 for (EVERECORD* p = p_new.next; p && p.clock < clock + value; p = p.next) { 422 if (p.unit_no == unit_no && p.kind == kind) { 423 _rec_cut(p); 424 } 425 } 426 } 427 428 return true; 429 } 430 431 bool Record_Add_f(int clock, ubyte unit_no, ubyte kind, float value_f) nothrow @system { 432 int value = *(cast(int*)(&value_f)); 433 return Record_Add_i(clock, unit_no, kind, value); 434 } 435 436 ///////////////////// 437 // linear 438 ///////////////////// 439 440 bool Linear_Start() nothrow @system { 441 if (!_eves) { 442 return false; 443 } 444 Clear(); 445 _linear = 0; 446 return true; 447 } 448 449 void Linear_Add_i(int clock, ubyte unit_no, ubyte kind, int value) nothrow @system { 450 EVERECORD* p = &_eves[_linear]; 451 452 p.clock = clock; 453 p.unit_no = unit_no; 454 p.kind = kind; 455 p.value = value; 456 457 _linear++; 458 } 459 460 void Linear_Add_f(int clock, ubyte unit_no, ubyte kind, float value_f) nothrow @system { 461 int value = *(cast(int*)(&value_f)); 462 Linear_Add_i(clock, unit_no, kind, value); 463 } 464 465 void Linear_End(bool b_connect) nothrow @system { 466 if (_eves[0].kind != EVENTKIND.NULL) { 467 _start = &_eves[0]; 468 } 469 470 if (b_connect) { 471 for (int r = 1; r < _eve_allocated_num; r++) { 472 if (_eves[r].kind == EVENTKIND.NULL) { 473 break; 474 } 475 _eves[r].prev = &_eves[r - 1]; 476 _eves[r - 1].next = &_eves[r]; 477 } 478 } 479 } 480 481 int Record_Clock_Shift(int clock, int shift, ubyte unit_no) nothrow @system // can't be under 0. 482 { 483 if (!_eves) { 484 return 0; 485 } 486 if (!_start) { 487 return 0; 488 } 489 if (!shift) { 490 return 0; 491 } 492 493 int count = 0; 494 int c; 495 ubyte k; 496 int v; 497 EVERECORD* p_next; 498 EVERECORD* p_prev; 499 EVERECORD* p = _start; 500 501 if (shift < 0) { 502 for (; p; p = p.next) { 503 if (p.clock >= clock) { 504 break; 505 } 506 } 507 while (p) { 508 if (p.unit_no == unit_no) { 509 c = p.clock + shift; 510 k = p.kind; 511 v = p.value; 512 p_next = p.next; 513 514 _rec_cut(p); 515 if (c >= 0) { 516 Record_Add_i(c, unit_no, k, v); 517 } 518 count++; 519 520 p = p_next; 521 } else { 522 p = p.next; 523 } 524 } 525 } else if (shift > 0) { 526 while (p.next) { 527 p = p.next; 528 } 529 while (p) { 530 if (p.clock < clock) { 531 break; 532 } 533 534 if (p.unit_no == unit_no) { 535 c = p.clock + shift; 536 k = p.kind; 537 v = p.value; 538 p_prev = p.prev; 539 540 _rec_cut(p); 541 Record_Add_i(c, unit_no, k, v); 542 count++; 543 544 p = p_prev; 545 } else { 546 p = p.prev; 547 } 548 } 549 } 550 return count; 551 } 552 553 int Record_Value_Set(int clock1, int clock2, ubyte unit_no, ubyte kind, int value) nothrow @safe { 554 if (!_eves) { 555 return 0; 556 } 557 558 int count = 0; 559 560 for (EVERECORD* p = _start; p; p = p.next) { 561 if (p.unit_no == unit_no && p.kind == kind && p.clock >= clock1 && p.clock < clock2) { 562 p.value = value; 563 count++; 564 } 565 } 566 567 return count; 568 } 569 570 int Record_Value_Change(int clock1, int clock2, ubyte unit_no, ubyte kind, int value) nothrow @safe { 571 if (!_eves) { 572 return 0; 573 } 574 575 int count = 0; 576 577 int max, min; 578 579 switch (kind) { 580 case EVENTKIND.NULL: 581 max = 0; 582 min = 0; 583 break; 584 case EVENTKIND.ON: 585 max = 120; 586 min = 120; 587 break; 588 case EVENTKIND.KEY: 589 max = 0xbfff; 590 min = 0; 591 break; 592 case EVENTKIND.PAN_VOLUME: 593 max = 0x80; 594 min = 0; 595 break; 596 case EVENTKIND.PAN_TIME: 597 max = 0x80; 598 min = 0; 599 break; 600 case EVENTKIND.VELOCITY: 601 max = 0x80; 602 min = 0; 603 break; 604 case EVENTKIND.VOLUME: 605 max = 0x80; 606 min = 0; 607 break; 608 default: 609 max = 0; 610 min = 0; 611 } 612 613 for (EVERECORD* p = _start; p; p = p.next) { 614 if (p.unit_no == unit_no && p.kind == kind && p.clock >= clock1) { 615 if (clock2 == -1 || p.clock < clock2) { 616 p.value += value; 617 if (p.value < min) { 618 p.value = min; 619 } 620 if (p.value > max) { 621 p.value = max; 622 } 623 count++; 624 } 625 } 626 } 627 628 return count; 629 } 630 631 int Record_Value_Omit(ubyte kind, int value) nothrow @safe { 632 if (!_eves) { 633 return 0; 634 } 635 636 int count = 0; 637 638 for (EVERECORD* p = _start; p; p = p.next) { 639 if (p.kind == kind) { 640 if (p.value == value) { 641 _rec_cut(p); 642 count++; 643 } else if (p.value > value) { 644 p.value--; 645 count++; 646 } 647 } 648 } 649 return count; 650 } 651 652 int Record_Value_Replace(ubyte kind, int old_value, int new_value) nothrow @safe { 653 if (!_eves) { 654 return 0; 655 } 656 657 int count = 0; 658 659 if (old_value == new_value) { 660 return 0; 661 } 662 if (old_value < new_value) { 663 for (EVERECORD* p = _start; p; p = p.next) { 664 if (p.kind == kind) { 665 if (p.value == old_value) { 666 p.value = new_value; 667 count++; 668 } else if (p.value > old_value && p.value <= new_value) { 669 p.value--; 670 count++; 671 } 672 } 673 } 674 } else { 675 for (EVERECORD* p = _start; p; p = p.next) { 676 if (p.kind == kind) { 677 if (p.value == old_value) { 678 p.value = new_value; 679 count++; 680 } else if (p.value < old_value && p.value >= new_value) { 681 p.value++; 682 count++; 683 } 684 } 685 } 686 } 687 688 return count; 689 } 690 691 int Record_Delete(int clock1, int clock2, ubyte unit_no, ubyte kind) nothrow @safe { 692 if (!_eves) { 693 return 0; 694 } 695 696 int count = 0; 697 698 for (EVERECORD* p = _start; p; p = p.next) { 699 if (p.clock != clock1 && p.clock >= clock2) { 700 break; 701 } 702 if (p.clock >= clock1 && p.unit_no == unit_no && p.kind == kind) { 703 _rec_cut(p); 704 count++; 705 } 706 } 707 708 if (Evelist_Kind_IsTail(kind)) { 709 for (EVERECORD* p = _start; p; p = p.next) { 710 if (p.clock >= clock1) { 711 break; 712 } 713 if (p.unit_no == unit_no && p.kind == kind && p.clock + p.value > clock1) { 714 p.value = clock1 - p.clock; 715 count++; 716 } 717 } 718 } 719 720 return count; 721 } 722 723 int Record_Delete(int clock1, int clock2, ubyte unit_no) nothrow @safe { 724 if (!_eves) { 725 return 0; 726 } 727 728 int count = 0; 729 730 for (EVERECORD* p = _start; p; p = p.next) { 731 if (p.clock != clock1 && p.clock >= clock2) { 732 break; 733 } 734 if (p.clock >= clock1 && p.unit_no == unit_no) { 735 _rec_cut(p); 736 count++; 737 } 738 } 739 740 for (EVERECORD* p = _start; p; p = p.next) { 741 if (p.clock >= clock1) { 742 break; 743 } 744 if (p.unit_no == unit_no && Evelist_Kind_IsTail(p.kind) && p.clock + p.value > clock1) { 745 p.value = clock1 - p.clock; 746 count++; 747 } 748 } 749 750 return count; 751 } 752 753 int Record_UnitNo_Miss(ubyte unit_no) nothrow @safe // delete event has the unit-no 754 { 755 if (!_eves) { 756 return 0; 757 } 758 759 int count = 0; 760 761 for (EVERECORD* p = _start; p; p = p.next) { 762 if (p.unit_no == unit_no) { 763 _rec_cut(p); 764 count++; 765 } else if (p.unit_no > unit_no) { 766 p.unit_no--; 767 count++; 768 } 769 } 770 return count; 771 } 772 773 int Record_UnitNo_Set(ubyte unit_no) nothrow @safe // set the unit-no 774 { 775 if (!_eves) { 776 return 0; 777 } 778 779 int count = 0; 780 for (EVERECORD* p = _start; p; p = p.next) { 781 p.unit_no = unit_no; 782 count++; 783 } 784 return count; 785 } 786 787 int Record_UnitNo_Replace(ubyte old_u, ubyte new_u) nothrow @safe // exchange unit 788 { 789 if (!_eves) { 790 return 0; 791 } 792 793 int count = 0; 794 795 if (old_u == new_u) { 796 return 0; 797 } 798 if (old_u < new_u) { 799 for (EVERECORD* p = _start; p; p = p.next) { 800 if (p.unit_no == old_u) { 801 p.unit_no = new_u; 802 count++; 803 } else if (p.unit_no > old_u && p.unit_no <= new_u) { 804 p.unit_no--; 805 count++; 806 } 807 } 808 } else { 809 for (EVERECORD* p = _start; p; p = p.next) { 810 if (p.unit_no == old_u) { 811 p.unit_no = new_u; 812 count++; 813 } else if (p.unit_no < old_u && p.unit_no >= new_u) { 814 p.unit_no++; 815 count++; 816 } 817 } 818 } 819 820 return count; 821 } 822 823 int BeatClockOperation(int rate) nothrow @safe { 824 if (!_eves) { 825 return 0; 826 } 827 828 int count = 0; 829 830 for (EVERECORD* p = _start; p; p = p.next) { 831 p.clock *= rate; 832 if (Evelist_Kind_IsTail(p.kind)) { 833 p.value *= rate; 834 } 835 count++; 836 } 837 838 return count; 839 } 840 841 // ------------ 842 // io 843 // ------------ 844 845 void io_Write(ref pxtnDescriptor p_doc, int rough) const @system { 846 int eve_num = get_Count(); 847 int ralatived_size = 0; 848 int absolute = 0; 849 int clock; 850 int value; 851 852 for (const(EVERECORD)* p = get_Records(); p; p = p.next) { 853 clock = p.clock - absolute; 854 855 ralatived_size += pxtnDescriptor_v_chk(p.clock); 856 ralatived_size += 1; 857 ralatived_size += 1; 858 ralatived_size += pxtnDescriptor_v_chk(p.value); 859 860 absolute = p.clock; 861 } 862 863 int size = cast(int)(int.sizeof + ralatived_size); 864 p_doc.w_asfile(size); 865 p_doc.w_asfile(eve_num); 866 867 absolute = 0; 868 869 for (const(EVERECORD)* p = get_Records(); p; p = p.next) { 870 clock = p.clock - absolute; 871 872 if (Evelist_Kind_IsTail(p.kind)) { 873 value = p.value / rough; 874 } else { 875 value = p.value; 876 } 877 878 p_doc.v_w_asfile(clock / rough); 879 p_doc.w_asfile(p.unit_no); 880 p_doc.w_asfile(p.kind); 881 p_doc.v_w_asfile(value); 882 883 absolute = p.clock; 884 } 885 } 886 887 void io_Read(ref pxtnDescriptor p_doc) @system { 888 int size = 0; 889 int eve_num = 0; 890 891 p_doc.r(size); 892 p_doc.r(eve_num); 893 894 int clock = 0; 895 int absolute = 0; 896 ubyte unit_no = 0; 897 ubyte kind = 0; 898 int value = 0; 899 900 for (int e = 0; e < eve_num; e++) { 901 p_doc.v_r(clock); 902 p_doc.r(unit_no); 903 p_doc.r(kind); 904 p_doc.v_r(value); 905 absolute += clock; 906 clock = absolute; 907 Linear_Add_i(clock, unit_no, kind, value); 908 } 909 } 910 911 int io_Read_EventNum(ref pxtnDescriptor p_doc) const @system { 912 int size = 0; 913 int eve_num = 0; 914 915 p_doc.r(size); 916 p_doc.r(eve_num); 917 918 int count = 0; 919 int clock = 0; 920 ubyte unit_no = 0; 921 ubyte kind = 0; 922 int value = 0; 923 924 for (int e = 0; e < eve_num; e++) { 925 p_doc.v_r(clock); 926 p_doc.r(unit_no); 927 p_doc.r(kind); 928 p_doc.v_r(value); 929 count++; 930 } 931 if (count != eve_num) { 932 return 0; 933 } 934 935 return eve_num; 936 } 937 938 bool x4x_Read_Start() nothrow @system { 939 if (!_eves) { 940 return false; 941 } 942 Clear(); 943 _linear = 0; 944 _p_x4x_rec = null; 945 return true; 946 } 947 948 void x4x_Read_NewKind() nothrow @safe { 949 _p_x4x_rec = null; 950 } 951 952 void x4x_Read_Add(int clock, ubyte unit_no, ubyte kind, int value) nothrow @system { 953 EVERECORD* p_new = null; 954 EVERECORD* p_prev = null; 955 EVERECORD* p_next = null; 956 957 p_new = &_eves[_linear++]; 958 959 // first. 960 if (!_start) { 961 } // top 962 else if (clock < _start.clock) { 963 p_next = _start; 964 } else { 965 EVERECORD* p; 966 967 if (_p_x4x_rec) { 968 p = _p_x4x_rec; 969 } else { 970 p = _start; 971 } 972 973 for (; p; p = p.next) { 974 // 同時 975 if (p.clock == clock) { 976 for (; true; p = p.next) { 977 if (p.clock != clock) { 978 p_prev = p.prev; 979 p_next = p; 980 break; 981 } 982 if (unit_no == p.unit_no && kind == p.kind) { 983 p_prev = p.prev; 984 p_next = p.next; 985 p.kind = EVENTKIND.NULL; 986 break; 987 } // 置き換え 988 if (_ComparePriority(kind, p.kind) < 0) { 989 p_prev = p.prev; 990 p_next = p; 991 break; 992 } // プライオリティを検査 993 if (!p.next) { 994 p_prev = p; 995 break; 996 } // 末端 997 } 998 break; 999 } else if (p.clock > clock) { 1000 p_prev = p.prev; 1001 p_next = p; 1002 break; 1003 } // 追い越した 1004 else if (!p.next) { 1005 p_prev = p; 1006 break; 1007 } // 末端 1008 } 1009 } 1010 _rec_set(p_new, p_prev, p_next, clock, unit_no, kind, value); 1011 1012 _p_x4x_rec = p_new; 1013 } 1014 1015 // write event. 1016 void io_Unit_Read_x4x_EVENT(ref pxtnDescriptor p_doc, bool bTailAbsolute, bool bCheckRRR) @system { 1017 _x4x_EVENTSTRUCT evnt; 1018 int clock = 0; 1019 int value = 0; 1020 int absolute = 0; 1021 int e = 0; 1022 int size = 0; 1023 1024 p_doc.r(size); 1025 p_doc.r(evnt); 1026 1027 if (evnt.data_num != 2) { 1028 throw new PxtoneException("fmt unknown"); 1029 } 1030 if (evnt.event_kind >= EVENTKIND.NUM) { 1031 throw new PxtoneException("fmt unknown"); 1032 } 1033 if (bCheckRRR && evnt.rrr) { 1034 throw new PxtoneException("fmt unknown"); 1035 } 1036 1037 absolute = 0; 1038 for (e = 0; e < cast(int) evnt.event_num; e++) { 1039 p_doc.v_r(clock); 1040 p_doc.v_r(value); 1041 absolute += clock; 1042 clock = absolute; 1043 x4x_Read_Add(clock, cast(ubyte) evnt.unit_index, cast(ubyte) evnt.event_kind, value); 1044 if (bTailAbsolute && Evelist_Kind_IsTail(evnt.event_kind)) { 1045 absolute += value; 1046 } 1047 } 1048 if (e != evnt.event_num) { 1049 throw new PxtoneException("desc broken"); 1050 } 1051 1052 x4x_Read_NewKind(); 1053 } 1054 1055 void io_Read_x4x_EventNum(ref pxtnDescriptor p_doc, int* p_num) const @system { 1056 if (!p_num) { 1057 throw new PxtoneException("param"); 1058 } 1059 1060 _x4x_EVENTSTRUCT evnt; 1061 int work = 0; 1062 int e = 0; 1063 int size = 0; 1064 1065 p_doc.r(size); 1066 p_doc.r(evnt); 1067 1068 // support only 2 1069 if (evnt.data_num != 2) { 1070 throw new PxtoneException("fmt unknown"); 1071 } 1072 1073 for (e = 0; e < cast(int) evnt.event_num; e++) { 1074 p_doc.v_r(work); 1075 p_doc.v_r(work); 1076 } 1077 if (e != evnt.event_num) { 1078 throw new PxtoneException("desc broken"); 1079 } 1080 1081 *p_num = evnt.event_num; 1082 } 1083 }