diff --git a/webrtc/common_audio/common_audio.gyp b/webrtc/common_audio/common_audio.gyp index 59ebfacdf0..bec3980707 100644 --- a/webrtc/common_audio/common_audio.gyp +++ b/webrtc/common_audio/common_audio.gyp @@ -45,6 +45,7 @@ 'signal_processing/auto_corr_to_refl_coef.c', 'signal_processing/auto_correlation.c', 'signal_processing/complex_fft.c', + 'signal_processing/complex_fft_tables.h', 'signal_processing/complex_bit_reverse.c', 'signal_processing/copy_set_operations.c', 'signal_processing/cross_correlation.c', @@ -115,9 +116,18 @@ }], ['target_arch=="mipsel"', { 'sources': [ + 'signal_processing/complex_bit_reverse_mips.c', + 'signal_processing/complex_fft_mips.c', + 'signal_processing/downsample_fast_mips.c', + 'signal_processing/filter_ar_fast_q12_mips.c', 'signal_processing/min_max_operations_mips.c', 'signal_processing/resample_by_2_mips.c', ], + 'sources!': [ + 'signal_processing/complex_bit_reverse.c', + 'signal_processing/complex_fft.c', + 'signal_processing/filter_ar_fast_q12.c', + ], }], ], # conditions # Ignore warning on shift operator promotion. diff --git a/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c b/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c new file mode 100644 index 0000000000..96bd1fc06f --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_bit_reverse_mips.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +static int16_t coefTable_7[] = { + 4, 256, 8, 128, 12, 384, 16, 64, + 20, 320, 24, 192, 28, 448, 36, 288, + 40, 160, 44, 416, 48, 96, 52, 352, + 56, 224, 60, 480, 68, 272, 72, 144, + 76, 400, 84, 336, 88, 208, 92, 464, + 100, 304, 104, 176, 108, 432, 116, 368, + 120, 240, 124, 496, 132, 264, 140, 392, + 148, 328, 152, 200, 156, 456, 164, 296, + 172, 424, 180, 360, 184, 232, 188, 488, + 196, 280, 204, 408, 212, 344, 220, 472, + 228, 312, 236, 440, 244, 376, 252, 504, + 268, 388, 276, 324, 284, 452, 300, 420, + 308, 356, 316, 484, 332, 404, 348, 468, + 364, 436, 380, 500, 412, 460, 444, 492 +}; + +static int16_t coefTable_8[] = { + 4, 512, 8, 256, 12, 768, 16, 128, + 20, 640, 24, 384, 28, 896, 32, 64, + 36, 576, 40, 320, 44, 832, 48, 192, + 52, 704, 56, 448, 60, 960, 68, 544, + 72, 288, 76, 800, 80, 160, 84, 672, + 88, 416, 92, 928, 100, 608, 104, 352, + 108, 864, 112, 224, 116, 736, 120, 480, + 124, 992, 132, 528, 136, 272, 140, 784, + 148, 656, 152, 400, 156, 912, 164, 592, + 168, 336, 172, 848, 176, 208, 180, 720, + 184, 464, 188, 976, 196, 560, 200, 304, + 204, 816, 212, 688, 216, 432, 220, 944, + 228, 624, 232, 368, 236, 880, 244, 752, + 248, 496, 252, 1008, 260, 520, 268, 776, + 276, 648, 280, 392, 284, 904, 292, 584, + 296, 328, 300, 840, 308, 712, 312, 456, + 316, 968, 324, 552, 332, 808, 340, 680, + 344, 424, 348, 936, 356, 616, 364, 872, + 372, 744, 376, 488, 380, 1000, 388, 536, + 396, 792, 404, 664, 412, 920, 420, 600, + 428, 856, 436, 728, 440, 472, 444, 984, + 452, 568, 460, 824, 468, 696, 476, 952, + 484, 632, 492, 888, 500, 760, 508, 1016, + 524, 772, 532, 644, 540, 900, 548, 580, + 556, 836, 564, 708, 572, 964, 588, 804, + 596, 676, 604, 932, 620, 868, 628, 740, + 636, 996, 652, 788, 668, 916, 684, 852, + 692, 724, 700, 980, 716, 820, 732, 948, + 748, 884, 764, 1012, 796, 908, 812, 844, + 828, 972, 860, 940, 892, 1004, 956, 988 +}; + +void WebRtcSpl_ComplexBitReverse(int16_t frfi[], int stages) { + int l; + int16_t tr, ti; + int32_t tmp1, tmp2, tmp3, tmp4; + int32_t* ptr_i; + int32_t* ptr_j; + + if (stages == 8) { + int16_t* pcoeftable_8 = coefTable_8; + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[l], $zero, 120 \n\t" + "1: \n\t" + "addiu %[l], %[l], -4 \n\t" + "lh %[tr], 0(%[pcoeftable_8]) \n\t" + "lh %[ti], 2(%[pcoeftable_8]) \n\t" + "lh %[tmp3], 4(%[pcoeftable_8]) \n\t" + "lh %[tmp4], 6(%[pcoeftable_8]) \n\t" + "addu %[ptr_i], %[frfi], %[tr] \n\t" + "addu %[ptr_j], %[frfi], %[ti] \n\t" + "addu %[tr], %[frfi], %[tmp3] \n\t" + "addu %[ti], %[frfi], %[tmp4] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "lh %[tmp1], 8(%[pcoeftable_8]) \n\t" + "lh %[tmp2], 10(%[pcoeftable_8]) \n\t" + "lh %[tr], 12(%[pcoeftable_8]) \n\t" + "lh %[ti], 14(%[pcoeftable_8]) \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[frfi], %[tmp2] \n\t" + "addu %[tr], %[frfi], %[tr] \n\t" + "addu %[ti], %[frfi], %[ti] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "bgtz %[l], 1b \n\t" + " addiu %[pcoeftable_8], %[pcoeftable_8], 16 \n\t" + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i), + [ptr_j] "=&r" (ptr_j), [tr] "=&r" (tr), [l] "=&r" (l), + [tmp3] "=&r" (tmp3), [pcoeftable_8] "+r" (pcoeftable_8), + [ti] "=&r" (ti), [tmp4] "=&r" (tmp4) + : [frfi] "r" (frfi) + : "memory" + ); + } else if (stages == 7) { + int16_t* pcoeftable_7 = coefTable_7; + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[l], $zero, 56 \n\t" + "1: \n\t" + "addiu %[l], %[l], -4 \n\t" + "lh %[tr], 0(%[pcoeftable_7]) \n\t" + "lh %[ti], 2(%[pcoeftable_7]) \n\t" + "lh %[tmp3], 4(%[pcoeftable_7]) \n\t" + "lh %[tmp4], 6(%[pcoeftable_7]) \n\t" + "addu %[ptr_i], %[frfi], %[tr] \n\t" + "addu %[ptr_j], %[frfi], %[ti] \n\t" + "addu %[tr], %[frfi], %[tmp3] \n\t" + "addu %[ti], %[frfi], %[tmp4] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "lh %[tmp1], 8(%[pcoeftable_7]) \n\t" + "lh %[tmp2], 10(%[pcoeftable_7]) \n\t" + "lh %[tr], 12(%[pcoeftable_7]) \n\t" + "lh %[ti], 14(%[pcoeftable_7]) \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[frfi], %[tmp2] \n\t" + "addu %[tr], %[frfi], %[tr] \n\t" + "addu %[ti], %[frfi], %[ti] \n\t" + "ulw %[tmp1], 0(%[ptr_i]) \n\t" + "ulw %[tmp2], 0(%[ptr_j]) \n\t" + "ulw %[tmp3], 0(%[tr]) \n\t" + "ulw %[tmp4], 0(%[ti]) \n\t" + "usw %[tmp1], 0(%[ptr_j]) \n\t" + "usw %[tmp2], 0(%[ptr_i]) \n\t" + "usw %[tmp4], 0(%[tr]) \n\t" + "usw %[tmp3], 0(%[ti]) \n\t" + "bgtz %[l], 1b \n\t" + " addiu %[pcoeftable_7], %[pcoeftable_7], 16 \n\t" + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [ptr_i] "=&r" (ptr_i), + [ptr_j] "=&r" (ptr_j), [ti] "=&r" (ti), [tr] "=&r" (tr), + [l] "=&r" (l), [pcoeftable_7] "+r" (pcoeftable_7), + [tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4) + : [frfi] "r" (frfi) + : "memory" + ); + } +} + diff --git a/webrtc/common_audio/signal_processing/complex_fft.c b/webrtc/common_audio/signal_processing/complex_fft.c index 81c78576e2..f352e63da0 100644 --- a/webrtc/common_audio/signal_processing/complex_fft.c +++ b/webrtc/common_audio/signal_processing/complex_fft.c @@ -16,6 +16,7 @@ */ #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/complex_fft_tables.h" #define CFFTSFT 14 #define CFFTRND 1 @@ -24,137 +25,6 @@ #define CIFFTSFT 14 #define CIFFTRND 1 -static const int16_t kSinTable1024[] = { - 0, 201, 402, 603, 804, 1005, 1206, 1406, - 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, - 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, - 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, - 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, - 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, - 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, - 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, - 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, - 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, - 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, - 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, - 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, - 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, - 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, - 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, - 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, - 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, - 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, - 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, - 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, - 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, - 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, - 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, - 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, - 30851, 30918, 30984, 31049, - 31113, 31175, 31236, 31297, - 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, - 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, - 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, - 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, - 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, - 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, - 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, - 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, - 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, - 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, - 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, - 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, - 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, - 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, - 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, - 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, - 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, - 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, - 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, - 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, - 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, - 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, - 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, - 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, - 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, - 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, - 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, - 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, - 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, - 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, - 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, - 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, - 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, - 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, - 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, - 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, - 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, - 1607, 1406, 1206, 1005, 804, 603, 402, 201, - 0, -201, -402, -603, -804, -1005, -1206, -1406, - -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, - -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, - -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, - -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, - -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, - -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, - -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, - -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, - -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, - -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, - -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, - -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, - -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, - -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, - -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, - -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, - -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, - -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, - -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, - -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, - -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, - -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, - -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, - -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, - -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, - -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, - -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, - -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, - -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, - -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, - -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, - -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, - -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, - -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, - -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, - -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, - -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, - -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, - -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, - -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, - -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, - -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, - -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, - -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, - -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, - -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, - -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, - -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, - -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, - -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, - -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, - -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, - -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, - -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, - -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, - -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, - -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, - -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, - -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, - -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, - -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, - -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, - -1607, -1406, -1206, -1005, -804, -603, -402, -201 -}; int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) { diff --git a/webrtc/common_audio/signal_processing/complex_fft_mips.c b/webrtc/common_audio/signal_processing/complex_fft_mips.c new file mode 100644 index 0000000000..46603cb2a4 --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_fft_mips.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "webrtc/common_audio/signal_processing/complex_fft_tables.h" + +#define CFFTSFT 14 +#define CFFTRND 1 +#define CFFTRND2 16384 + +#define CIFFTSFT 14 +#define CIFFTRND 1 + +int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) { + int i = 0; + int l = 0; + int k = 0; + int istep = 0; + int n = 0; + int m = 0; + int32_t wr = 0, wi = 0; + int32_t tmp1 = 0; + int32_t tmp2 = 0; + int32_t tmp3 = 0; + int32_t tmp4 = 0; + int32_t tmp5 = 0; + int32_t tmp6 = 0; + int32_t tmp = 0; + int16_t* ptr_j = NULL; + int16_t* ptr_i = NULL; + + n = 1 << stages; + if (n > 1024) { + return -1; + } + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "addiu %[k], $zero, 10 \n\t" + "addiu %[l], $zero, 1 \n\t" + "3: \n\t" + "sll %[istep], %[l], 1 \n\t" + "move %[m], $zero \n\t" + "sll %[tmp], %[l], 2 \n\t" + "move %[i], $zero \n\t" + "2: \n\t" +#if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addiu %[tmp2], %[tmp3], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t" + "lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t" + "addiu %[ptr_i], %[ptr_j], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lh %[wi], 0(%[ptr_j]) \n\t" + "lh %[wr], 0(%[ptr_i]) \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "1: \n\t" + "sll %[tmp1], %[i], 2 \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[ptr_i], %[tmp] \n\t" + "lh %[tmp6], 0(%[ptr_i]) \n\t" + "lh %[tmp5], 2(%[ptr_i]) \n\t" + "lh %[tmp3], 0(%[ptr_j]) \n\t" + "lh %[tmp4], 2(%[ptr_j]) \n\t" + "addu %[i], %[i], %[istep] \n\t" +#if defined(MIPS_DSP_R2_LE) + "mult %[wr], %[tmp3] \n\t" + "madd %[wi], %[tmp4] \n\t" + "mult $ac1, %[wr], %[tmp4] \n\t" + "msub $ac1, %[wi], %[tmp3] \n\t" + "mflo %[tmp1] \n\t" + "mflo %[tmp2], $ac1 \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "shra_r.w %[tmp1], %[tmp1], 1 \n\t" + "shra_r.w %[tmp2], %[tmp2], 1 \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "shra_r.w %[tmp1], %[tmp1], 15 \n\t" + "shra_r.w %[tmp6], %[tmp6], 15 \n\t" + "shra_r.w %[tmp4], %[tmp4], 15 \n\t" + "shra_r.w %[tmp5], %[tmp5], 15 \n\t" +#else // #if defined(MIPS_DSP_R2_LE) + "mul %[tmp2], %[wr], %[tmp4] \n\t" + "mul %[tmp1], %[wr], %[tmp3] \n\t" + "mul %[tmp4], %[wi], %[tmp4] \n\t" + "mul %[tmp3], %[wi], %[tmp3] \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "addiu %[tmp6], %[tmp6], 16384 \n\t" + "addiu %[tmp5], %[tmp5], 16384 \n\t" + "addu %[tmp1], %[tmp1], %[tmp4] \n\t" + "subu %[tmp2], %[tmp2], %[tmp3] \n\t" + "addiu %[tmp1], %[tmp1], 1 \n\t" + "addiu %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp1], %[tmp1], 1 \n\t" + "sra %[tmp2], %[tmp2], 1 \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "sra %[tmp4], %[tmp4], 15 \n\t" + "sra %[tmp1], %[tmp1], 15 \n\t" + "sra %[tmp6], %[tmp6], 15 \n\t" + "sra %[tmp5], %[tmp5], 15 \n\t" +#endif // #if defined(MIPS_DSP_R2_LE) + "sh %[tmp1], 0(%[ptr_i]) \n\t" + "sh %[tmp6], 2(%[ptr_i]) \n\t" + "sh %[tmp4], 0(%[ptr_j]) \n\t" + "blt %[i], %[n], 1b \n\t" + " sh %[tmp5], 2(%[ptr_j]) \n\t" + "blt %[m], %[l], 2b \n\t" + " addu %[i], $zero, %[m] \n\t" + "move %[l], %[istep] \n\t" + "blt %[l], %[n], 3b \n\t" + " addiu %[k], %[k], -1 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6), + [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [wi] "=&r" (wi), [wr] "=&r" (wr), + [m] "=&r" (m), [istep] "=&r" (istep), [l] "=&r" (l), [k] "=&r" (k), + [ptr_j] "=&r" (ptr_j), [tmp] "=&r" (tmp) + : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024) + : "hi", "lo", "$ac1hi", "$ac1lo", "memory" + ); + + return 0; +} + +int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) { + int i = 0, l = 0, k = 0; + int istep = 0, n = 0, m = 0; + int scale = 0, shift = 0; + int32_t wr = 0, wi = 0; + int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; + int32_t tmp5 = 0, tmp6 = 0, tmp = 0, tempMax = 0, round2 = 0; + int16_t* ptr_j = NULL; + int16_t* ptr_i = NULL; + + n = 1 << stages; + if (n > 1024) { + return -1; + } + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + + "addiu %[k], $zero, 10 \n\t" + "addiu %[l], $zero, 1 \n\t" + "move %[scale], $zero \n\t" + "3: \n\t" + "addiu %[shift], $zero, 14 \n\t" + "addiu %[round2], $zero, 8192 \n\t" + "move %[ptr_i], %[frfi] \n\t" + "move %[tempMax], $zero \n\t" + "addu %[i], %[n], %[n] \n\t" + "5: \n\t" + "lh %[tmp1], 0(%[ptr_i]) \n\t" + "lh %[tmp2], 2(%[ptr_i]) \n\t" + "lh %[tmp3], 4(%[ptr_i]) \n\t" + "lh %[tmp4], 6(%[ptr_i]) \n\t" +#if defined(MIPS_DSP_R1_LE) + "absq_s.w %[tmp1], %[tmp1] \n\t" + "absq_s.w %[tmp2], %[tmp2] \n\t" + "absq_s.w %[tmp3], %[tmp3] \n\t" + "absq_s.w %[tmp4], %[tmp4] \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp5], %[tmp1], $zero \n\t" + "subu %[tmp6], $zero, %[tmp1] \n\t" + "movn %[tmp1], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp2], $zero \n\t" + "subu %[tmp6], $zero, %[tmp2] \n\t" + "movn %[tmp2], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp3], $zero \n\t" + "subu %[tmp6], $zero, %[tmp3] \n\t" + "movn %[tmp3], %[tmp6], %[tmp5] \n\t" + "slt %[tmp5], %[tmp4], $zero \n\t" + "subu %[tmp6], $zero, %[tmp4] \n\t" + "movn %[tmp4], %[tmp6], %[tmp5] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp5], %[tempMax], %[tmp1] \n\t" + "movn %[tempMax], %[tmp1], %[tmp5] \n\t" + "addiu %[i], %[i], -4 \n\t" + "slt %[tmp5], %[tempMax], %[tmp2] \n\t" + "movn %[tempMax], %[tmp2], %[tmp5] \n\t" + "slt %[tmp5], %[tempMax], %[tmp3] \n\t" + "movn %[tempMax], %[tmp3], %[tmp5] \n\t" + "slt %[tmp5], %[tempMax], %[tmp4] \n\t" + "movn %[tempMax], %[tmp4], %[tmp5] \n\t" + "bgtz %[i], 5b \n\t" + " addiu %[ptr_i], %[ptr_i], 8 \n\t" + "addiu %[tmp1], $zero, 13573 \n\t" + "addiu %[tmp2], $zero, 27146 \n\t" +#if !defined(MIPS32_R2_LE) + "sll %[tempMax], %[tempMax], 16 \n\t" + "sra %[tempMax], %[tempMax], 16 \n\t" +#else // #if !defined(MIPS32_R2_LE) + "seh %[tempMax] \n\t" +#endif // #if !defined(MIPS32_R2_LE) + "slt %[tmp1], %[tmp1], %[tempMax] \n\t" + "slt %[tmp2], %[tmp2], %[tempMax] \n\t" + "addu %[tmp1], %[tmp1], %[tmp2] \n\t" + "addu %[shift], %[shift], %[tmp1] \n\t" + "addu %[scale], %[scale], %[tmp1] \n\t" + "sllv %[round2], %[round2], %[tmp1] \n\t" + "sll %[istep], %[l], 1 \n\t" + "move %[m], $zero \n\t" + "sll %[tmp], %[l], 2 \n\t" + "2: \n\t" +#if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addiu %[tmp2], %[tmp3], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lhx %[wi], %[tmp3](%[kSinTable1024]) \n\t" + "lhx %[wr], %[tmp2](%[kSinTable1024]) \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "sllv %[tmp3], %[m], %[k] \n\t" + "addu %[ptr_j], %[tmp3], %[kSinTable1024] \n\t" + "addiu %[ptr_i], %[ptr_j], 512 \n\t" + "addiu %[m], %[m], 1 \n\t" + "lh %[wi], 0(%[ptr_j]) \n\t" + "lh %[wr], 0(%[ptr_i]) \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "1: \n\t" + "sll %[tmp1], %[i], 2 \n\t" + "addu %[ptr_i], %[frfi], %[tmp1] \n\t" + "addu %[ptr_j], %[ptr_i], %[tmp] \n\t" + "lh %[tmp3], 0(%[ptr_j]) \n\t" + "lh %[tmp4], 2(%[ptr_j]) \n\t" + "lh %[tmp6], 0(%[ptr_i]) \n\t" + "lh %[tmp5], 2(%[ptr_i]) \n\t" + "addu %[i], %[i], %[istep] \n\t" +#if defined(MIPS_DSP_R2_LE) + "mult %[wr], %[tmp3] \n\t" + "msub %[wi], %[tmp4] \n\t" + "mult $ac1, %[wr], %[tmp4] \n\t" + "madd $ac1, %[wi], %[tmp3] \n\t" + "mflo %[tmp1] \n\t" + "mflo %[tmp2], $ac1 \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "shra_r.w %[tmp1], %[tmp1], 1 \n\t" + "shra_r.w %[tmp2], %[tmp2], 1 \n\t" + "addu %[tmp6], %[tmp6], %[round2] \n\t" + "addu %[tmp5], %[tmp5], %[round2] \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "srav %[tmp4], %[tmp4], %[shift] \n\t" + "srav %[tmp1], %[tmp1], %[shift] \n\t" + "srav %[tmp6], %[tmp6], %[shift] \n\t" + "srav %[tmp5], %[tmp5], %[shift] \n\t" +#else // #if defined(MIPS_DSP_R2_LE) + "mul %[tmp1], %[wr], %[tmp3] \n\t" + "mul %[tmp2], %[wr], %[tmp4] \n\t" + "mul %[tmp4], %[wi], %[tmp4] \n\t" + "mul %[tmp3], %[wi], %[tmp3] \n\t" + "sll %[tmp6], %[tmp6], 14 \n\t" + "sll %[tmp5], %[tmp5], 14 \n\t" + "sub %[tmp1], %[tmp1], %[tmp4] \n\t" + "addu %[tmp2], %[tmp2], %[tmp3] \n\t" + "addiu %[tmp1], %[tmp1], 1 \n\t" + "addiu %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp2], %[tmp2], 1 \n\t" + "sra %[tmp1], %[tmp1], 1 \n\t" + "addu %[tmp6], %[tmp6], %[round2] \n\t" + "addu %[tmp5], %[tmp5], %[round2] \n\t" + "subu %[tmp4], %[tmp6], %[tmp1] \n\t" + "addu %[tmp1], %[tmp6], %[tmp1] \n\t" + "addu %[tmp6], %[tmp5], %[tmp2] \n\t" + "subu %[tmp5], %[tmp5], %[tmp2] \n\t" + "sra %[tmp4], %[tmp4], %[shift] \n\t" + "sra %[tmp1], %[tmp1], %[shift] \n\t" + "sra %[tmp6], %[tmp6], %[shift] \n\t" + "sra %[tmp5], %[tmp5], %[shift] \n\t" +#endif // #if defined(MIPS_DSP_R2_LE) + "sh %[tmp1], 0(%[ptr_i]) \n\t" + "sh %[tmp6], 2(%[ptr_i]) \n\t" + "sh %[tmp4], 0(%[ptr_j]) \n\t" + "blt %[i], %[n], 1b \n\t" + " sh %[tmp5], 2(%[ptr_j]) \n\t" + "blt %[m], %[l], 2b \n\t" + " addu %[i], $zero, %[m] \n\t" + "move %[l], %[istep] \n\t" + "blt %[l], %[n], 3b \n\t" + " addiu %[k], %[k], -1 \n\t" + + ".set pop \n\t" + + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6), + [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [m] "=&r" (m), [tmp] "=&r" (tmp), + [istep] "=&r" (istep), [wi] "=&r" (wi), [wr] "=&r" (wr), [l] "=&r" (l), + [k] "=&r" (k), [round2] "=&r" (round2), [ptr_j] "=&r" (ptr_j), + [shift] "=&r" (shift), [scale] "=&r" (scale), [tempMax] "=&r" (tempMax) + : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024) + : "hi", "lo", "$ac1hi", "$ac1lo", "memory" + ); + + return scale; + +} + diff --git a/webrtc/common_audio/signal_processing/complex_fft_tables.h b/webrtc/common_audio/signal_processing/complex_fft_tables.h new file mode 100644 index 0000000000..ca7b7fe39b --- /dev/null +++ b/webrtc/common_audio/signal_processing/complex_fft_tables.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ +#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ + +#include "webrtc/typedefs.h" + +static const int16_t kSinTable1024[] = { + 0, 201, 402, 603, 804, 1005, 1206, 1406, + 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, + 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, + 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, + 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, + 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, + 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, + 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, + 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, + 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, + 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, + 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, + 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, + 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, + 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, + 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, + 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, + 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, + 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, + 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, + 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, + 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, + 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, + 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, + 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, + 30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297, + 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, + 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, + 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, + 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, + 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, + 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, + 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, + 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, + 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, + 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, + 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, + 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, + 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, + 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, + 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, + 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, + 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, + 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, + 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, + 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, + 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, + 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, + 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, + 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, + 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, + 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, + 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, + 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, + 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, + 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, + 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, + 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, + 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, + 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, + 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, + 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, + 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, + 1607, 1406, 1206, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1206, -1406, + -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, + -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, + -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, + -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, + -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, + -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, + -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, + -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, + -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, + -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, + -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, + -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, + -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, + -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, + -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, + -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, + -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, + -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, + -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, + -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, + -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, + -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, + -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, + -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, + -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, + -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, + -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, + -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, + -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, + -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, + -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, + -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, + -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, + -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, + -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, + -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, + -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, + -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, + -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, + -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, + -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, + -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, + -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, + -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, + -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, + -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, + -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, + -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, + -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, + -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, + -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, + -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, + -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, + -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, + -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, + -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, + -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, + -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, + -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, + -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, + -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, + -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, + -1607, -1406, -1206, -1005, -804, -603, -402, -201 +}; + +#endif // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_ diff --git a/webrtc/common_audio/signal_processing/downsample_fast_mips.c b/webrtc/common_audio/signal_processing/downsample_fast_mips.c new file mode 100644 index 0000000000..a063919dee --- /dev/null +++ b/webrtc/common_audio/signal_processing/downsample_fast_mips.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +// Version of WebRtcSpl_DownsampleFast() for MIPS platforms. +int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in, + int data_in_length, + int16_t* data_out, + int data_out_length, + const int16_t* __restrict coefficients, + int coefficients_length, + int factor, + int delay) { + int i; + int j; + int k; + int32_t out_s32 = 0; + int endpos = delay + factor * (data_out_length - 1) + 1; + + int32_t tmp1, tmp2, tmp3, tmp4, factor_2; + int16_t* p_coefficients; + int16_t* p_data_in; + int16_t* p_data_in_0 = (int16_t*)&data_in[delay]; + int16_t* p_coefficients_0 = (int16_t*)&coefficients[0]; +#if !defined(MIPS_DSP_R1_LE) + int32_t max_16 = 0x7FFF; + int32_t min_16 = 0xFFFF8000; +#endif // #if !defined(MIPS_DSP_R1_LE) + + // Return error if any of the running conditions doesn't meet. + if (data_out_length <= 0 || coefficients_length <= 0 + || data_in_length < endpos) { + return -1; + } +#if defined(MIPS_DSP_R2_LE) + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "subu %[i], %[endpos], %[delay] \n\t" + "sll %[factor_2], %[factor], 1 \n\t" + "1: \n\t" + "move %[p_data_in], %[p_data_in_0] \n\t" + "mult $zero, $zero \n\t" + "move %[p_coefs], %[p_coefs_0] \n\t" + "sra %[j], %[coef_length], 2 \n\t" + "beq %[j], $zero, 3f \n\t" + " andi %[k], %[coef_length], 3 \n\t" + "2: \n\t" + "lwl %[tmp1], 1(%[p_data_in]) \n\t" + "lwl %[tmp2], 3(%[p_coefs]) \n\t" + "lwl %[tmp3], -3(%[p_data_in]) \n\t" + "lwl %[tmp4], 7(%[p_coefs]) \n\t" + "lwr %[tmp1], -2(%[p_data_in]) \n\t" + "lwr %[tmp2], 0(%[p_coefs]) \n\t" + "lwr %[tmp3], -6(%[p_data_in]) \n\t" + "lwr %[tmp4], 4(%[p_coefs]) \n\t" + "packrl.ph %[tmp1], %[tmp1], %[tmp1] \n\t" + "packrl.ph %[tmp3], %[tmp3], %[tmp3] \n\t" + "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" + "dpa.w.ph $ac0, %[tmp3], %[tmp4] \n\t" + "addiu %[j], %[j], -1 \n\t" + "addiu %[p_data_in], %[p_data_in], -8 \n\t" + "bgtz %[j], 2b \n\t" + " addiu %[p_coefs], %[p_coefs], 8 \n\t" + "3: \n\t" + "beq %[k], $zero, 5f \n\t" + " nop \n\t" + "4: \n\t" + "lhu %[tmp1], 0(%[p_data_in]) \n\t" + "lhu %[tmp2], 0(%[p_coefs]) \n\t" + "addiu %[p_data_in], %[p_data_in], -2 \n\t" + "addiu %[k], %[k], -1 \n\t" + "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" + "bgtz %[k], 4b \n\t" + " addiu %[p_coefs], %[p_coefs], 2 \n\t" + "5: \n\t" + "extr_r.w %[out_s32], $ac0, 12 \n\t" + "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" + "subu %[i], %[i], %[factor] \n\t" + "shll_s.w %[out_s32], %[out_s32], 16 \n\t" + "sra %[out_s32], %[out_s32], 16 \n\t" + "sh %[out_s32], 0(%[data_out]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[data_out], %[data_out], 2 \n\t" + ".set pop \n\t" + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), + [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), + [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), + [i] "=&r" (i), [k] "=&r" (k) + : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), + [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), + [delay] "r" (delay), [factor] "r" (factor) + : "memory", "hi", "lo" + ); +#else // #if defined(MIPS_DSP_R2_LE) + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "sll %[factor_2], %[factor], 1 \n\t" + "subu %[i], %[endpos], %[delay] \n\t" + "1: \n\t" + "move %[p_data_in], %[p_data_in_0] \n\t" + "addiu %[out_s32], $zero, 2048 \n\t" + "move %[p_coefs], %[p_coefs_0] \n\t" + "sra %[j], %[coef_length], 1 \n\t" + "beq %[j], $zero, 3f \n\t" + " andi %[k], %[coef_length], 1 \n\t" + "2: \n\t" + "lh %[tmp1], 0(%[p_data_in]) \n\t" + "lh %[tmp2], 0(%[p_coefs]) \n\t" + "lh %[tmp3], -2(%[p_data_in]) \n\t" + "lh %[tmp4], 2(%[p_coefs]) \n\t" + "mul %[tmp1], %[tmp1], %[tmp2] \n\t" + "addiu %[p_coefs], %[p_coefs], 4 \n\t" + "mul %[tmp3], %[tmp3], %[tmp4] \n\t" + "addiu %[j], %[j], -1 \n\t" + "addiu %[p_data_in], %[p_data_in], -4 \n\t" + "addu %[tmp1], %[tmp1], %[tmp3] \n\t" + "bgtz %[j], 2b \n\t" + " addu %[out_s32], %[out_s32], %[tmp1] \n\t" + "3: \n\t" + "beq %[k], $zero, 4f \n\t" + " nop \n\t" + "lh %[tmp1], 0(%[p_data_in]) \n\t" + "lh %[tmp2], 0(%[p_coefs]) \n\t" + "mul %[tmp1], %[tmp1], %[tmp2] \n\t" + "addu %[out_s32], %[out_s32], %[tmp1] \n\t" + "4: \n\t" + "sra %[out_s32], %[out_s32], 12 \n\t" + "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[out_s32], %[out_s32], 16 \n\t" + "sra %[out_s32], %[out_s32], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "slt %[tmp1], %[max_16], %[out_s32] \n\t" + "movn %[out_s32], %[max_16], %[tmp1] \n\t" + "slt %[tmp1], %[out_s32], %[min_16] \n\t" + "movn %[out_s32], %[min_16], %[tmp1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "subu %[i], %[i], %[factor] \n\t" + "sh %[out_s32], 0(%[data_out]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[data_out], %[data_out], 2 \n\t" + ".set pop \n\t" + : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), + [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k), + [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), + [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), + [i] "=&r" (i) + : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), + [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), +#if !defined(MIPS_DSP_R1_LE) + [max_16] "r" (max_16), [min_16] "r" (min_16), +#endif // #if !defined(MIPS_DSP_R1_LE) + [delay] "r" (delay), [factor] "r" (factor) + : "memory", "hi", "lo" + ); +#endif // #if defined(MIPS_DSP_R2_LE) + return 0; +} + diff --git a/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c new file mode 100644 index 0000000000..208c5933c4 --- /dev/null +++ b/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include + +#include "signal_processing_library.h" + +void WebRtcSpl_FilterARFastQ12(const int16_t* data_in, + int16_t* data_out, + const int16_t* __restrict coefficients, + int coefficients_length, + int data_length) { + int r0, r1, r2, r3; + int coef0, offset; + int i, j, k; + int coefptr, outptr, tmpout, inptr; +#if !defined(MIPS_DSP_R1_LE) + int max16 = 0x7FFF; + int min16 = 0xFFFF8000; +#endif // #if !defined(MIPS_DSP_R1_LE) + + assert(data_length > 0); + assert(coefficients_length > 1); + + __asm __volatile ( + ".set push \n\t" + ".set noreorder \n\t" + "addiu %[i], %[data_length], 0 \n\t" + "lh %[coef0], 0(%[coefficients]) \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" + "andi %[k], %[j], 1 \n\t" + "sll %[offset], %[j], 1 \n\t" + "subu %[outptr], %[data_out], %[offset] \n\t" + "addiu %[inptr], %[data_in], 0 \n\t" + "bgtz %[k], 3f \n\t" + " addu %[coefptr], %[coefficients], %[offset] \n\t" + "1: \n\t" + "lh %[r0], 0(%[inptr]) \n\t" + "addiu %[i], %[i], -1 \n\t" + "addiu %[tmpout], %[outptr], 0 \n\t" + "mult %[r0], %[coef0] \n\t" + "2: \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "lh %[r2], 2(%[tmpout]) \n\t" + "lh %[r3], -2(%[coefptr]) \n\t" + "addiu %[tmpout], %[tmpout], 4 \n\t" + "msub %[r0], %[r1] \n\t" + "msub %[r2], %[r3] \n\t" + "addiu %[j], %[j], -2 \n\t" + "bgtz %[j], 2b \n\t" + " addiu %[coefptr], %[coefptr], -4 \n\t" +#if defined(MIPS_DSP_R1_LE) + "extr_r.w %[r0], $ac0, 12 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "mflo %[r0] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "addu %[coefptr], %[coefficients], %[offset] \n\t" + "addiu %[inptr], %[inptr], 2 \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[r0], %[r0], 16 \n\t" + "sra %[r0], %[r0], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "addiu %[r0], %[r0], 2048 \n\t" + "sra %[r0], %[r0], 12 \n\t" + "slt %[r1], %[max16], %[r0] \n\t" + "movn %[r0], %[max16], %[r1] \n\t" + "slt %[r1], %[r0], %[min16] \n\t" + "movn %[r0], %[min16], %[r1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "sh %[r0], 0(%[tmpout]) \n\t" + "bgtz %[i], 1b \n\t" + " addiu %[outptr], %[outptr], 2 \n\t" + "b 5f \n\t" + " nop \n\t" + "3: \n\t" + "lh %[r0], 0(%[inptr]) \n\t" + "addiu %[i], %[i], -1 \n\t" + "addiu %[tmpout], %[outptr], 0 \n\t" + "mult %[r0], %[coef0] \n\t" + "4: \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "lh %[r2], 2(%[tmpout]) \n\t" + "lh %[r3], -2(%[coefptr]) \n\t" + "addiu %[tmpout], %[tmpout], 4 \n\t" + "msub %[r0], %[r1] \n\t" + "msub %[r2], %[r3] \n\t" + "addiu %[j], %[j], -2 \n\t" + "bgtz %[j], 4b \n\t" + " addiu %[coefptr], %[coefptr], -4 \n\t" + "lh %[r0], 0(%[tmpout]) \n\t" + "lh %[r1], 0(%[coefptr]) \n\t" + "msub %[r0], %[r1] \n\t" +#if defined(MIPS_DSP_R1_LE) + "extr_r.w %[r0], $ac0, 12 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "mflo %[r0] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "addu %[coefptr], %[coefficients], %[offset] \n\t" + "addiu %[inptr], %[inptr], 2 \n\t" + "addiu %[j], %[coefficients_length], -1 \n\t" +#if defined(MIPS_DSP_R1_LE) + "shll_s.w %[r0], %[r0], 16 \n\t" + "sra %[r0], %[r0], 16 \n\t" +#else // #if defined(MIPS_DSP_R1_LE) + "addiu %[r0], %[r0], 2048 \n\t" + "sra %[r0], %[r0], 12 \n\t" + "slt %[r1], %[max16], %[r0] \n\t" + "movn %[r0], %[max16], %[r1] \n\t" + "slt %[r1], %[r0], %[min16] \n\t" + "movn %[r0], %[min16], %[r1] \n\t" +#endif // #if defined(MIPS_DSP_R1_LE) + "sh %[r0], 2(%[tmpout]) \n\t" + "bgtz %[i], 3b \n\t" + " addiu %[outptr], %[outptr], 2 \n\t" + "5: \n\t" + ".set pop \n\t" + : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0), + [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3), + [coef0] "=&r" (coef0), [offset] "=&r" (offset), + [outptr] "=&r" (outptr), [inptr] "=&r" (inptr), + [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout) + : [coefficients] "r" (coefficients), [data_length] "r" (data_length), + [coefficients_length] "r" (coefficients_length), +#if !defined(MIPS_DSP_R1_LE) + [max16] "r" (max16), [min16] "r" (min16), +#endif + [data_out] "r" (data_out), [data_in] "r" (data_in) + : "hi", "lo", "memory" + ); +} + diff --git a/webrtc/common_audio/signal_processing/include/signal_processing_library.h b/webrtc/common_audio/signal_processing/include/signal_processing_library.h index 2c42f994f1..887400cb22 100644 --- a/webrtc/common_audio/signal_processing/include/signal_processing_library.h +++ b/webrtc/common_audio/signal_processing/include/signal_processing_library.h @@ -771,6 +771,16 @@ int WebRtcSpl_DownsampleFastNeon(const int16_t* data_in, int factor, int delay); #endif +#if defined(MIPS32_LE) +int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in, + int data_in_length, + int16_t* data_out, + int data_out_length, + const int16_t* __restrict coefficients, + int coefficients_length, + int factor, + int delay); +#endif // End: Filter operations. diff --git a/webrtc/common_audio/signal_processing/spl_init.c b/webrtc/common_audio/signal_processing/spl_init.c index fdb77ef102..1645f63fc1 100644 --- a/webrtc/common_audio/signal_processing/spl_init.c +++ b/webrtc/common_audio/signal_processing/spl_init.c @@ -77,7 +77,7 @@ static void InitPointersToMIPS() { WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips; WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips; WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC; - WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC; + WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips; WebRtcSpl_ScaleAndAddVectorsWithRound = WebRtcSpl_ScaleAndAddVectorsWithRoundC; WebRtcSpl_RealForwardFFT = WebRtcSpl_RealForwardFFTC;