Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2017 Google Inc.
      2    Written by Andrew Allen */
      3 /*
      4    Redistribution and use in source and binary forms, with or without
      5    modification, are permitted provided that the following conditions
      6    are met:
      7 
      8    - Redistributions of source code must retain the above copyright
      9    notice, this list of conditions and the following disclaimer.
     10 
     11    - Redistributions in binary form must reproduce the above copyright
     12    notice, this list of conditions and the following disclaimer in the
     13    documentation and/or other materials provided with the distribution.
     14 
     15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 */
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include "config.h"
     30 #endif
     31 
     32 #include "arch.h"
     33 #include "float_cast.h"
     34 #include "opus_private.h"
     35 #include "opus_defines.h"
     36 #include "mapping_matrix.h"
     37 
     38 #define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
     39 
     40 opus_int32 mapping_matrix_get_size(int rows, int cols)
     41 {
     42   opus_int32 size;
     43 
     44   /* Mapping Matrix must only support up to 255 channels in or out.
     45    * Additionally, the total cell count must be <= 65004 octets in order
     46    * for the matrix to be stored in an OGG header.
     47    */
     48   if (rows > 255 || cols > 255)
     49       return 0;
     50   size = rows * (opus_int32)cols * sizeof(opus_int16);
     51   if (size > 65004)
     52     return 0;
     53 
     54   return align(sizeof(MappingMatrix)) + align(size);
     55 }
     56 
     57 opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
     58 {
     59   /* void* cast avoids clang -Wcast-align warning */
     60   return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix)));
     61 }
     62 
     63 void mapping_matrix_init(MappingMatrix * const matrix,
     64   int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size)
     65 {
     66   int i;
     67   opus_int16 *ptr;
     68 
     69 #if !defined(ENABLE_ASSERTIONS)
     70   (void)data_size;
     71 #endif
     72   celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16)));
     73 
     74   matrix->rows = rows;
     75   matrix->cols = cols;
     76   matrix->gain = gain;
     77   ptr = mapping_matrix_get_data(matrix);
     78   for (i = 0; i < rows * cols; i++)
     79   {
     80      ptr[i] = data[i];
     81   }
     82 }
     83 
     84 #ifndef DISABLE_FLOAT_API
     85 void mapping_matrix_multiply_channel_in_float(
     86     const MappingMatrix *matrix,
     87     const float *input,
     88     int input_rows,
     89     opus_val16 *output,
     90     int output_row,
     91     int output_rows,
     92     int frame_size)
     93 {
     94   /* Matrix data is ordered col-wise. */
     95   opus_int16* matrix_data;
     96   int i, col;
     97 
     98   celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
     99 
    100   matrix_data = mapping_matrix_get_data(matrix);
    101 
    102   for (i = 0; i < frame_size; i++)
    103   {
    104     float tmp = 0;
    105     for (col = 0; col < input_rows; col++)
    106     {
    107       tmp +=
    108         matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
    109         input[MATRIX_INDEX(input_rows, col, i)];
    110     }
    111 #if defined(FIXED_POINT)
    112     output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp);
    113 #else
    114     output[output_rows * i] = (1/32768.f)*tmp;
    115 #endif
    116   }
    117 }
    118 
    119 void mapping_matrix_multiply_channel_out_float(
    120     const MappingMatrix *matrix,
    121     const opus_val16 *input,
    122     int input_row,
    123     int input_rows,
    124     float *output,
    125     int output_rows,
    126     int frame_size
    127 )
    128 {
    129   /* Matrix data is ordered col-wise. */
    130   opus_int16* matrix_data;
    131   int i, row;
    132   float input_sample;
    133 
    134   celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
    135 
    136   matrix_data = mapping_matrix_get_data(matrix);
    137 
    138   for (i = 0; i < frame_size; i++)
    139   {
    140 #if defined(FIXED_POINT)
    141     input_sample = (1/32768.f)*input[input_rows * i];
    142 #else
    143     input_sample = input[input_rows * i];
    144 #endif
    145     for (row = 0; row < output_rows; row++)
    146     {
    147       float tmp =
    148         (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
    149         input_sample;
    150       output[MATRIX_INDEX(output_rows, row, i)] += tmp;
    151     }
    152   }
    153 }
    154 #endif /* DISABLE_FLOAT_API */
    155 
    156 void mapping_matrix_multiply_channel_in_short(
    157     const MappingMatrix *matrix,
    158     const opus_int16 *input,
    159     int input_rows,
    160     opus_val16 *output,
    161     int output_row,
    162     int output_rows,
    163     int frame_size)
    164 {
    165   /* Matrix data is ordered col-wise. */
    166   opus_int16* matrix_data;
    167   int i, col;
    168 
    169   celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
    170 
    171   matrix_data = mapping_matrix_get_data(matrix);
    172 
    173   for (i = 0; i < frame_size; i++)
    174   {
    175     opus_val32 tmp = 0;
    176     for (col = 0; col < input_rows; col++)
    177     {
    178 #if defined(FIXED_POINT)
    179       tmp +=
    180         ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
    181         (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8;
    182 #else
    183       tmp +=
    184         matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
    185         input[MATRIX_INDEX(input_rows, col, i)];
    186 #endif
    187     }
    188 #if defined(FIXED_POINT)
    189     output[output_rows * i] = (opus_int16)((tmp + 64) >> 7);
    190 #else
    191     output[output_rows * i] = (1/(32768.f*32768.f))*tmp;
    192 #endif
    193   }
    194 }
    195 
    196 void mapping_matrix_multiply_channel_out_short(
    197     const MappingMatrix *matrix,
    198     const opus_val16 *input,
    199     int input_row,
    200     int input_rows,
    201     opus_int16 *output,
    202     int output_rows,
    203     int frame_size)
    204 {
    205   /* Matrix data is ordered col-wise. */
    206   opus_int16* matrix_data;
    207   int i, row;
    208   opus_int32 input_sample;
    209 
    210   celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
    211 
    212   matrix_data = mapping_matrix_get_data(matrix);
    213 
    214   for (i = 0; i < frame_size; i++)
    215   {
    216 #if defined(FIXED_POINT)
    217     input_sample = (opus_int32)input[input_rows * i];
    218 #else
    219     input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]);
    220 #endif
    221     for (row = 0; row < output_rows; row++)
    222     {
    223       opus_int32 tmp =
    224         (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
    225         input_sample;
    226       output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15;
    227     }
    228   }
    229 }
    230 
    231 const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 };
    232 const opus_int16 mapping_matrix_foa_mixing_data[36] = {
    233      16384,      0, -16384,  23170,      0,      0,  16384,  23170,
    234      16384,      0,      0,      0,  16384,      0, -16384, -23170,
    235          0,      0,  16384, -23170,  16384,      0,      0,      0,
    236          0,      0,      0,      0,  32767,      0,      0,      0,
    237          0,      0,      0,  32767
    238 };
    239 
    240 const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 };
    241 const opus_int16 mapping_matrix_soa_mixing_data[121] = {
    242      10923,   7723,  13377, -13377,  11585,   9459,   7723, -16384,
    243      -6689,      0,      0,  10923,   7723,  13377,  13377, -11585,
    244       9459,   7723,  16384,  -6689,      0,      0,  10923, -15447,
    245      13377,      0,      0, -18919,   7723,      0,  13377,      0,
    246          0,  10923,   7723, -13377, -13377,  11585,  -9459,   7723,
    247      16384,  -6689,      0,      0,  10923,  -7723,      0,  13377,
    248     -16384,      0, -15447,      0,   9459,      0,      0,  10923,
    249      -7723,      0, -13377,  16384,      0, -15447,      0,   9459,
    250          0,      0,  10923,  15447,      0,      0,      0,      0,
    251     -15447,      0, -18919,      0,      0,  10923,   7723, -13377,
    252      13377, -11585,  -9459,   7723, -16384,  -6689,      0,      0,
    253      10923, -15447, -13377,      0,      0,  18919,   7723,      0,
    254      13377,      0,      0,      0,      0,      0,      0,      0,
    255          0,      0,      0,      0,  32767,      0,      0,      0,
    256          0,      0,      0,      0,      0,      0,      0,      0,
    257      32767
    258 };
    259 
    260 const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 };
    261 const opus_int16 mapping_matrix_toa_mixing_data[324] = {
    262       8208,      0,   -881,  14369,      0,      0,  -8192,  -4163,
    263      13218,      0,      0,      0,  11095,  -8836,  -6218,  14833,
    264          0,      0,   8208, -10161,    881,  10161, -13218,  -2944,
    265      -8192,   2944,      0, -10488,  -6218,   6248, -11095,  -6248,
    266          0, -10488,      0,      0,   8208,  10161,    881, -10161,
    267     -13218,   2944,  -8192,  -2944,      0,  10488,  -6218,  -6248,
    268     -11095,   6248,      0,  10488,      0,      0,   8176,   5566,
    269     -11552,   5566,   9681, -11205,   8192, -11205,      0,   4920,
    270     -15158,   9756,  -3334,   9756,      0,  -4920,      0,      0,
    271       8176,   7871,  11552,      0,      0,  15846,   8192,      0,
    272      -9681,  -6958,      0,  13797,   3334,      0, -15158,      0,
    273          0,      0,   8176,      0,  11552,   7871,      0,      0,
    274       8192,  15846,   9681,      0,      0,      0,   3334,  13797,
    275      15158,   6958,      0,      0,   8176,   5566, -11552,  -5566,
    276      -9681, -11205,   8192,  11205,      0,   4920,  15158,   9756,
    277      -3334,  -9756,      0,   4920,      0,      0,   8208,  14369,
    278       -881,      0,      0,  -4163,  -8192,      0, -13218, -14833,
    279          0,  -8836,  11095,      0,   6218,      0,      0,      0,
    280       8208,  10161,    881,  10161,  13218,   2944,  -8192,   2944,
    281          0,  10488,   6218,  -6248, -11095,  -6248,      0, -10488,
    282          0,      0,   8208, -14369,   -881,      0,      0,   4163,
    283      -8192,      0, -13218,  14833,      0,   8836,  11095,      0,
    284       6218,      0,      0,      0,   8208,      0,   -881, -14369,
    285          0,      0,  -8192,   4163,  13218,      0,      0,      0,
    286      11095,   8836,  -6218, -14833,      0,      0,   8176,  -5566,
    287     -11552,   5566,  -9681,  11205,   8192, -11205,      0,  -4920,
    288      15158,  -9756,  -3334,   9756,      0,  -4920,      0,      0,
    289       8176,      0,  11552,  -7871,      0,      0,   8192, -15846,
    290       9681,      0,      0,      0,   3334, -13797,  15158,  -6958,
    291          0,      0,   8176,  -7871,  11552,      0,      0, -15846,
    292       8192,      0,  -9681,   6958,      0, -13797,   3334,      0,
    293     -15158,      0,      0,      0,   8176,  -5566, -11552,  -5566,
    294       9681,  11205,   8192,  11205,      0,  -4920, -15158,  -9756,
    295      -3334,  -9756,      0,   4920,      0,      0,   8208, -10161,
    296        881, -10161,  13218,  -2944,  -8192,  -2944,      0, -10488,
    297       6218,   6248, -11095,   6248,      0,  10488,      0,      0,
    298          0,      0,      0,      0,      0,      0,      0,      0,
    299          0,      0,      0,      0,      0,      0,      0,      0,
    300      32767,      0,      0,      0,      0,      0,      0,      0,
    301          0,      0,      0,      0,      0,      0,      0,      0,
    302          0,      0,      0,  32767
    303 };
    304 
    305 const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 };
    306 const opus_int16 mapping_matrix_foa_demixing_data[36] = {
    307      16384,  16384,  16384,  16384,      0,      0,      0,  23170,
    308          0, -23170,      0,      0, -16384,  16384, -16384,  16384,
    309          0,      0,  23170,      0, -23170,      0,      0,      0,
    310          0,      0,      0,      0,  32767,      0,      0,      0,
    311          0,      0,      0,  32767
    312 };
    313 
    314 const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 };
    315 const opus_int16 mapping_matrix_soa_demixing_data[121] = {
    316       2771,   2771,   2771,   2771,   2771,   2771,   2771,   2771,
    317       2771,      0,      0,  10033,  10033, -20066,  10033,  14189,
    318      14189, -28378,  10033, -20066,      0,      0,   3393,   3393,
    319       3393,  -3393,      0,      0,      0,  -3393,  -3393,      0,
    320          0, -17378,  17378,      0, -17378, -24576,  24576,      0,
    321      17378,      0,      0,      0, -14189,  14189,      0, -14189,
    322     -28378,  28378,      0,  14189,      0,      0,      0,   2399,
    323       2399,  -4799,  -2399,      0,      0,      0,  -2399,   4799,
    324          0,      0,   1959,   1959,   1959,   1959,  -3918,  -3918,
    325      -3918,   1959,   1959,      0,      0,  -4156,   4156,      0,
    326       4156,      0,      0,      0,  -4156,      0,      0,      0,
    327       8192,   8192, -16384,   8192,  16384,  16384, -32768,   8192,
    328     -16384,      0,      0,      0,      0,      0,      0,      0,
    329          0,      0,      0,      0,   8312,      0,      0,      0,
    330          0,      0,      0,      0,      0,      0,      0,      0,
    331       8312
    332 };
    333 
    334 const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 };
    335 const opus_int16 mapping_matrix_toa_demixing_data[324] = {
    336       8192,   8192,   8192,   8192,   8192,   8192,   8192,   8192,
    337       8192,   8192,   8192,   8192,   8192,   8192,   8192,   8192,
    338          0,      0,      0,  -9779,   9779,   6263,   8857,      0,
    339       6263,  13829,   9779, -13829,      0,  -6263,      0,  -8857,
    340      -6263,  -9779,      0,      0,  -3413,   3413,   3413, -11359,
    341      11359,  11359, -11359,  -3413,   3413,  -3413,  -3413, -11359,
    342      11359,  11359, -11359,   3413,      0,      0,  13829,   9779,
    343      -9779,   6263,      0,   8857,  -6263,      0,   9779,      0,
    344     -13829,   6263,  -8857,      0,  -6263,  -9779,      0,      0,
    345          0, -15617, -15617,   6406,      0,      0,  -6406,      0,
    346      15617,      0,      0,  -6406,      0,      0,   6406,  15617,
    347          0,      0,      0,  -5003,   5003, -10664,  15081,      0,
    348     -10664,  -7075,   5003,   7075,      0,  10664,      0, -15081,
    349      10664,  -5003,      0,      0,  -8176,  -8176,  -8176,   8208,
    350       8208,   8208,   8208,  -8176,  -8176,  -8176,  -8176,   8208,
    351       8208,   8208,   8208,  -8176,      0,      0,  -7075,   5003,
    352      -5003, -10664,      0,  15081,  10664,      0,   5003,      0,
    353       7075, -10664, -15081,      0,  10664,  -5003,      0,      0,
    354      15617,      0,      0,      0,  -6406,   6406,      0, -15617,
    355          0, -15617,  15617,      0,   6406,  -6406,      0,      0,
    356          0,      0,      0, -11393,  11393,   2993,  -4233,      0,
    357       2993, -16112,  11393,  16112,      0,  -2993,      0,   4233,
    358      -2993, -11393,      0,      0,      0,  -9974,  -9974, -13617,
    359          0,      0,  13617,      0,   9974,      0,      0,  13617,
    360          0,      0, -13617,   9974,      0,      0,      0,   5579,
    361      -5579,  10185,  14403,      0,  10185,  -7890,  -5579,   7890,
    362          0, -10185,      0, -14403, -10185,   5579,      0,      0,
    363      11826, -11826, -11826,   -901,    901,    901,   -901,  11826,
    364     -11826,  11826,  11826,   -901,    901,    901,   -901, -11826,
    365          0,      0,  -7890,  -5579,   5579,  10185,      0,  14403,
    366     -10185,      0,  -5579,      0,   7890,  10185, -14403,      0,
    367     -10185,   5579,      0,      0,  -9974,      0,      0,      0,
    368     -13617,  13617,      0,   9974,      0,   9974,  -9974,      0,
    369      13617, -13617,      0,      0,      0,      0,  16112, -11393,
    370      11393,  -2993,      0,   4233,   2993,      0, -11393,      0,
    371     -16112,  -2993,  -4233,      0,   2993,  11393,      0,      0,
    372          0,      0,      0,      0,      0,      0,      0,      0,
    373          0,      0,      0,      0,      0,      0,      0,      0,
    374      32767,      0,      0,      0,      0,      0,      0,      0,
    375          0,      0,      0,      0,      0,      0,      0,      0,
    376          0,      0,      0,  32767
    377 };
    378 
    379