home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 Secrets / Secrets2.iso / Audio / WAV / MaplayP / _SETUP.1 / synfilt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-20  |  32.1 KB  |  1,053 lines

  1. /* synfilt.cpp
  2.  
  3.     Synthesis Filter implementation */
  4.  
  5. /* -- 03/20/97 --
  6.  *  compute_new_v() -- reoptimized with the assumption that constant offsets
  7.  *    to memory are free.  Common subexpression were redone for better
  8.  *    optimization.
  9.  *  compute_pcm_samples() -- reoptimized with constant offsets.
  10.  *
  11.  *  -- Conrad Wei-Li Song (conradsong@mail.utexas.edu)
  12.  */
  13.  
  14. /*
  15.  *  @(#) synthesis_filter.cc 1.14, last edit: 6/21/94 11:22:20
  16.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  17.  *  @(#) Berlin University of Technology
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  */
  33.  
  34. /*
  35.  *  Changes from version 1.1 to 1.2:
  36.  *    - compute_new_v() uses a 32 point fast cosine transform as described by
  37.  *      Byeong Gi Lee in IEEE Transactions ASSP-32 Part 2, August 1984,
  38.  *      "A New Algorithm to Compute the Discrete Cosine Transform"
  39.  *      instead of the matrix-vector multiplication in V1.1
  40.  *    - loop unrolling done in compute_pcm_samples()
  41.  *    - if ULAW is defined, the synthesis filter does a downsampling
  42.  *      to 8 kHz by dropping samples and ignoring subbands above 4 kHz
  43.  */
  44.  
  45. #include <math.h>
  46. #include "all.h"
  47. #include "synfilt.h"
  48.  
  49. #define MY_PI 3.14159265358979323846
  50.  
  51. static const real cos1_64  = 1.0 / (2.0 * cos(MY_PI        / 64.0));
  52. static const real cos3_64  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 64.0));
  53. static const real cos5_64  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 64.0));
  54. static const real cos7_64  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 64.0));
  55. static const real cos9_64  = 1.0 / (2.0 * cos(MY_PI * 9.0  / 64.0));
  56. static const real cos11_64 = 1.0 / (2.0 * cos(MY_PI * 11.0 / 64.0));
  57. static const real cos13_64 = 1.0 / (2.0 * cos(MY_PI * 13.0 / 64.0));
  58. static const real cos15_64 = 1.0 / (2.0 * cos(MY_PI * 15.0 / 64.0));
  59. static const real cos17_64 = 1.0 / (2.0 * cos(MY_PI * 17.0 / 64.0));
  60. static const real cos19_64 = 1.0 / (2.0 * cos(MY_PI * 19.0 / 64.0));
  61. static const real cos21_64 = 1.0 / (2.0 * cos(MY_PI * 21.0 / 64.0));
  62. static const real cos23_64 = 1.0 / (2.0 * cos(MY_PI * 23.0 / 64.0));
  63. static const real cos25_64 = 1.0 / (2.0 * cos(MY_PI * 25.0 / 64.0));
  64. static const real cos27_64 = 1.0 / (2.0 * cos(MY_PI * 27.0 / 64.0));
  65. static const real cos29_64 = 1.0 / (2.0 * cos(MY_PI * 29.0 / 64.0));
  66. static const real cos31_64 = 1.0 / (2.0 * cos(MY_PI * 31.0 / 64.0));
  67. static const real cos1_32  = 1.0 / (2.0 * cos(MY_PI        / 32.0));
  68. static const real cos3_32  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 32.0));
  69. static const real cos5_32  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 32.0));
  70. static const real cos7_32  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 32.0));
  71. static const real cos9_32  = 1.0 / (2.0 * cos(MY_PI * 9.0  / 32.0));
  72. static const real cos11_32 = 1.0 / (2.0 * cos(MY_PI * 11.0 / 32.0));
  73. static const real cos13_32 = 1.0 / (2.0 * cos(MY_PI * 13.0 / 32.0));
  74. static const real cos15_32 = 1.0 / (2.0 * cos(MY_PI * 15.0 / 32.0));
  75. static const real cos1_16  = 1.0 / (2.0 * cos(MY_PI        / 16.0));
  76. static const real cos3_16  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 16.0));
  77. static const real cos5_16  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 16.0));
  78. static const real cos7_16  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 16.0));
  79. static const real cos1_8   = 1.0 / (2.0 * cos(MY_PI        / 8.0));
  80. static const real cos3_8   = 1.0 / (2.0 * cos(MY_PI * 3.0  / 8.0));
  81. static const real cos1_4   = 1.0 / (2.0 * cos(MY_PI / 4.0));
  82.  
  83.  
  84. const real SynthesisFilter::d[512] = {
  85.     // Note: These values are not in the same order
  86.     // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3
  87.     0.000000000, -0.000442505,  0.003250122, -0.007003784,
  88.     0.031082153, -0.078628540,  0.100311279, -0.572036743,
  89.     1.144989014,  0.572036743,  0.100311279,  0.078628540,
  90.     0.031082153,  0.007003784,  0.003250122,  0.000442505,
  91.     -0.000015259, -0.000473022,  0.003326416, -0.007919312,
  92.     0.030517578, -0.084182739,  0.090927124, -0.600219727,
  93.     1.144287109,  0.543823242,  0.108856201,  0.073059082,
  94.     0.031478882,  0.006118774,  0.003173828,  0.000396729,
  95.   -0.000015259, -0.000534058,  0.003387451, -0.008865356,
  96.     0.029785156, -0.089706421,  0.080688477, -0.628295898,
  97.     1.142211914,  0.515609741,  0.116577148,  0.067520142,
  98.      0.031738281,  0.005294800,  0.003082275,  0.000366211,
  99.     -0.000015259, -0.000579834,  0.003433228, -0.009841919,
  100.      0.028884888, -0.095169067,  0.069595337, -0.656219482,
  101.     1.138763428,  0.487472534,  0.123474121,  0.061996460,
  102.    0.031845093,  0.004486084,  0.002990723,  0.000320435,
  103.   -0.000015259, -0.000625610,  0.003463745, -0.010848999,
  104.      0.027801514, -0.100540161,  0.057617188, -0.683914185,
  105.     1.133926392,  0.459472656,  0.129577637,  0.056533813,
  106.     0.031814575,  0.003723145,  0.002899170,  0.000289917,
  107.   -0.000015259, -0.000686646,  0.003479004, -0.011886597,
  108.     0.026535034, -0.105819702,  0.044784546, -0.711318970,
  109.     1.127746582,  0.431655884,  0.134887695,  0.051132202,
  110.     0.031661987,  0.003005981,  0.002792358,  0.000259399,
  111.     -0.000015259, -0.000747681,  0.003479004, -0.012939453,
  112.     0.025085449, -0.110946655,  0.031082153, -0.738372803,
  113.    1.120223999,  0.404083252,  0.139450073,  0.045837402,
  114.    0.031387329,  0.002334595,  0.002685547,  0.000244141,
  115.   -0.000030518, -0.000808716,  0.003463745, -0.014022827,
  116.    0.023422241, -0.115921021,  0.016510010, -0.765029907,
  117.     1.111373901,  0.376800537,  0.143264771,  0.040634155,
  118.    0.031005859,  0.001693726,  0.002578735,  0.000213623,
  119.     -0.000030518, -0.000885010,  0.003417969, -0.015121460,
  120.     0.021575928, -0.120697021,  0.001068115, -0.791213989,
  121.    1.101211548,  0.349868774,  0.146362305,  0.035552979,
  122.     0.030532837,  0.001098633,  0.002456665,  0.000198364,
  123.     -0.000030518, -0.000961304,  0.003372192, -0.016235352,
  124.    0.019531250, -0.125259399, -0.015228271, -0.816864014,
  125.      1.089782715,  0.323318481,  0.148773193,  0.030609131,
  126.     0.029937744,  0.000549316,  0.002349854,  0.000167847,
  127.     -0.000030518, -0.001037598,  0.003280640, -0.017349243,
  128.     0.017257690, -0.129562378, -0.032379150, -0.841949463,
  129.    1.077117920,  0.297210693,  0.150497437,  0.025817871,
  130.    0.029281616,  0.000030518,  0.002243042,  0.000152588,
  131.   -0.000045776, -0.001113892,  0.003173828, -0.018463135,
  132.     0.014801025, -0.133590698, -0.050354004, -0.866363525,
  133.     1.063217163,  0.271591187,  0.151596069,  0.021179199,
  134.     0.028533936, -0.000442505,  0.002120972,  0.000137329,
  135.     -0.000045776, -0.001205444,  0.003051758, -0.019577026,
  136.     0.012115479, -0.137298584, -0.069168091, -0.890090942,
  137.      1.048156738,  0.246505737,  0.152069092,  0.016708374,
  138.     0.027725220, -0.000869751,  0.002014160,  0.000122070,
  139.   -0.000061035, -0.001296997,  0.002883911, -0.020690918,
  140.    0.009231567, -0.140670776, -0.088775635, -0.913055420,
  141.      1.031936646,  0.221984863,  0.151962280,  0.012420654,
  142.    0.026840210, -0.001266479,  0.001907349,  0.000106812,
  143.   -0.000061035, -0.001388550,  0.002700806, -0.021789551,
  144.     0.006134033, -0.143676758, -0.109161377, -0.935195923,
  145.    1.014617920,  0.198059082,  0.151306152,  0.008316040,
  146.     0.025909424, -0.001617432,  0.001785278,  0.000106812,
  147.     -0.000076294, -0.001480103,  0.002487183, -0.022857666,
  148.      0.002822876, -0.146255493, -0.130310059, -0.956481934,
  149.     0.996246338,  0.174789429,  0.150115967,  0.004394531,
  150.    0.024932861, -0.001937866,  0.001693726,  0.000091553,
  151.   -0.000076294, -0.001586914,  0.002227783, -0.023910522,
  152.     -0.000686646, -0.148422241, -0.152206421, -0.976852417,
  153.    0.976852417,  0.152206421,  0.148422241,  0.000686646,
  154.     0.023910522, -0.002227783,  0.001586914,  0.000076294,
  155.     -0.000091553, -0.001693726,  0.001937866, -0.024932861,
  156.     -0.004394531, -0.150115967, -0.174789429, -0.996246338,
  157.    0.956481934,  0.130310059,  0.146255493, -0.002822876,
  158.    0.022857666, -0.002487183,  0.001480103,  0.000076294,
  159.     -0.000106812, -0.001785278,  0.001617432, -0.025909424,
  160.   -0.008316040, -0.151306152, -0.198059082, -1.014617920,
  161.    0.935195923,  0.109161377,  0.143676758, -0.006134033,
  162.    0.021789551, -0.002700806,  0.001388550,  0.000061035,
  163.   -0.000106812, -0.001907349,  0.001266479, -0.026840210,
  164.     -0.012420654, -0.151962280, -0.221984863, -1.031936646,
  165.     0.913055420,  0.088775635,  0.140670776, -0.009231567,
  166.      0.020690918, -0.002883911,  0.001296997,  0.000061035,
  167.     -0.000122070, -0.002014160,  0.000869751, -0.027725220,
  168.   -0.016708374, -0.152069092, -0.246505737, -1.048156738,
  169.    0.890090942,  0.069168091,  0.137298584, -0.012115479,
  170.     0.019577026, -0.003051758,  0.001205444,  0.000045776,
  171.     -0.000137329, -0.002120972,  0.000442505, -0.028533936,
  172.   -0.021179199, -0.151596069, -0.271591187, -1.063217163,
  173.    0.866363525,  0.050354004,  0.133590698, -0.014801025,
  174.    0.018463135, -0.003173828,  0.001113892,  0.000045776,
  175.   -0.000152588, -0.002243042, -0.000030518, -0.029281616,
  176.   -0.025817871, -0.150497437, -0.297210693, -1.077117920,
  177.      0.841949463,  0.032379150,  0.129562378, -0.017257690,
  178.      0.017349243, -0.003280640,  0.001037598,  0.000030518,
  179.   -0.000167847, -0.002349854, -0.000549316, -0.029937744,
  180.   -0.030609131, -0.148773193, -0.323318481, -1.089782715,
  181.     0.816864014,  0.015228271,  0.125259399, -0.019531250,
  182.    0.016235352, -0.003372192,  0.000961304,  0.000030518,
  183.     -0.000198364, -0.002456665, -0.001098633, -0.030532837,
  184.     -0.035552979, -0.146362305, -0.349868774, -1.101211548,
  185.      0.791213989, -0.001068115,  0.120697021, -0.021575928,
  186.     0.015121460, -0.003417969,  0.000885010,  0.000030518,
  187.   -0.000213623, -0.002578735, -0.001693726, -0.031005859,
  188.     -0.040634155, -0.143264771, -0.376800537, -1.111373901,
  189.    0.765029907, -0.016510010,  0.115921021, -0.023422241,
  190.    0.014022827, -0.003463745,  0.000808716,  0.000030518,
  191.   -0.000244141, -0.002685547, -0.002334595, -0.031387329,
  192.   -0.045837402, -0.139450073, -0.404083252, -1.120223999,
  193.    0.738372803, -0.031082153,  0.110946655, -0.025085449,
  194.     0.012939453, -0.003479004,  0.000747681,  0.000015259,
  195.     -0.000259399, -0.002792358, -0.003005981, -0.031661987,
  196.   -0.051132202, -0.134887695, -0.431655884, -1.127746582,
  197.     0.711318970, -0.044784546,  0.105819702, -0.026535034,
  198.    0.011886597, -0.003479004,  0.000686646,  0.000015259,
  199.     -0.000289917, -0.002899170, -0.003723145, -0.031814575,
  200.     -0.056533813, -0.129577637, -0.459472656, -1.133926392,
  201.    0.683914185, -0.057617188,  0.100540161, -0.027801514,
  202.     0.010848999, -0.003463745,  0.000625610,  0.000015259,
  203.   -0.000320435, -0.002990723, -0.004486084, -0.031845093,
  204.   -0.061996460, -0.123474121, -0.487472534, -1.138763428,
  205.     0.656219482, -0.069595337,  0.095169067, -0.028884888,
  206.     0.009841919, -0.003433228,  0.000579834,  0.000015259,
  207.     -0.000366211, -0.003082275, -0.005294800, -0.031738281,
  208.   -0.067520142, -0.116577148, -0.515609741, -1.142211914,
  209.     0.628295898, -0.080688477,  0.089706421, -0.029785156,
  210.     0.008865356, -0.003387451,  0.000534058,  0.000015259,
  211.   -0.000396729, -0.003173828, -0.006118774, -0.031478882,
  212.   -0.073059082, -0.108856201, -0.543823242, -1.144287109,
  213.     0.600219727, -0.090927124,  0.084182739, -0.030517578,
  214.     0.007919312, -0.003326416,  0.000473022,  0.000015259
  215. };
  216.  
  217. SynthesisFilter::SynthesisFilter(uint32 channelnumber, real factor)
  218. {
  219.   register real *floatp, *floatp2;
  220.  
  221.   // initialize v1[] and v2[]:
  222.   for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; )
  223.      *--floatp = *--floatp2 = 0.0;
  224.  
  225.   // initialize samples[]:
  226.   for (floatp = samples + 32; floatp > samples; )
  227.      *--floatp = 0.0;
  228.  
  229.   channel = channelnumber;
  230.   actual_v = v1;
  231.   actual_write_pos = 15;
  232.   scalefactor = factor;
  233. }
  234.  
  235. void SynthesisFilter::reset()
  236. {
  237.   register real *floatp, *floatp2;
  238.  
  239.   // initialize v1[] and v2[]:
  240.   for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; )
  241.      *--floatp = *--floatp2 = 0.0;
  242.  
  243.   // initialize samples[]:
  244.   for (floatp = samples + 32; floatp > samples; )
  245.      *--floatp = 0.0;
  246.  
  247.   actual_v = v1;
  248.   actual_write_pos = 15;
  249. }
  250.  
  251. void SynthesisFilter::compute_new_v()
  252. {
  253.     real new_v[32];         // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
  254.     real p[16];
  255.     real pp[16];
  256.  
  257.     // compute new values via a fast cosine transform:
  258.     {
  259.     register real *x1 = samples;
  260.  
  261.     p[0] = x1[0] + x1[31];
  262.     p[1] = x1[1] + x1[30];
  263.     p[2] = x1[2] + x1[29];
  264.     p[3] = x1[3] + x1[28];
  265.     p[4] = x1[4] + x1[27];
  266.     p[5] = x1[5] + x1[26];
  267.     p[6] = x1[6] + x1[25];
  268.     p[7] = x1[7] + x1[24];
  269.     p[8] = x1[8] + x1[23];
  270.     p[9] = x1[9] + x1[22];
  271.     p[10] = x1[10] + x1[21];
  272.     p[11] = x1[11] + x1[20];
  273.     p[12] = x1[12] + x1[19];
  274.     p[13] = x1[13] + x1[18];
  275.     p[14] = x1[14] + x1[17];
  276.     p[15] = x1[15] + x1[16];
  277.     }
  278.  
  279.     {
  280.     pp[0] = p[0] + p[15];
  281.     pp[1] = p[1] + p[14];
  282.     pp[2] = p[2] + p[13];
  283.     pp[3] = p[3] + p[12];
  284.     pp[4] = p[4] + p[11];
  285.     pp[5] = p[5] + p[10];
  286.     pp[6] = p[6] + p[9];
  287.     pp[7] = p[7] + p[8];
  288.     pp[8] = (p[0] - p[15]) * cos1_32;
  289.     pp[9] = (p[1] - p[14]) * cos3_32;
  290.     pp[10] = (p[2] - p[13]) * cos5_32;
  291.     pp[11] = (p[3] - p[12]) * cos7_32;
  292.     pp[12] = (p[4] - p[11]) * cos9_32;
  293.     pp[13] = (p[5] - p[10]) * cos11_32;
  294.     pp[14] = (p[6] - p[9]) * cos13_32;
  295.     pp[15] = (p[7] - p[8]) * cos15_32;
  296.     }
  297.  
  298.     {
  299.     p[0] = pp[0] + pp[7];
  300.     p[1] = pp[1] + pp[6];
  301.     p[2] = pp[2] + pp[5];
  302.     p[3] = pp[3] + pp[4];
  303.     p[4] = (pp[0] - pp[7]) * cos1_16;
  304.     p[5] = (pp[1] - pp[6]) * cos3_16;
  305.     p[6] = (pp[2] - pp[5]) * cos5_16;
  306.     p[7] = (pp[3] - pp[4]) * cos7_16;
  307.     p[8] = pp[8] + pp[15];
  308.     p[9] = pp[9] + pp[14];
  309.     p[10] = pp[10] + pp[13];
  310.     p[11] = pp[11] + pp[12];
  311.     p[12] = (pp[8] - pp[15]) * cos1_16;
  312.     p[13] = (pp[9] - pp[14]) * cos3_16;
  313.     p[14] = (pp[10] - pp[13]) * cos5_16;
  314.     p[15] = (pp[11] - pp[12]) * cos7_16;
  315.     }
  316.  
  317.     {
  318.     pp[0] = p[0] + p[3];
  319.     pp[1] = p[1] + p[2];
  320.     pp[2] = (p[0] - p[3]) * cos1_8;
  321.     pp[3] = (p[1] - p[2]) * cos3_8;
  322.     pp[4] = p[4] + p[7];
  323.     pp[5] = p[5] + p[6];
  324.     pp[6] = (p[4] - p[7]) * cos1_8;
  325.     pp[7] = (p[5] - p[6]) * cos3_8;
  326.     pp[8] = p[8] + p[11];
  327.     pp[9] = p[9] + p[10];
  328.     pp[10] = (p[8] - p[11]) * cos1_8;
  329.     pp[11] = (p[9] - p[10]) * cos3_8;
  330.     pp[12] = p[12] + p[15];
  331.     pp[13] = p[13] + p[14];
  332.     pp[14] = (p[12] - p[15]) * cos1_8;
  333.     pp[15] = (p[13] - p[14]) * cos3_8;
  334.     }
  335.  
  336.     {
  337.     p[0] = pp[0] + pp[1];
  338.     p[1] = (pp[0] - pp[1]) * cos1_4;
  339.     p[2] = pp[2] + pp[3];
  340.     p[3] = (pp[2] - pp[3]) * cos1_4;
  341.     p[4] = pp[4] + pp[5];
  342.     p[5] = (pp[4] - pp[5]) * cos1_4;
  343.     p[6] = pp[6] + pp[7];
  344.     p[7] = (pp[6] - pp[7]) * cos1_4;
  345.     p[8] = pp[8] + pp[9];
  346.     p[9] = (pp[8] - pp[9]) * cos1_4;
  347.     p[10] = pp[10] + pp[11];
  348.     p[11] = (pp[10] - pp[11]) * cos1_4;
  349.     p[12] = pp[12] + pp[13];
  350.     p[13] = (pp[12] - pp[13]) * cos1_4;
  351.     p[14] = pp[14] + pp[15];
  352.     p[15] = (pp[14] - pp[15]) * cos1_4;
  353.     }
  354.  
  355.     {
  356.     // this is pretty insane coding
  357.     register real tmp1;
  358.     new_v[36-17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6];
  359.     new_v[44-17] = -p[6] - p[7] - p[4];
  360.     new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13];
  361.     new_v[34-17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14];
  362.     new_v[38-17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13];
  363.     new_v[46-17] = -p[14] - p[15] - p[12] - p[8];
  364.     new_v[42-17] = tmp1 - p[12];
  365.     new_v[48-17] = -p[0];
  366.     new_v[0] = p[1];
  367.     new_v[40-17] = -(new_v[8] = p[3]) - p[2];
  368.     }
  369.  
  370.     {
  371.     register real *x1 = samples;
  372.  
  373.     p[0] = (x1[0] - x1[31]) * cos1_64;
  374.     p[1] = (x1[1] - x1[30]) * cos3_64;
  375.     p[2] = (x1[2] - x1[29]) * cos5_64;
  376.     p[3] = (x1[3] - x1[28]) * cos7_64;
  377.     p[4] = (x1[4] - x1[27]) * cos9_64;
  378.     p[5] = (x1[5] - x1[26]) * cos11_64;
  379.     p[6] = (x1[6] - x1[25]) * cos13_64;
  380.     p[7] = (x1[7] - x1[24]) * cos15_64;
  381.     p[8] = (x1[8] - x1[23]) * cos17_64;
  382.     p[9] = (x1[9] - x1[22]) * cos19_64;
  383.     p[10] = (x1[10] - x1[21]) * cos21_64;
  384.     p[11] = (x1[11] - x1[20]) * cos23_64;
  385.     p[12] = (x1[12] - x1[19]) * cos25_64;
  386.     p[13] = (x1[13] - x1[18]) * cos27_64;
  387.     p[14] = (x1[14] - x1[17]) * cos29_64;
  388.     p[15] = (x1[15] - x1[16]) * cos31_64;
  389.     }
  390.  
  391.     {
  392.     pp[0] = p[0] + p[15];
  393.     pp[1] = p[1] + p[14];
  394.     pp[2] = p[2] + p[13];
  395.     pp[3] = p[3] + p[12];
  396.     pp[4] = p[4] + p[11];
  397.     pp[5] = p[5] + p[10];
  398.     pp[6] = p[6] + p[9];
  399.     pp[7] = p[7] + p[8];
  400.     pp[8] = (p[0] - p[15]) * cos1_32;
  401.     pp[9] = (p[1] - p[14]) * cos3_32;
  402.     pp[10] = (p[2] - p[13]) * cos5_32;
  403.     pp[11] = (p[3] - p[12]) * cos7_32;
  404.     pp[12] = (p[4] - p[11]) * cos9_32;
  405.     pp[13] = (p[5] - p[10]) * cos11_32;
  406.     pp[14] = (p[6] - p[9]) * cos13_32;
  407.     pp[15] = (p[7] - p[8]) * cos15_32;
  408.     }
  409.  
  410.     {
  411.     p[0] = pp[0] + pp[7];
  412.     p[1] = pp[1] + pp[6];
  413.     p[2] = pp[2] + pp[5];
  414.     p[3] = pp[3] + pp[4];
  415.     p[4] = (pp[0] - pp[7]) * cos1_16;
  416.     p[5] = (pp[1] - pp[6]) * cos3_16;
  417.     p[6] = (pp[2] - pp[5]) * cos5_16;
  418.     p[7] = (pp[3] - pp[4]) * cos7_16;
  419.     p[8] = pp[8] + pp[15];
  420.     p[9] = pp[9] + pp[14];
  421.     p[10] = pp[10] + pp[13];
  422.     p[11] = pp[11] + pp[12];
  423.     p[12] = (pp[8] - pp[15]) * cos1_16;
  424.     p[13] = (pp[9] - pp[14]) * cos3_16;
  425.     p[14] = (pp[10] - pp[13]) * cos5_16;
  426.     p[15] = (pp[11] - pp[12]) * cos7_16;
  427.     }
  428.  
  429.     {
  430.     pp[0] = p[0] + p[3];
  431.     pp[1] = p[1] + p[2];
  432.     pp[2] = (p[0] - p[3]) * cos1_8;
  433.     pp[3] = (p[1] - p[2]) * cos3_8;
  434.     pp[4] = p[4] + p[7];
  435.     pp[5] = p[5] + p[6];
  436.     pp[6] = (p[4] - p[7]) * cos1_8;
  437.     pp[7] = (p[5] - p[6]) * cos3_8;
  438.     pp[8] = p[8] + p[11];
  439.     pp[9] = p[9] + p[10];
  440.     pp[10] = (p[8] - p[11]) * cos1_8;
  441.     pp[11] = (p[9] - p[10]) * cos3_8;
  442.     pp[12] = p[12] + p[15];
  443.     pp[13] = p[13] + p[14];
  444.     pp[14] = (p[12] - p[15]) * cos1_8;
  445.     pp[15] = (p[13] - p[14]) * cos3_8;
  446.     }
  447.  
  448.     {
  449.     p[0] = pp[0] + pp[1];
  450.     p[1] = (pp[0] - pp[1]) * cos1_4;
  451.     p[2] = pp[2] + pp[3];
  452.     p[3] = (pp[2] - pp[3]) * cos1_4;
  453.     p[4] = pp[4] + pp[5];
  454.     p[5] = (pp[4] - pp[5]) * cos1_4;
  455.     p[6] = pp[6] + pp[7];
  456.     p[7] = (pp[6] - pp[7]) * cos1_4;
  457.     p[8] = pp[8] + pp[9];
  458.     p[9] = (pp[8] - pp[9]) * cos1_4;
  459.     p[10] = pp[10] + pp[11];
  460.     p[11] = (pp[10] - pp[11]) * cos1_4;
  461.     p[12] = pp[12] + pp[13];
  462.     p[13] = (pp[12] - pp[13]) * cos1_4;
  463.     p[14] = pp[14] + pp[15];
  464.     p[15] = (pp[14] - pp[15]) * cos1_4;
  465.     }
  466.  
  467.     {
  468.     // manually doing something that a compiler should handle sucks
  469.     // coding like this is hard to read
  470.     register real tmp1, tmp2;
  471.     new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11])
  472.                             + p[5] + p[13];
  473.     new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13];
  474.     new_v[33-17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14];
  475.     new_v[35-17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14];
  476.  
  477.     new_v[39-17] = (tmp1 = -p[10] - p[11] - p[14] - p[15])
  478.                                     - p[13] - p[2] - p[3];
  479.     new_v[37-17] = tmp1 - p[13] - p[5] - p[6] - p[7];
  480.     new_v[41-17] = tmp1 - p[12] - p[2] - p[3];
  481.     new_v[43-17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]);
  482.     new_v[47-17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0];
  483.     new_v[45-17] = tmp1 - tmp2;
  484.     }
  485.  
  486.     {
  487.     // insert V[0-15] (== new_v[0-15]) into actual v:
  488.     register real *x1 = new_v;
  489.     register real *x2 = actual_v + actual_write_pos;
  490.     x2[0] = x1[0];
  491.     x2[16] = x1[1];
  492.     x2[32] = x1[2];
  493.     x2[48] = x1[3];
  494.     x2[64] = x1[4];
  495.     x2[80] = x1[5];
  496.     x2[96] = x1[6];
  497.     x2[112] = x1[7];
  498.     x2[128] = x1[8];
  499.     x2[144] = x1[9];
  500.     x2[160] = x1[10];
  501.     x2[176] = x1[11];
  502.     x2[192] = x1[12];
  503.     x2[208] = x1[13];
  504.     x2[224] = x1[14];
  505.     x2[240] = x1[15];
  506.  
  507.     // V[16] is always 0.0:
  508.     x2[256] = 0.0f;
  509.  
  510.     // insert V[17-31] (== -new_v[15-1]) into actual v:
  511.     x2[272] = -x1[15];
  512.     x2[288] = -x1[14];
  513.     x2[304] = -x1[13];
  514.     x2[320] = -x1[12];
  515.     x2[336] = -x1[11];
  516.     x2[352] = -x1[10];
  517.     x2[368] = -x1[9];
  518.     x2[384] = -x1[8];
  519.     x2[400] = -x1[7];
  520.     x2[416] = -x1[6];
  521.     x2[432] = -x1[5];
  522.     x2[448] = -x1[4];
  523.     x2[464] = -x1[3];
  524.     x2[480] = -x1[2];
  525.     x2[496] = -x1[1];
  526.  
  527.     // insert V[32] (== -new_v[0]) into other v:
  528.     x2 = (actual_v == v1 ? v2 : v1) + actual_write_pos;
  529.     x2[0] = -x1[0];
  530.  
  531.     // insert V[33-48] (== new_v[16-31]) into other v:
  532.     x2[16] = x1[16];
  533.     x2[32] = x1[17];
  534.     x2[48] = x1[18];
  535.     x2[64] = x1[19];
  536.     x2[80] = x1[20];
  537.     x2[96] = x1[21];
  538.     x2[112] = x1[22];
  539.     x2[128] = x1[23];
  540.     x2[144] = x1[24];
  541.     x2[160] = x1[25];
  542.     x2[176] = x1[26];
  543.     x2[192] = x1[27];
  544.     x2[208] = x1[28];
  545.     x2[224] = x1[29];
  546.     x2[240] = x1[30];
  547.     x2[256] = x1[31];
  548.  
  549.     // insert V[49-63] (== new_v[30-16]) into other v:
  550.     x2[272] = x1[30];
  551.     x2[288] = x1[29];
  552.     x2[304] = x1[28];
  553.     x2[320] = x1[27];
  554.     x2[336] = x1[26];
  555.     x2[352] = x1[25];
  556.     x2[368] = x1[24];
  557.     x2[384] = x1[23];
  558.     x2[400] = x1[22];
  559.     x2[416] = x1[21];
  560.     x2[432] = x1[20];
  561.     x2[448] = x1[19];
  562.     x2[464] = x1[18];
  563.     x2[480] = x1[17];
  564.     x2[496] = x1[16];
  565.     }
  566. }
  567.  
  568. void SynthesisFilter::compute_pcm_samples(Obuffer *buffer)
  569. {
  570.     // scoping variables makes it easier to optimize for the compiler
  571.     register real *vp = actual_v;
  572.  
  573.     // switch depending on the value for actual_write_pos
  574.     switch (actual_write_pos) {
  575.         case 0: {
  576.             // fat chance of having this loop unroll
  577.             for( register const real *dp = d;
  578.                      dp < d + (32 * 16);
  579.                      dp += 16, vp += 16 ) {
  580.                 register real pcm_sample;
  581.  
  582.                 pcm_sample = (real)(((vp[0] * dp[0]) +
  583.                     (vp[15] * dp[1]) +
  584.                     (vp[14] * dp[2]) +
  585.                     (vp[13] * dp[3]) +
  586.                     (vp[12] * dp[4]) +
  587.                     (vp[11] * dp[5]) +
  588.                     (vp[10] * dp[6]) +
  589.                     (vp[9] * dp[7]) +
  590.                     (vp[8] * dp[8]) +
  591.                     (vp[7] * dp[9]) +
  592.                     (vp[6] * dp[10]) +
  593.                     (vp[5] * dp[11]) +
  594.                     (vp[4] * dp[12]) +
  595.                     (vp[3] * dp[13]) +
  596.                     (vp[2] * dp[14]) +
  597.                     (vp[1] * dp[15])
  598.                     ) * scalefactor);
  599.  
  600.             buffer->append (channel, clip(pcm_sample));
  601.             } // for
  602.         } break; // case 0:
  603.  
  604.         case 1: {
  605.             // fat chance of having this loop unroll
  606.             for( register const real *dp = d;
  607.                      dp < d + (32 * 16);
  608.                      dp += 16, vp += 16 ) {
  609.                 register real pcm_sample;
  610.  
  611.                 pcm_sample = (real)(((vp[1] * dp[0]) +
  612.                     (vp[0] * dp[1]) +
  613.                     (vp[15] * dp[2]) +
  614.                     (vp[14] * dp[3]) +
  615.                     (vp[13] * dp[4]) +
  616.                     (vp[12] * dp[5]) +
  617.                     (vp[11] * dp[6]) +
  618.                     (vp[10] * dp[7]) +
  619.                     (vp[9] * dp[8]) +
  620.                     (vp[8] * dp[9]) +
  621.                     (vp[7] * dp[10]) +
  622.                     (vp[6] * dp[11]) +
  623.                     (vp[5] * dp[12]) +
  624.                     (vp[4] * dp[13]) +
  625.                     (vp[3] * dp[14]) +
  626.                     (vp[2] * dp[15])
  627.                     ) * scalefactor);
  628.  
  629.             buffer->append (channel, clip(pcm_sample));
  630.          } // for
  631.         } break; // case 1:
  632.  
  633.         case 2: {
  634.             // fat chance of having this loop unroll
  635.             for( register const real *dp = d;
  636.                      dp < d + (32 * 16);
  637.                      dp += 16, vp += 16 ) {
  638.                 register real pcm_sample;
  639.  
  640.                 pcm_sample = (real)(((vp[2] * dp[0]) +
  641.                     (vp[1] * dp[1]) +
  642.                     (vp[0] * dp[2]) +
  643.                     (vp[15] * dp[3]) +
  644.                     (vp[14] * dp[4]) +
  645.                     (vp[13] * dp[5]) +
  646.                     (vp[12] * dp[6]) +
  647.                     (vp[11] * dp[7]) +
  648.                     (vp[10] * dp[8]) +
  649.                     (vp[9] * dp[9]) +
  650.                     (vp[8] * dp[10]) +
  651.                     (vp[7] * dp[11]) +
  652.                     (vp[6] * dp[12]) +
  653.                     (vp[5] * dp[13]) +
  654.                     (vp[4] * dp[14]) +
  655.                     (vp[3] * dp[15])
  656.                     ) * scalefactor);
  657.  
  658.             buffer->append (channel, clip(pcm_sample));
  659.             } // for
  660.         } break; // case 2:
  661.  
  662.         case 3: {
  663.             // fat chance of having this loop unroll
  664.             for( register const real *dp = d;
  665.                      dp < d + (32 * 16);
  666.                      dp += 16, vp += 16 ) {
  667.                 register real pcm_sample;
  668.  
  669.                 pcm_sample = (real)(((vp[3] * dp[0]) +
  670.                     (vp[2] * dp[1]) +
  671.                     (vp[1] * dp[2]) +
  672.                     (vp[0] * dp[3]) +
  673.                     (vp[15] * dp[4]) +
  674.                     (vp[14] * dp[5]) +
  675.                     (vp[13] * dp[6]) +
  676.                     (vp[12] * dp[7]) +
  677.                     (vp[11] * dp[8]) +
  678.                     (vp[10] * dp[9]) +
  679.                     (vp[9] * dp[10]) +
  680.                     (vp[8] * dp[11]) +
  681.                     (vp[7] * dp[12]) +
  682.                     (vp[6] * dp[13]) +
  683.                     (vp[5] * dp[14]) +
  684.                     (vp[4] * dp[15])
  685.                     ) * scalefactor);
  686.  
  687.                 buffer->append (channel, clip(pcm_sample));
  688.             } // for
  689.         } break; // case 3:
  690.  
  691.         case 4: {
  692.             // fat chance of having this loop unroll
  693.             for( register const real *dp = d;
  694.                      dp < d + (32 * 16);
  695.                      dp += 16, vp += 16 ) {
  696.                 register real pcm_sample;
  697.  
  698.                 pcm_sample = (real)(((vp[4] * dp[0]) +
  699.                     (vp[3] * dp[1]) +
  700.                     (vp[2] * dp[2]) +
  701.                     (vp[1] * dp[3]) +
  702.                     (vp[0] * dp[4]) +
  703.                     (vp[15] * dp[5]) +
  704.                     (vp[14] * dp[6]) +
  705.                     (vp[13] * dp[7]) +
  706.                     (vp[12] * dp[8]) +
  707.                     (vp[11] * dp[9]) +
  708.                     (vp[10] * dp[10]) +
  709.                     (vp[9] * dp[11]) +
  710.                     (vp[8] * dp[12]) +
  711.                     (vp[7] * dp[13]) +
  712.                     (vp[6] * dp[14]) +
  713.                     (vp[5] * dp[15])
  714.                     ) * scalefactor);
  715.  
  716.                 buffer->append (channel, clip(pcm_sample));
  717.             } // for
  718.         } break; // case 4:
  719.  
  720.         case 5: {
  721.             // fat chance of having this loop unroll
  722.             for( register const real *dp = d;
  723.                      dp < d + (32 * 16);
  724.                      dp += 16, vp += 16 ) {
  725.                 register real pcm_sample;
  726.  
  727.                 pcm_sample = (real)(((vp[5] * dp[0]) +
  728.                     (vp[4] * dp[1]) +
  729.                     (vp[3] * dp[2]) +
  730.                     (vp[2] * dp[3]) +
  731.                     (vp[1] * dp[4]) +
  732.                     (vp[0] * dp[5]) +
  733.                     (vp[15] * dp[6]) +
  734.                     (vp[14] * dp[7]) +
  735.                     (vp[13] * dp[8]) +
  736.                     (vp[12] * dp[9]) +
  737.                     (vp[11] * dp[10]) +
  738.                     (vp[10] * dp[11]) +
  739.                     (vp[9] * dp[12]) +
  740.                     (vp[8] * dp[13]) +
  741.                     (vp[7] * dp[14]) +
  742.                     (vp[6] * dp[15])
  743.                     ) * scalefactor);
  744.  
  745.                 buffer->append (channel, clip(pcm_sample));
  746.             } // for
  747.         } break; // case 5:
  748.  
  749.         case 6: {
  750.             // fat chance of having this loop unroll
  751.             for( register const real *dp = d;
  752.                      dp < d + (32 * 16);
  753.                      dp += 16, vp += 16 ) {
  754.                 register real pcm_sample;
  755.  
  756.                 pcm_sample = (real)(((vp[6] * dp[0]) +
  757.                     (vp[5] * dp[1]) +
  758.                     (vp[4] * dp[2]) +
  759.                     (vp[3] * dp[3]) +
  760.                     (vp[2] * dp[4]) +
  761.                     (vp[1] * dp[5]) +
  762.                     (vp[0] * dp[6]) +
  763.                     (vp[15] * dp[7]) +
  764.                     (vp[14] * dp[8]) +
  765.                     (vp[13] * dp[9]) +
  766.                     (vp[12] * dp[10]) +
  767.                     (vp[11] * dp[11]) +
  768.                     (vp[10] * dp[12]) +
  769.                     (vp[9] * dp[13]) +
  770.                     (vp[8] * dp[14]) +
  771.                     (vp[7] * dp[15])
  772.                     ) * scalefactor);
  773.  
  774.             buffer->append (channel, clip(pcm_sample));
  775.             } // for
  776.         } break; // case 6:
  777.  
  778.         case 7: {
  779.             // fat chance of having this loop unroll
  780.             for( register const real *dp = d;
  781.                      dp < d + (32 * 16);
  782.                      dp += 16, vp += 16 ) {
  783.                 register real pcm_sample;
  784.  
  785.                 pcm_sample = (real)(((vp[7] * dp[0]) +
  786.                     (vp[6] * dp[1]) +
  787.                     (vp[5] * dp[2]) +
  788.                     (vp[4] * dp[3]) +
  789.                     (vp[3] * dp[4]) +
  790.                     (vp[2] * dp[5]) +
  791.                     (vp[1] * dp[6]) +
  792.                     (vp[0] * dp[7]) +
  793.                     (vp[15] * dp[8]) +
  794.                     (vp[14] * dp[9]) +
  795.                     (vp[13] * dp[10]) +
  796.                     (vp[12] * dp[11]) +
  797.                     (vp[11] * dp[12]) +
  798.                     (vp[10] * dp[13]) +
  799.                     (vp[9] * dp[14]) +
  800.                     (vp[8] * dp[15])
  801.                     ) * scalefactor);
  802.  
  803.             buffer->append (channel, clip(pcm_sample));
  804.             } // for
  805.         } break; // case 7:
  806.  
  807.         case 8: {
  808.             // fat chance of having this loop unroll
  809.             for( register const real *dp = d;
  810.                      dp < d + (32 * 16);
  811.                      dp += 16, vp += 16 ) {
  812.                 register real pcm_sample;
  813.  
  814.                 pcm_sample = (real)(((vp[8] * dp[0]) +
  815.                     (vp[7] * dp[1]) +
  816.                     (vp[6] * dp[2]) +
  817.                     (vp[5] * dp[3]) +
  818.                     (vp[4] * dp[4]) +
  819.                     (vp[3] * dp[5]) +
  820.                     (vp[2] * dp[6]) +
  821.                     (vp[1] * dp[7]) +
  822.                     (vp[0] * dp[8]) +
  823.                     (vp[15] * dp[9]) +
  824.                     (vp[14] * dp[10]) +
  825.                     (vp[13] * dp[11]) +
  826.                     (vp[12] * dp[12]) +
  827.                     (vp[11] * dp[13]) +
  828.                     (vp[10] * dp[14]) +
  829.                     (vp[9] * dp[15])
  830.                     ) * scalefactor);
  831.  
  832.             buffer->append (channel, clip(pcm_sample));
  833.             } // for
  834.         } break; // case 8:
  835.  
  836.         case 9: {
  837.             // fat chance of having this loop unroll
  838.             for( register const real *dp = d;
  839.                      dp < d + (32 * 16);
  840.                      dp += 16, vp += 16 ) {
  841.                 register real pcm_sample;
  842.  
  843.                 pcm_sample = (real)(((vp[9] * dp[0]) +
  844.                     (vp[8] * dp[1]) +
  845.                     (vp[7] * dp[2]) +
  846.                     (vp[6] * dp[3]) +
  847.                     (vp[5] * dp[4]) +
  848.                     (vp[4] * dp[5]) +
  849.                     (vp[3] * dp[6]) +
  850.                     (vp[2] * dp[7]) +
  851.                     (vp[1] * dp[8]) +
  852.                     (vp[0] * dp[9]) +
  853.                     (vp[15] * dp[10]) +
  854.                     (vp[14] * dp[11]) +
  855.                     (vp[13] * dp[12]) +
  856.                     (vp[12] * dp[13]) +
  857.                     (vp[11] * dp[14]) +
  858.                     (vp[10] * dp[15])
  859.                     ) * scalefactor);
  860.  
  861.             buffer->append (channel, clip(pcm_sample));
  862.             } // for
  863.         } break; // case 9:
  864.  
  865.         case 10: {
  866.             // fat chance of having this loop unroll
  867.             for( register const real *dp = d;
  868.                      dp < d + (32 * 16);
  869.                      dp += 16, vp += 16 ) {
  870.                 register real pcm_sample;
  871.  
  872.                 pcm_sample = (real)(((vp[10] * dp[0]) +
  873.                     (vp[9] * dp[1]) +
  874.                     (vp[8] * dp[2]) +
  875.                     (vp[7] * dp[3]) +
  876.                     (vp[6] * dp[4]) +
  877.                     (vp[5] * dp[5]) +
  878.                     (vp[4] * dp[6]) +
  879.                     (vp[3] * dp[7]) +
  880.                     (vp[2] * dp[8]) +
  881.                     (vp[1] * dp[9]) +
  882.                     (vp[0] * dp[10]) +
  883.                     (vp[15] * dp[11]) +
  884.                     (vp[14] * dp[12]) +
  885.                     (vp[13] * dp[13]) +
  886.                     (vp[12] * dp[14]) +
  887.                     (vp[11] * dp[15])
  888.                     ) * scalefactor);
  889.  
  890.             buffer->append (channel, clip(pcm_sample));
  891.             } // for
  892.         } break; // case 10:
  893.  
  894.         case 11: {
  895.             // fat chance of having this loop unroll
  896.             for( register const real *dp = d;
  897.                      dp < d + (32 * 16);
  898.                      dp += 16, vp += 16 ) {
  899.                 register real pcm_sample;
  900.  
  901.                 pcm_sample = (real)(((vp[11] * dp[0]) +
  902.                     (vp[10] * dp[1]) +
  903.                     (vp[9] * dp[2]) +
  904.                     (vp[8] * dp[3]) +
  905.                     (vp[7] * dp[4]) +
  906.                     (vp[6] * dp[5]) +
  907.                     (vp[5] * dp[6]) +
  908.                     (vp[4] * dp[7]) +
  909.                     (vp[3] * dp[8]) +
  910.                     (vp[2] * dp[9]) +
  911.                     (vp[1] * dp[10]) +
  912.                     (vp[0] * dp[11]) +
  913.                     (vp[15] * dp[12]) +
  914.                     (vp[14] * dp[13]) +
  915.                     (vp[13] * dp[14]) +
  916.                     (vp[12] * dp[15])
  917.                     ) * scalefactor);
  918.  
  919.             buffer->append (channel, clip(pcm_sample));
  920.             } // for
  921.         } break; // case 11:
  922.  
  923.         case 12: {
  924.             // fat chance of having this loop unroll
  925.             for( register const real *dp = d;
  926.                      dp < d + (32 * 16);
  927.                      dp += 16, vp += 16 ) {
  928.                 register real pcm_sample;
  929.  
  930.                 pcm_sample = (real)(((vp[12] * dp[0]) +
  931.                     (vp[11] * dp[1]) +
  932.                     (vp[10] * dp[2]) +
  933.                     (vp[9] * dp[3]) +
  934.                     (vp[8] * dp[4]) +
  935.                     (vp[7] * dp[5]) +
  936.                     (vp[6] * dp[6]) +
  937.                     (vp[5] * dp[7]) +
  938.                     (vp[4] * dp[8]) +
  939.                     (vp[3] * dp[9]) +
  940.                     (vp[2] * dp[10]) +
  941.                     (vp[1] * dp[11]) +
  942.                     (vp[0] * dp[12]) +
  943.                     (vp[15] * dp[13]) +
  944.                     (vp[14] * dp[14]) +
  945.                     (vp[13] * dp[15])
  946.                     ) * scalefactor);
  947.  
  948.             buffer->append (channel, clip(pcm_sample));
  949.             } // for
  950.         } break; // case 12:
  951.  
  952.         case 13: {
  953.             // fat chance of having this loop unroll
  954.             for( register const real *dp = d;
  955.                      dp < d + (32 * 16);
  956.                      dp += 16, vp += 16 ) {
  957.                 register real pcm_sample;
  958.  
  959.                 pcm_sample = (real)(((vp[13] * dp[0]) +
  960.                     (vp[12] * dp[1]) +
  961.                     (vp[11] * dp[2]) +
  962.                     (vp[10] * dp[3]) +
  963.                     (vp[9] * dp[4]) +
  964.                     (vp[8] * dp[5]) +
  965.                     (vp[7] * dp[6]) +
  966.                     (vp[6] * dp[7]) +
  967.                     (vp[5] * dp[8]) +
  968.                     (vp[4] * dp[9]) +
  969.                     (vp[3] * dp[10]) +
  970.                     (vp[2] * dp[11]) +
  971.                     (vp[1] * dp[12]) +
  972.                     (vp[0] * dp[13]) +
  973.                     (vp[15] * dp[14]) +
  974.                     (vp[14] * dp[15])
  975.                     ) * scalefactor);
  976.  
  977.             buffer->append (channel, clip(pcm_sample));
  978.             } // for
  979.         } break; // case 13:
  980.  
  981.         case 14: {
  982.             // fat chance of having this loop unroll
  983.             for( register const real *dp = d;
  984.                      dp < d + (32 * 16);
  985.                      dp += 16, vp += 16 ) {
  986.                 register real pcm_sample;
  987.  
  988.                 pcm_sample = (real)(((vp[14] * dp[0]) +
  989.                     (vp[13] * dp[1]) +
  990.                     (vp[12] * dp[2]) +
  991.                     (vp[11] * dp[3]) +
  992.                     (vp[10] * dp[4]) +
  993.                     (vp[9] * dp[5]) +
  994.                     (vp[8] * dp[6]) +
  995.                     (vp[7] * dp[7]) +
  996.                     (vp[6] * dp[8]) +
  997.                     (vp[5] * dp[9]) +
  998.                     (vp[4] * dp[10]) +
  999.                     (vp[3] * dp[11]) +
  1000.                     (vp[2] * dp[12]) +
  1001.                     (vp[1] * dp[13]) +
  1002.                     (vp[0] * dp[14]) +
  1003.                     (vp[15] * dp[15])
  1004.                     ) * scalefactor);
  1005.  
  1006.             buffer->append (channel, clip(pcm_sample));
  1007.             } // for
  1008.         } break; // case 14:
  1009.  
  1010.         case 15: {
  1011.             // fat chance of having this loop unroll
  1012.             for( register const real *dp = d;
  1013.                      dp < d + (32 * 16);
  1014.                      dp += 16, vp += 16 ) {
  1015.                 register real pcm_sample;
  1016.  
  1017.                 pcm_sample = (real)(((vp[15] * dp[0]) +
  1018.                     (vp[14] * dp[1]) +
  1019.                     (vp[13] * dp[2]) +
  1020.                     (vp[12] * dp[3]) +
  1021.                     (vp[11] * dp[4]) +
  1022.                     (vp[10] * dp[5]) +
  1023.                     (vp[9] * dp[6]) +
  1024.                     (vp[8] * dp[7]) +
  1025.                     (vp[7] * dp[8]) +
  1026.                     (vp[6] * dp[9]) +
  1027.                     (vp[5] * dp[10]) +
  1028.                     (vp[4] * dp[11]) +
  1029.                     (vp[3] * dp[12]) +
  1030.                     (vp[2] * dp[13]) +
  1031.                     (vp[1] * dp[14]) +
  1032.                     (vp[0] * dp[15])
  1033.                     ) * scalefactor);
  1034.  
  1035.             buffer->append (channel, clip(pcm_sample));
  1036.             } // for
  1037.         } break; // case 15:
  1038.     }; // switch (actual_write_pos)
  1039. }
  1040.  
  1041. void SynthesisFilter::calculate_pcm_samples(Obuffer *buffer)
  1042. {
  1043.     compute_new_v();
  1044.     compute_pcm_samples(buffer);
  1045.  
  1046.    actual_write_pos = (actual_write_pos + 1) & 0xf;
  1047.     actual_v = (actual_v == v1) ? v2 : v1;
  1048.  
  1049.     // initialize samples[]:
  1050.   for (register real *floatp = samples + 32; floatp > samples; )
  1051.      *--floatp = 0.0f;
  1052. }
  1053.