fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

pti/wav: Improve square wave output

+241 -190
+238 -176
src/drivers/pti/pti-img-wav.c
··· 5 5 /***************************************************************************** 6 6 * File name: src/drivers/pti/pti-img-wav.c * 7 7 * Created: 2020-04-25 by Hampa Hug <hampa@hampa.ch> * 8 - * Copyright: (C) 2020-2022 Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2020-2023 Hampa Hug <hampa@hampa.ch> * 9 9 *****************************************************************************/ 10 10 11 11 /***************************************************************************** ··· 69 69 const pti_img_t *img; 70 70 const pti_wav_param_t *par; 71 71 72 - unsigned long size; 72 + uint32_t size; 73 + uint32_t start_riff; 74 + uint32_t start_fmt; 75 + uint32_t start_data; 76 + uint32_t start_pcm; 73 77 74 - unsigned long start_riff; 75 - unsigned long start_fmt; 76 - unsigned long start_data; 77 - unsigned long start_pcm; 78 + int16_t smp0; 79 + int16_t smp1; 80 + 81 + unsigned long rem; 82 + 83 + long lp0_smp; 84 + 85 + double lp1_smp; 86 + double lp1_a; 87 + double lp1_b; 78 88 79 89 unsigned iir_cnt; 80 90 wav_iir2_t iir[8]; 81 - 82 - unsigned long rem; 83 91 } wav_save_t; 84 92 85 93 ··· 89 97 .srate = 48000, 90 98 .bits = 16, 91 99 .channels = 1, 92 - .lowpass = 0, 93 - .order = 4, 94 - .sine_wave = 1 100 + .lowpass = 8000, 101 + .order = 0, 95 102 }; 96 103 97 104 ··· 100 107 par->srate = 48000; 101 108 par->bits = 16; 102 109 par->channels = 1; 103 - par->lowpass = 0; 104 - par->order = 4; 105 - par->sine_wave = 1; 110 + par->lowpass = 8000; 111 + par->order = 0; 106 112 } 107 113 108 114 void pti_wav_set_default_clock (unsigned long val) ··· 137 143 void pti_wav_set_lowpass_order (unsigned val) 138 144 { 139 145 wav_default.order = val; 140 - } 141 - 142 - void pti_wav_set_sine_wave (int val) 143 - { 144 - wav_default.sine_wave = (val != 0); 145 - } 146 - 147 - 148 - static 149 - void wav_iir2_init (wav_iir2_t *iir) 150 - { 151 - unsigned i; 152 - 153 - for (i = 0; i < 3; i++) { 154 - iir->a[i] = 0.0; 155 - iir->b[i] = 0.0; 156 - iir->x[i] = 0.0; 157 - iir->y[i] = 0.0; 158 - } 159 - } 160 - 161 - static 162 - void wav_iir2_butterworth (wav_iir2_t *iir, unsigned k, unsigned N, double om) 163 - { 164 - double b0, c, f; 165 - 166 - wav_iir2_init (iir); 167 - 168 - c = 1.0 / tan (M_PI * om); 169 - f = 2.0 * c * cos (M_PI * (2.0 * k + 1.0) / (2.0 * N)); 170 - b0 = c * c + f + 1.0; 171 - 172 - iir->a[0] = 1.0 / b0; 173 - iir->a[1] = 2.0 / b0; 174 - iir->a[2] = 1.0 / b0; 175 - 176 - iir->b[0] = 1.0; 177 - iir->b[1] = 2.0 * (c * c - 1.0) / b0; 178 - iir->b[2] = (f - c * c - 1.0) / b0; 179 - } 180 - 181 - static 182 - void wav_iir_butterworth (wav_iir2_t *iir, unsigned n, unsigned long cut, unsigned long srate) 183 - { 184 - unsigned i; 185 - double om; 186 - 187 - om = (double) cut / (double) srate; 188 - 189 - for (i = 0; i < n; i++) { 190 - wav_iir2_butterworth (iir + i, i, 2 * n, om); 191 - } 192 - } 193 - 194 - static 195 - double wav_iir2 (wav_iir2_t *iir, double x) 196 - { 197 - iir->x[2] = iir->x[1]; 198 - iir->x[1] = iir->x[0]; 199 - iir->x[0] = x; 200 - 201 - iir->y[2] = iir->y[1]; 202 - iir->y[1] = iir->y[0]; 203 - 204 - iir->y[0] = iir->a[0] * iir->x[0]; 205 - iir->y[0] += iir->a[1] * iir->x[1] + iir->a[2] * iir->x[2]; 206 - iir->y[0] += iir->b[1] * iir->y[1] + iir->b[2] * iir->y[2]; 207 - 208 - return (iir->y[0]); 209 - } 210 - 211 - static 212 - double wav_iir (wav_iir2_t *iir, unsigned n, double x) 213 - { 214 - unsigned i; 215 - 216 - for (i = 0; i < n; i++) { 217 - x = wav_iir2 (iir + i, x); 218 - } 219 - 220 - return (x); 221 146 } 222 147 223 148 ··· 604 529 } 605 530 606 531 static 607 - void wav_setup_iir (wav_save_t *wav) 532 + int wav_save_pulse_0 (wav_save_t *wav, unsigned long clk, long smp) 608 533 { 609 - unsigned cnt; 610 - unsigned long freq; 534 + unsigned long cnt; 535 + unsigned long clock, srate; 536 + double f; 611 537 612 - if (wav->par->lowpass == 0) { 613 - wav->iir_cnt = 0; 614 - return; 615 - } 538 + clock = wav->img->clock; 539 + srate = wav->par->srate; 540 + 541 + f = (double) wav->rem / (double) clock; 616 542 617 - cnt = (wav->par->order + 1) / 2; 543 + wav->lp0_smp = f * wav->lp0_smp + (1.0 - f) * smp; 618 544 619 - if (cnt < 1) { 620 - cnt = 1; 621 - } 622 - else if (cnt > 8) { 623 - cnt = 8; 545 + while (clk > 0) { 546 + cnt = (clk < 256) ? clk : 256; 547 + clk -= cnt; 548 + 549 + wav->rem += cnt * srate; 550 + 551 + while (wav->rem >= clock) { 552 + wav->rem -= clock; 553 + 554 + if (wav_save_smp (wav, wav->lp0_smp)) { 555 + return (1); 556 + } 557 + 558 + wav->lp0_smp = smp; 559 + } 624 560 } 625 561 626 - if (wav->par->sine_wave) { 627 - freq = wav->par->srate; 562 + return (0); 563 + } 564 + 565 + static 566 + int wav_save_pcm_0 (wav_save_t *wav) 567 + { 568 + unsigned long i; 569 + unsigned long clk; 570 + long smp; 571 + int level; 572 + const pti_img_t *img; 573 + 574 + img = wav->img; 575 + 576 + wav->lp0_smp = 0; 577 + 578 + for (i = 0; i < img->pulse_cnt; i++) { 579 + pti_pulse_get (img->pulse[i], &clk, &level); 580 + 581 + smp = (level == 0) ? 0 : ((level < 0) ? wav->smp0 : wav->smp1); 582 + 583 + if (wav_save_pulse_0 (wav, clk, smp)) { 584 + return (1); 585 + } 628 586 } 629 - else { 630 - freq = wav->img->clock; 587 + 588 + return (0); 589 + } 590 + 591 + static 592 + void wav_setup_1 (wav_save_t *wav) 593 + { 594 + double om; 595 + 596 + wav->lp1_smp = 0.0; 597 + 598 + if (wav->par->lowpass == 0) { 599 + wav->lp1_a = 1.0; 600 + wav->lp1_b = 0.0; 601 + return; 631 602 } 632 603 633 - wav_iir_butterworth (wav->iir, cnt, wav->par->lowpass, freq); 604 + om = 2.0 * M_PI * (double) wav->par->lowpass / (double) wav->img->clock; 634 605 635 - wav->iir_cnt = cnt; 606 + wav->lp1_a = om / (om + 1.0); 607 + wav->lp1_b = 1.0 / (om + 1.0); 636 608 } 637 609 638 610 static 639 - int wav_save_pulse_square (wav_save_t *wav, unsigned long clk, long smp) 611 + int wav_save_pulse_1 (wav_save_t *wav, unsigned long clk, long smp) 640 612 { 641 - unsigned long cnt; 642 613 unsigned long clock, srate; 614 + double f1, f2; 643 615 644 616 clock = wav->img->clock; 645 617 srate = wav->par->srate; 646 618 647 - while (clk > 0) { 648 - cnt = (clk < 256) ? clk : 256; 619 + f1 = wav->lp1_b; 620 + f2 = wav->lp1_a * smp; 621 + 622 + while (clk--) { 623 + wav->lp1_smp = f1 * wav->lp1_smp + f2; 649 624 650 - wav->rem += cnt * srate; 625 + wav->rem += srate; 651 626 652 627 while (wav->rem >= clock) { 653 628 wav->rem -= clock; 654 629 655 - if (wav_save_smp (wav, smp)) { 630 + if (wav_save_smp (wav, (long) wav->lp1_smp)) { 656 631 return (1); 657 632 } 658 633 } 634 + } 659 635 660 - clk -= cnt; 636 + return (0); 637 + } 638 + 639 + static 640 + int wav_save_pcm_1 (wav_save_t *wav) 641 + { 642 + unsigned long i; 643 + unsigned long clk; 644 + long smp; 645 + int level; 646 + const pti_img_t *img; 647 + 648 + img = wav->img; 649 + 650 + wav_setup_1 (wav); 651 + 652 + for (i = 0; i < img->pulse_cnt; i++) { 653 + pti_pulse_get (img->pulse[i], &clk, &level); 654 + 655 + smp = (level == 0) ? 0 : ((level < 0) ? wav->smp0 : wav->smp1); 656 + 657 + if (wav_save_pulse_1 (wav, clk, smp)) { 658 + return (1); 659 + } 661 660 } 662 661 663 662 return (0); 664 663 } 665 664 666 665 static 667 - int wav_save_pulse_sine (wav_save_t *wav, unsigned long clk, long smp) 666 + void wav_iir2_butterworth (wav_iir2_t *iir, unsigned k, unsigned N, double om) 668 667 { 669 - unsigned long i; 670 - unsigned long clock, srate; 671 - double val, fct; 668 + unsigned i; 669 + double b0, c, f; 672 670 673 - clock = wav->img->clock; 674 - srate = wav->par->srate; 671 + c = 1.0 / tan (M_PI * om); 672 + f = 2.0 * c * cos (M_PI * (2.0 * k + 1.0) / (2.0 * N)); 673 + b0 = c * c + f + 1.0; 674 + 675 + iir->a[0] = 1.0 / b0; 676 + iir->a[1] = 2.0 / b0; 677 + iir->a[2] = 1.0 / b0; 675 678 676 - fct = M_PI / (double) clk; 679 + iir->b[0] = 1.0; 680 + iir->b[1] = 2.0 * (c * c - 1.0) / b0; 681 + iir->b[2] = (f - c * c - 1.0) / b0; 682 + 683 + for (i = 0; i < 3; i++) { 684 + iir->x[i] = 0.0; 685 + iir->y[i] = 0.0; 686 + } 687 + } 688 + 689 + static 690 + void wav_iir_butterworth (wav_iir2_t *iir, unsigned n, unsigned long cut, unsigned long srate) 691 + { 692 + unsigned i; 693 + double om; 694 + 695 + om = (double) cut / (double) srate; 696 + 697 + for (i = 0; i < n; i++) { 698 + wav_iir2_butterworth (iir + i, i, 2 * n, om); 699 + } 700 + } 701 + 702 + static 703 + void wav_setup_n (wav_save_t *wav) 704 + { 705 + unsigned cnt; 706 + 707 + if (wav->par->lowpass == 0) { 708 + wav->iir_cnt = 0; 709 + return; 710 + } 711 + 712 + cnt = (wav->par->order + 1) / 2; 713 + 714 + if (cnt < 1) { 715 + cnt = 1; 716 + } 717 + else if (cnt > 8) { 718 + cnt = 8; 719 + } 720 + 721 + wav_iir_butterworth (wav->iir, cnt, wav->par->lowpass, wav->img->clock); 722 + 723 + wav->iir_cnt = cnt; 724 + } 725 + 726 + static inline 727 + double wav_iir2 (wav_iir2_t *iir, double x) 728 + { 729 + iir->x[2] = iir->x[1]; 730 + iir->x[1] = iir->x[0]; 731 + iir->x[0] = x; 677 732 678 - for (i = 0; i < clk; i++) { 679 - wav->rem += srate; 733 + iir->y[2] = iir->y[1]; 734 + iir->y[1] = iir->y[0]; 680 735 681 - while (wav->rem >= clock) { 682 - wav->rem -= clock; 736 + iir->y[0] = iir->a[0] * iir->x[0]; 737 + iir->y[0] += iir->a[1] * iir->x[1] + iir->a[2] * iir->x[2]; 738 + iir->y[0] += iir->b[1] * iir->y[1] + iir->b[2] * iir->y[2]; 683 739 684 - val = smp * sin (i * fct); 740 + return (iir->y[0]); 741 + } 685 742 686 - if (wav->iir_cnt > 0) { 687 - val = wav_iir (wav->iir, wav->iir_cnt, val); 688 - } 743 + static 744 + double wav_iir (wav_iir2_t *iir, unsigned n, double x) 745 + { 746 + unsigned i; 689 747 690 - if (wav_save_smp (wav, (long) val)) { 691 - return (1); 692 - } 693 - } 748 + for (i = 0; i < n; i++) { 749 + x = wav_iir2 (iir + i, x); 694 750 } 695 751 696 - return (0); 752 + return (x); 697 753 } 698 754 699 755 static 700 - int wav_save_pulse_iir (wav_save_t *wav, unsigned long clk, long smp) 756 + int wav_save_pulse_n (wav_save_t *wav, unsigned long clk, long smp) 701 757 { 702 - unsigned long i; 703 758 unsigned long clock, srate; 759 + double smpf; 704 760 long val; 705 761 706 762 clock = wav->img->clock; 707 763 srate = wav->par->srate; 708 764 709 - for (i = 0; i < clk; i++) { 710 - val = wav_iir (wav->iir, wav->iir_cnt, smp); 765 + smpf = (double) smp; 766 + 767 + while (clk--) { 768 + val = (long) wav_iir (wav->iir, wav->iir_cnt, smpf); 711 769 712 770 wav->rem += srate; 713 771 ··· 724 782 } 725 783 726 784 static 727 - int wav_save_pcm (wav_save_t *wav) 785 + int wav_save_pcm_n (wav_save_t *wav) 728 786 { 729 787 unsigned long i; 730 788 unsigned long clk; ··· 732 790 int level; 733 791 const pti_img_t *img; 734 792 735 - if (pti_set_pos (wav->fp, wav->start_pcm)) { 736 - return (1); 737 - } 738 - 739 - wav_setup_iir (wav); 740 - 741 - wav->size = 0; 742 - 743 793 img = wav->img; 744 794 745 - wav->rem = 0; 795 + wav_setup_n (wav); 746 796 747 797 for (i = 0; i < img->pulse_cnt; i++) { 748 798 pti_pulse_get (img->pulse[i], &clk, &level); 749 799 750 - if (level < 0) { 751 - smp = -16384; 800 + smp = (level == 0) ? 0 : ((level < 0) ? wav->smp0 : wav->smp1); 801 + 802 + if (wav_save_pulse_n (wav, clk, smp)) { 803 + return (1); 752 804 } 753 - else if (level > 0) { 754 - smp = 16384; 755 - } 756 - else { 757 - smp = 0; 758 - } 805 + } 806 + 807 + return (0); 808 + } 759 809 760 - if (wav->par->sine_wave) { 761 - if (wav_save_pulse_sine (wav, clk, smp)) { 762 - return (1); 763 - } 810 + static 811 + int wav_save_pcm (wav_save_t *wav) 812 + { 813 + if (pti_set_pos (wav->fp, wav->start_pcm)) { 814 + return (1); 815 + } 816 + 817 + wav->size = 0; 818 + wav->rem = 0; 819 + 820 + if (wav->par->order == 0) { 821 + if (wav_save_pcm_0 (wav)) { 822 + return (1); 764 823 } 765 - else if (wav->iir_cnt == 0) { 766 - if (wav_save_pulse_square (wav, clk, smp)) { 767 - return (1); 768 - } 824 + } 825 + else if (wav->par->order == 1) { 826 + if (wav_save_pcm_1 (wav)) { 827 + return (1); 769 828 } 770 - else { 771 - if (wav_save_pulse_iir (wav, clk, smp)) { 772 - return (1); 773 - } 829 + } 830 + else { 831 + if (wav_save_pcm_n (wav)) { 832 + return (1); 774 833 } 775 834 } 776 835 777 - if (wav->rem >= (img->clock / 2)) { 836 + if (wav->rem >= (wav->img->clock / 2)) { 778 837 if (wav_save_smp (wav, 0)) { 779 838 return (1); 780 839 } ··· 799 858 wav.start_fmt = wav.start_riff + 12; 800 859 wav.start_data = wav.start_fmt + 24; 801 860 wav.start_pcm = wav.start_data + 8; 861 + 862 + wav.smp0 = -16384; 863 + wav.smp1 = 16384; 802 864 803 865 wav.iir_cnt = 0; 804 866
+2 -4
src/drivers/pti/pti-img-wav.h
··· 5 5 /***************************************************************************** 6 6 * File name: src/drivers/pti/pti-img-wav.h * 7 7 * Created: 2020-04-25 by Hampa Hug <hampa@hampa.ch> * 8 - * Copyright: (C) 2020 Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2020-2023 Hampa Hug <hampa@hampa.ch> * 9 9 *****************************************************************************/ 10 10 11 11 /***************************************************************************** ··· 15 15 * * 16 16 * This program is distributed in the hope that it will be useful, but * 17 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 19 * Public License for more details. * 20 20 *****************************************************************************/ 21 21 ··· 33 33 unsigned channels; 34 34 unsigned long lowpass; 35 35 unsigned order; 36 - char sine_wave; 37 36 } pti_wav_param_t; 38 37 39 38 ··· 44 43 void pti_wav_set_bits (unsigned val); 45 44 void pti_wav_set_lowpass (unsigned long val); 46 45 void pti_wav_set_lowpass_order (unsigned val); 47 - void pti_wav_set_sine_wave (int val); 48 46 49 47 pti_img_t *pti_load_wav (FILE *fp, unsigned long clock); 50 48
+1 -10
src/utils/pti/main.c
··· 5 5 /***************************************************************************** 6 6 * File name: src/utils/pti/main.c * 7 7 * Created: 2020-04-25 by Hampa Hug <hampa@hampa.ch> * 8 - * Copyright: (C) 2020-2022 Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2020-2023 Hampa Hug <hampa@hampa.ch> * 9 9 *****************************************************************************/ 10 10 11 11 /***************************************************************************** ··· 480 480 } 481 481 482 482 pti_wav_set_lowpass_order (order); 483 - } 484 - else if (strcmp (name, "wav-sine") == 0) { 485 - int sine; 486 - 487 - if (pti_parse_bool (val, &sine)) { 488 - return (1); 489 - } 490 - 491 - pti_wav_set_sine_wave (sine); 492 483 } 493 484 else if (strcmp (name, "wav-srate") == 0) { 494 485 unsigned long srate;