1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/* 2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * 4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Use of this source code is governed by a BSD-style license 5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * that can be found in the LICENSE file in the root of the source 6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * tree. An additional intellectual property rights grant can be found 7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * in the file PATENTS. All contributing project authors may 8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * be found in the AUTHORS file in the root of the source tree. 9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */ 10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "noise_suppression_x.h" 12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <assert.h> 14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <math.h> 15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <string.h> 16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <stdlib.h> 17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "nsx_core.h" 19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Skip first frequency bins during estimation. (0 <= value < 64) 21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const int kStartBand = 5; 22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Rounding 24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kRoundTable[16] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2048, 4096, 8192, 16384}; 26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Constants to compensate for shifting signal log(2^shifts). 28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kLogTable[9] = {0, 177, 355, 532, 710, 887, 1065, 1242, 1420}; 29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kCounterDiv[201] = {32767, 16384, 10923, 8192, 6554, 5461, 4681, 31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 4096, 3641, 3277, 2979, 2731, 2521, 2341, 2185, 2048, 1928, 1820, 1725, 1638, 1560, 32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, 1092, 1057, 1024, 993, 964, 936, 910, 33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 886, 862, 840, 819, 799, 780, 762, 745, 728, 712, 697, 683, 669, 655, 643, 630, 618, 34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 607, 596, 585, 575, 565, 555, 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468, 35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 462, 455, 449, 443, 437, 431, 426, 420, 415, 410, 405, 400, 395, 390, 386, 381, 377, 36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 372, 368, 364, 360, 356, 352, 349, 345, 341, 338, 334, 331, 328, 324, 321, 318, 315, 37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 312, 309, 306, 303, 301, 298, 295, 293, 290, 287, 285, 282, 280, 278, 275, 273, 271, 38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 269, 266, 264, 262, 260, 258, 256, 254, 252, 250, 248, 246, 245, 243, 241, 239, 237, 39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 236, 234, 232, 231, 229, 228, 226, 224, 223, 221, 220, 218, 217, 216, 214, 213, 211, 40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 210, 209, 207, 206, 205, 204, 202, 201, 200, 199, 197, 196, 195, 194, 193, 192, 191, 41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 172, 172, 171, 170, 169, 168, 167, 166, 165, 165, 164, 163}; 43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kLogTableFrac[256] = { 45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 1, 3, 4, 6, 7, 9, 10, 11, 13, 14, 16, 17, 18, 20, 21, 46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 22, 24, 25, 26, 28, 29, 30, 32, 33, 34, 36, 37, 38, 40, 41, 42, 47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 56, 57, 59, 60, 61, 62, 48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 82, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 97, 98, 99, 50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, 51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 178, 55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, 190, 191, 192, 192, 56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 207, 208, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219, 58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 220, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 228, 229, 230, 231, 231, 59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 232, 233, 234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 244, 60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 244, 245, 246, 247, 247, 248, 249, 249, 250, 251, 252, 252, 253, 254, 255, 255 61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kPowTableFrac[1024] = { 64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 1, 1, 2, 3, 3, 4, 5, 65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 6, 6, 7, 8, 8, 9, 10, 10, 66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11, 12, 13, 13, 14, 15, 15, 16, 67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 17, 17, 18, 19, 20, 20, 21, 22, 68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 22, 23, 24, 25, 25, 26, 27, 27, 69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 28, 29, 30, 30, 31, 32, 32, 33, 70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 34, 35, 35, 36, 37, 37, 38, 39, 71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 40, 40, 41, 42, 42, 43, 44, 45, 72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 45, 46, 47, 48, 48, 49, 50, 50, 73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 51, 52, 53, 53, 54, 55, 56, 56, 74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 57, 58, 58, 59, 60, 61, 61, 62, 75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 63, 64, 64, 65, 66, 67, 67, 68, 76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 69, 69, 70, 71, 72, 72, 73, 74, 77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 75, 75, 76, 77, 78, 78, 79, 80, 78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 81, 81, 82, 83, 84, 84, 85, 86, 79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 87, 87, 88, 89, 90, 90, 91, 92, 80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 93, 93, 94, 95, 96, 96, 97, 98, 81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 99, 100, 100, 101, 102, 103, 103, 104, 82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 105, 106, 106, 107, 108, 109, 109, 110, 83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 111, 112, 113, 113, 114, 115, 116, 116, 84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 117, 118, 119, 119, 120, 121, 122, 123, 85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 123, 124, 125, 126, 126, 127, 128, 129, 86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 130, 130, 131, 132, 133, 133, 134, 135, 87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 136, 137, 137, 138, 139, 140, 141, 141, 88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 142, 143, 144, 144, 145, 146, 147, 148, 89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 148, 149, 150, 151, 152, 152, 153, 154, 90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 155, 156, 156, 157, 158, 159, 160, 160, 91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 161, 162, 163, 164, 164, 165, 166, 167, 92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 168, 168, 169, 170, 171, 172, 173, 173, 93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 174, 175, 176, 177, 177, 178, 179, 180, 94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 181, 181, 182, 183, 184, 185, 186, 186, 95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 187, 188, 189, 190, 190, 191, 192, 193, 96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 194, 195, 195, 196, 197, 198, 199, 200, 97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 200, 201, 202, 203, 204, 205, 205, 206, 98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 207, 208, 209, 210, 210, 211, 212, 213, 99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 214, 215, 215, 216, 217, 218, 219, 220, 100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 220, 221, 222, 223, 224, 225, 225, 226, 101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 227, 228, 229, 230, 231, 231, 232, 233, 102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 234, 235, 236, 237, 237, 238, 239, 240, 103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 241, 242, 243, 243, 244, 245, 246, 247, 104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 248, 249, 249, 250, 251, 252, 253, 254, 105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 255, 255, 256, 257, 258, 259, 260, 261, 106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 262, 262, 263, 264, 265, 266, 267, 268, 107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 268, 269, 270, 271, 272, 273, 274, 275, 108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 276, 276, 277, 278, 279, 280, 281, 282, 109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 283, 283, 284, 285, 286, 287, 288, 289, 110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 290, 291, 291, 292, 293, 294, 295, 296, 111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 297, 298, 299, 299, 300, 301, 302, 303, 112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 304, 305, 306, 307, 308, 308, 309, 310, 113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 311, 312, 313, 314, 315, 316, 317, 318, 114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 318, 319, 320, 321, 322, 323, 324, 325, 115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 326, 327, 328, 328, 329, 330, 331, 332, 116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 333, 334, 335, 336, 337, 338, 339, 339, 117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 340, 341, 342, 343, 344, 345, 346, 347, 118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 348, 349, 350, 351, 352, 352, 353, 354, 119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 355, 356, 357, 358, 359, 360, 361, 362, 120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 363, 364, 365, 366, 367, 367, 368, 369, 121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 370, 371, 372, 373, 374, 375, 376, 377, 122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 378, 379, 380, 381, 382, 383, 384, 385, 123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 385, 386, 387, 388, 389, 390, 391, 392, 124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 393, 394, 395, 396, 397, 398, 399, 400, 125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 401, 402, 403, 404, 405, 406, 407, 408, 126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 409, 410, 410, 411, 412, 413, 414, 415, 127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 416, 417, 418, 419, 420, 421, 422, 423, 128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 424, 425, 426, 427, 428, 429, 430, 431, 129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 432, 433, 434, 435, 436, 437, 438, 439, 130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 440, 441, 442, 443, 444, 445, 446, 447, 131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 448, 449, 450, 451, 452, 453, 454, 455, 132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 456, 457, 458, 459, 460, 461, 462, 463, 133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 464, 465, 466, 467, 468, 469, 470, 471, 134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 472, 473, 474, 475, 476, 477, 478, 479, 135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 480, 481, 482, 483, 484, 485, 486, 487, 136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 488, 489, 490, 491, 492, 493, 494, 495, 137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 496, 498, 499, 500, 501, 502, 503, 504, 138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 505, 506, 507, 508, 509, 510, 511, 512, 139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 513, 514, 515, 516, 517, 518, 519, 520, 140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 521, 522, 523, 525, 526, 527, 528, 529, 141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 530, 531, 532, 533, 534, 535, 536, 537, 142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 538, 539, 540, 541, 542, 544, 545, 546, 143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 547, 548, 549, 550, 551, 552, 553, 554, 144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 555, 556, 557, 558, 560, 561, 562, 563, 145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 564, 565, 566, 567, 568, 569, 570, 571, 146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 572, 574, 575, 576, 577, 578, 579, 580, 147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 581, 582, 583, 584, 585, 587, 588, 589, 148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 590, 591, 592, 593, 594, 595, 596, 597, 149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 599, 600, 601, 602, 603, 604, 605, 606, 150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 607, 608, 610, 611, 612, 613, 614, 615, 151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 616, 617, 618, 620, 621, 622, 623, 624, 152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 625, 626, 627, 628, 630, 631, 632, 633, 153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 634, 635, 636, 637, 639, 640, 641, 642, 154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 643, 644, 645, 646, 648, 649, 650, 651, 155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 652, 653, 654, 656, 657, 658, 659, 660, 156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 661, 662, 664, 665, 666, 667, 668, 669, 157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 670, 672, 673, 674, 675, 676, 677, 678, 158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 680, 681, 682, 683, 684, 685, 687, 688, 159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 689, 690, 691, 692, 693, 695, 696, 697, 160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 698, 699, 700, 702, 703, 704, 705, 706, 161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 708, 709, 710, 711, 712, 713, 715, 716, 162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 717, 718, 719, 720, 722, 723, 724, 725, 163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 726, 728, 729, 730, 731, 732, 733, 735, 164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 736, 737, 738, 739, 741, 742, 743, 744, 165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 745, 747, 748, 749, 750, 751, 753, 754, 166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 755, 756, 757, 759, 760, 761, 762, 763, 167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 765, 766, 767, 768, 770, 771, 772, 773, 168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 774, 776, 777, 778, 779, 780, 782, 783, 169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 784, 785, 787, 788, 789, 790, 792, 793, 170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 794, 795, 796, 798, 799, 800, 801, 803, 171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 804, 805, 806, 808, 809, 810, 811, 813, 172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 814, 815, 816, 818, 819, 820, 821, 823, 173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 824, 825, 826, 828, 829, 830, 831, 833, 174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 834, 835, 836, 838, 839, 840, 841, 843, 175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 844, 845, 846, 848, 849, 850, 851, 853, 176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 854, 855, 857, 858, 859, 860, 862, 863, 177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 864, 866, 867, 868, 869, 871, 872, 873, 178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 874, 876, 877, 878, 880, 881, 882, 883, 179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 885, 886, 887, 889, 890, 891, 893, 894, 180e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 895, 896, 898, 899, 900, 902, 903, 904, 181e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 906, 907, 908, 909, 911, 912, 913, 915, 182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 916, 917, 919, 920, 921, 923, 924, 925, 183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 927, 928, 929, 931, 932, 933, 935, 936, 184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 937, 938, 940, 941, 942, 944, 945, 946, 185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 948, 949, 950, 952, 953, 955, 956, 957, 186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 959, 960, 961, 963, 964, 965, 967, 968, 187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 969, 971, 972, 973, 975, 976, 977, 979, 188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 980, 981, 983, 984, 986, 987, 988, 990, 189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 991, 992, 994, 995, 996, 998, 999, 1001, 190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1002, 1003, 1005, 1006, 1007, 1009, 1010, 1012, 191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1013, 1014, 1016, 1017, 1018, 1020, 1021, 1023 192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kIndicatorTable[17] = {0, 2017, 3809, 5227, 6258, 6963, 7424, 7718, 195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7901, 8014, 8084, 8126, 8152, 8168, 8177, 8183, 8187}; 196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// hybrib Hanning & flat window 198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kBlocks80w128x[128] = { 199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 536, 1072, 1606, 2139, 2669, 3196, 3720, 4240, 4756, 5266, 200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 5771, 6270, 6762, 7246, 7723, 8192, 8652, 9102, 9543, 9974, 10394, 201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10803, 11200, 11585, 11958, 12318, 12665, 12998, 13318, 13623, 13913, 14189, 202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14449, 14694, 14924, 15137, 15334, 15515, 15679, 15826, 15956, 16069, 16165, 203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16244, 16305, 16349, 16375, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16384, 16384, 16384, 16384, 16375, 16349, 16305, 16244, 16165, 16069, 15956, 207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15826, 15679, 15515, 15334, 15137, 14924, 14694, 14449, 14189, 13913, 13623, 208e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13318, 12998, 12665, 12318, 11958, 11585, 11200, 10803, 10394, 9974, 9543, 209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9102, 8652, 8192, 7723, 7246, 6762, 6270, 5771, 5266, 4756, 4240, 210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 3720, 3196, 2669, 2139, 1606, 1072, 536 211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// hybrib Hanning & flat window 214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kBlocks160w256x[256] = { 215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 268, 536, 804, 1072, 1339, 1606, 1872, 216e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2139, 2404, 2669, 2933, 3196, 3459, 3720, 3981, 217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 4240, 4499, 4756, 5012, 5266, 5520, 5771, 6021, 218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 6270, 6517, 6762, 7005, 7246, 7486, 7723, 7959, 219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8423, 8652, 8878, 9102, 9324, 9543, 9760, 220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9974, 10185, 10394, 10600, 10803, 11003, 11200, 11394, 221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent11585, 11773, 11958, 12140, 12318, 12493, 12665, 12833, 222e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent12998, 13160, 13318, 13472, 13623, 13770, 13913, 14053, 223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent14189, 14321, 14449, 14574, 14694, 14811, 14924, 15032, 224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent15137, 15237, 15334, 15426, 15515, 15599, 15679, 15754, 225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent15826, 15893, 15956, 16015, 16069, 16119, 16165, 16207, 226e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16244, 16277, 16305, 16329, 16349, 16364, 16375, 16382, 227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16384, 16382, 16375, 16364, 16349, 16329, 16305, 16277, 236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent16244, 16207, 16165, 16119, 16069, 16015, 15956, 15893, 237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent15826, 15754, 15679, 15599, 15515, 15426, 15334, 15237, 238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent15137, 15032, 14924, 14811, 14694, 14574, 14449, 14321, 239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent14189, 14053, 13913, 13770, 13623, 13472, 13318, 13160, 240e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent12998, 12833, 12665, 12493, 12318, 12140, 11958, 11773, 241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent11585, 11394, 11200, 11003, 10803, 10600, 10394, 10185, 242e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9974, 9760, 9543, 9324, 9102, 8878, 8652, 8423, 243e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 7959, 7723, 7486, 7246, 7005, 6762, 6517, 244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 6270, 6021, 5771, 5520, 5266, 5012, 4756, 4499, 245e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 4240, 3981, 3720, 3459, 3196, 2933, 2669, 2404, 246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2139, 1872, 1606, 1339, 1072, 804, 536, 268 247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 249e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Gain factor table: Input value in Q8 and output value in Q13 250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kFactor1Table[257] = { 251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 253e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8233, 8274, 8315, 8355, 8396, 8436, 8475, 8515, 8554, 8592, 8631, 8669, 257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8707, 8745, 8783, 8820, 8857, 8894, 8931, 8967, 9003, 9039, 9075, 9111, 9146, 9181, 258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9216, 9251, 9286, 9320, 9354, 9388, 9422, 9456, 9489, 9523, 9556, 9589, 9622, 9655, 259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9687, 9719, 9752, 9784, 9816, 9848, 9879, 9911, 9942, 9973, 10004, 10035, 10066, 260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10097, 10128, 10158, 10188, 10218, 10249, 10279, 10308, 10338, 10368, 10397, 10426, 261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10456, 10485, 10514, 10543, 10572, 10600, 10629, 10657, 10686, 10714, 10742, 10770, 262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10798, 10826, 10854, 10882, 10847, 10810, 10774, 10737, 10701, 10666, 10631, 10596, 263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10562, 10527, 10494, 10460, 10427, 10394, 10362, 10329, 10297, 10266, 10235, 10203, 264e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 10173, 10142, 10112, 10082, 10052, 10023, 9994, 9965, 9936, 9908, 9879, 9851, 9824, 265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9796, 9769, 9742, 9715, 9689, 9662, 9636, 9610, 9584, 9559, 9534, 9508, 9484, 9459, 266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9434, 9410, 9386, 9362, 9338, 9314, 9291, 9268, 9245, 9222, 9199, 9176, 9154, 9132, 267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 9110, 9088, 9066, 9044, 9023, 9002, 8980, 8959, 8939, 8918, 8897, 8877, 8857, 8836, 268e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8816, 8796, 8777, 8757, 8738, 8718, 8699, 8680, 8661, 8642, 8623, 8605, 8586, 8568, 269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8550, 8532, 8514, 8496, 8478, 8460, 8443, 8425, 8408, 8391, 8373, 8356, 8339, 8323, 270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8306, 8289, 8273, 8256, 8240, 8224, 8208, 8192 271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Gain factor table: Input value in Q8 and output value in Q13 274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kFactor2Aggressiveness1[257] = { 275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7577, 7577, 7577, 7577, 7577, 7577, 276e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7596, 7614, 7632, 277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 278e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, 279e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, 280e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 281e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 282e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 283e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 284e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 285e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 286e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 287e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 288e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 293e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 294e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 295e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Gain factor table: Input value in Q8 and output value in Q13 297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kFactor2Aggressiveness2[257] = { 298e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7270, 7270, 7270, 7270, 7270, 7306, 299e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, 300e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, 302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, 303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Gain factor table: Input value in Q8 and output value in Q13 320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kFactor2Aggressiveness3[257] = { 321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7184, 7184, 7184, 7229, 7270, 7306, 322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, 323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, 324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, 325e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, 326e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 327e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 328e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 329e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 330e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 331e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 332e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 333e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 334e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 335e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 336e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 337e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 338e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 339e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 340e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 341e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 342e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// sum of log2(i) from table index to inst->anaLen2 in Q5 343e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Note that the first table value is invalid, since log2(0) = -infinity 344e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kSumLogIndex[66] = { 345e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 22917, 22917, 22885, 22834, 22770, 22696, 22613, 346e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 22524, 22428, 22326, 22220, 22109, 21994, 21876, 21754, 347e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 21629, 21501, 21370, 21237, 21101, 20963, 20822, 20679, 348e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 20535, 20388, 20239, 20089, 19937, 19783, 19628, 19470, 349e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 19312, 19152, 18991, 18828, 18664, 18498, 18331, 18164, 350e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 17994, 17824, 17653, 17480, 17306, 17132, 16956, 16779, 351e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16602, 16423, 16243, 16063, 15881, 15699, 15515, 15331, 352e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15146, 14960, 14774, 14586, 14398, 14209, 14019, 13829, 353e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13637, 13445 354e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 355e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 356e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// sum of log2(i)^2 from table index to inst->anaLen2 in Q2 357e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Note that the first table value is invalid, since log2(0) = -infinity 358e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kSumSquareLogIndex[66] = { 359e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 16959, 16959, 16955, 16945, 16929, 16908, 16881, 360e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16850, 16814, 16773, 16729, 16681, 16630, 16575, 16517, 361e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16456, 16392, 16325, 16256, 16184, 16109, 16032, 15952, 362e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15870, 15786, 15700, 15612, 15521, 15429, 15334, 15238, 363e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15140, 15040, 14938, 14834, 14729, 14622, 14514, 14404, 364e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14292, 14179, 14064, 13947, 13830, 13710, 13590, 13468, 365e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13344, 13220, 13094, 12966, 12837, 12707, 12576, 12444, 366e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 12310, 12175, 12039, 11902, 11763, 11624, 11483, 11341, 367e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11198, 11054 368e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 369e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 370e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// log2(table index) in Q12 371e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Note that the first table value is invalid, since log2(0) = -infinity 372e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kLogIndex[129] = { 373e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 0, 4096, 6492, 8192, 9511, 10588, 11499, 374e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 12288, 12984, 13607, 14170, 14684, 15157, 15595, 16003, 375e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 16384, 16742, 17080, 17400, 17703, 17991, 18266, 18529, 376e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 18780, 19021, 19253, 19476, 19691, 19898, 20099, 20292, 377e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 20480, 20662, 20838, 21010, 21176, 21338, 21496, 21649, 378e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 21799, 21945, 22087, 22226, 22362, 22495, 22625, 22752, 379e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 22876, 22998, 23117, 23234, 23349, 23462, 23572, 23680, 380e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 23787, 23892, 23994, 24095, 24195, 24292, 24388, 24483, 381e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 24576, 24668, 24758, 24847, 24934, 25021, 25106, 25189, 382e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 25272, 25354, 25434, 25513, 25592, 25669, 25745, 25820, 383e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 25895, 25968, 26041, 26112, 26183, 26253, 26322, 26390, 384e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 26458, 26525, 26591, 26656, 26721, 26784, 26848, 26910, 385e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 26972, 27033, 27094, 27154, 27213, 27272, 27330, 27388, 386e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 27445, 27502, 27558, 27613, 27668, 27722, 27776, 27830, 387e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 27883, 27935, 27988, 28039, 28090, 28141, 28191, 28241, 388e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 28291, 28340, 28388, 28437, 28484, 28532, 28579, 28626, 389e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 28672 390e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 391e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 392e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// determinant of estimation matrix in Q0 corresponding to the log2 tables above 393e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Note that the first table value is invalid, since log2(0) = -infinity 394e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentstatic const WebRtc_Word16 kDeterminantEstMatrix[66] = { 395e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0, 29814, 25574, 22640, 20351, 18469, 16873, 15491, 396e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14277, 13199, 12233, 11362, 10571, 9851, 9192, 8587, 397e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 8030, 7515, 7038, 6596, 6186, 5804, 5448, 5115, 398e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 4805, 4514, 4242, 3988, 3749, 3524, 3314, 3116, 399e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2930, 2755, 2590, 2435, 2289, 2152, 2022, 1900, 400e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1785, 1677, 1575, 1478, 1388, 1302, 1221, 1145, 401e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1073, 1005, 942, 881, 825, 771, 721, 674, 402e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 629, 587, 547, 510, 475, 442, 411, 382, 403e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 355, 330 404e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}; 405e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 406e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_UpdateNoiseEstimate(NsxInst_t *inst, int offset) 407e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 408e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no1 = 0; 409e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no2 = 0; 410e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 411e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16no1 = 0; 412e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16no2 = 0; 413e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 exp2Const = 11819; // Q13 414e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 415e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i = 0; 416e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 417e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = WebRtcSpl_MaxValueW16(inst->noiseEstLogQuantile + offset, inst->magnLen); 418e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->qNoise = 14 419e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - (int)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(exp2Const, tmp16no2, 21); 420e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 421e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 422e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // inst->quantile[i]=exp(inst->lquantile[offset+i]); 423e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // in Q21 424e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_MUL_16_16(exp2Const, inst->noiseEstLogQuantile[offset + i]); 425e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF)); 426e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no2, 21); 427e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 += 21;// shift 21 to get result in Q0 428e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 -= (WebRtc_Word16)inst->qNoise; //shift to get result in Q(qNoise) 429e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmp16no1 > 0) 430e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 431e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1 + 432e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent kRoundTable[tmp16no1], tmp16no1); 433e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 434e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 435e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 436e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32no1, 437e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent -tmp16no1); 438e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 439e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 440e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 441e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 442e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_CalcParametricNoiseEstimate(NsxInst_t *inst, 443e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 pink_noise_exp_avg, 444e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 pink_noise_num_avg, 445e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int freq_index, 446e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 *noise_estimate, 447e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 *noise_estimate_avg) 448e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 449e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no1 = 0; 450e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no2 = 0; 451e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 452e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 int_part = 0; 453e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 frac_part = 0; 454e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 455e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Use pink noise estimate 456e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // noise_estimate = 2^(pinkNoiseNumerator + pinkNoiseExp * log2(j)) 457e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(freq_index > 0); 458e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_MUL_16_16(pink_noise_exp_avg, kLogIndex[freq_index]); // Q26 459e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 15); // Q11 460e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 461e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 462e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate output: 2^tmp32no1 463e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Output in Q(minNorm-stages) 464e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(inst->minNorm - inst->stages), 11); 465e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmp32no1 > 0) 466e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 467e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int_part = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 11); 468e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac_part = (WebRtc_Word16)(tmp32no1 & 0x000007ff); // Q11 469e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Piecewise linear approximation of 'b' in 470e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 2^(int_part+frac_part) = 2^int_part * (1 + b) 471e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 'b' is given in Q11 and below stored in frac_part. 472e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WEBRTC_SPL_RSHIFT_W32(frac_part, 10)) 473e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 474e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Upper fractional part 475e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_MUL_32_16(2048 - frac_part, 1244); // Q21 476e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = 2048 - WEBRTC_SPL_RSHIFT_W32(tmp32no2, 10); 477e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 478e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 479e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 480e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Lower fractional part 481e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(frac_part, 804), 10); 482e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 483e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift fractional part to Q(minNorm-stages) 484e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_SHIFT_W32(tmp32no2, int_part - 11); 485e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *noise_estimate_avg = WEBRTC_SPL_LSHIFT_U32(1, int_part) + (WebRtc_UWord32)tmp32no2; 486e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Scale up to initMagnEst, which is not block averaged 487e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *noise_estimate = (*noise_estimate_avg) * (WebRtc_UWord32)(inst->blockIndex + 1); 488e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 489e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 490e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 491e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Initialize state 492e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentWebRtc_Word32 WebRtcNsx_InitCore(NsxInst_t *inst, WebRtc_UWord32 fs) 493e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 494e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i; 495e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 496e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //check for valid pointer 497e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst == NULL) 498e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 499e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 500e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 501e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 502e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 503e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Initialization of struct 504e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (fs == 8000 || fs == 16000 || fs == 32000) 505e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 506e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->fs = fs; 507e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 508e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 509e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 510e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 511e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 512e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (fs == 8000) 513e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 514e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockLen10ms = 80; 515e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen = 128; 516e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->stages = 7; 517e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->window = kBlocks80w128x; 518e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdLogLrt = 131072; //default threshold for LRT feature 519e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->maxLrt = 0x0040000; 520e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->minLrt = 52429; 521e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (fs == 16000) 522e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 523e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockLen10ms = 160; 524e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen = 256; 525e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->stages = 8; 526e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->window = kBlocks160w256x; 527e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdLogLrt = 212644; //default threshold for LRT feature 528e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->maxLrt = 0x0080000; 529e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->minLrt = 104858; 530e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (fs == 32000) 531e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 532e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockLen10ms = 160; 533e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen = 256; 534e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->stages = 8; 535e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->window = kBlocks160w256x; 536e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdLogLrt = 212644; //default threshold for LRT feature 537e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->maxLrt = 0x0080000; 538e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->minLrt = 104858; 539e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 540e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen2 = WEBRTC_SPL_RSHIFT_W16(inst->anaLen, 1); 541e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->magnLen = inst->anaLen2 + 1; 542e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 543e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->analysisBuffer, ANAL_BLOCKL_MAX); 544e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer, ANAL_BLOCKL_MAX); 545e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 546e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // for HB processing 547e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->dataBufHBFX, ANAL_BLOCKL_MAX); 548e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // for quantile noise estimation 549e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->noiseEstQuantile, HALF_ANAL_BLOCKL); 550e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) 551e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 552e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstLogQuantile[i] = 2048; // Q8 553e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstDensity[i] = 153; // Q9 554e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 555e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < SIMULT; i++) 556e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 557e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstCounter[i] = (WebRtc_Word16)(END_STARTUP_LONG * (i + 1)) / SIMULT; 558e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 559e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 560e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Initialize suppression filter with ones 561e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_MemSetW16((WebRtc_Word16*)inst->noiseSupFilter, 16384, HALF_ANAL_BLOCKL); 562e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 563e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Set the aggressiveness: default 564e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->aggrMode = 0; 565e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 566e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //initialize variables for new method 567e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->priorNonSpeechProb = 8192; // Q14(0.5) prior probability for speech/noise 568e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < HALF_ANAL_BLOCKL; i++) 569e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 570e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevMagnU16[i] = 0; 571e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevNoiseU32[i] = 0; //previous noise-spectrum 572e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->logLrtTimeAvgW32[i] = 0; //smooth LR ratio 573e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->avgMagnPause[i] = 0; //conservative noise spectrum estimate 574e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[i] = 0; //initial average magnitude spectrum 575e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 576e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 577e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //feature quantities 578e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdSpecDiff = 50; //threshold for difference feature: determined on-line 579e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdSpecFlat = 20480; //threshold for flatness: determined on-line 580e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureLogLrt = inst->thresholdLogLrt; //average LRT factor (= threshold) 581e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecFlat = inst->thresholdSpecFlat; //spectral flatness (= threshold) 582e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecDiff = inst->thresholdSpecDiff; //spectral difference (= threshold) 583e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightLogLrt = 6; //default weighting par for LRT feature 584e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightSpecFlat = 0; //default weighting par for spectral flatness feature 585e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightSpecDiff = 0; //default weighting par for spectral difference feature 586e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 587e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->curAvgMagnEnergy = 0; //window time-average of input magnitude spectrum 588e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergy = 0; //normalization for spectral difference 589e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergyTmp = 0; //normalization for spectral difference 590e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 591e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //histogram quantities: used to estimate/update thresholds for features 592e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST); 593e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST); 594e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST); 595e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 596e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockIndex = -1; //frame counter 597e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 598e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //inst->modelUpdate = 500; //window for update 599e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->modelUpdate = (1 << STAT_UPDATES); //window for update 600e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->cntThresUpdate = 0; //counter feature thresholds updates 601e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 602e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->sumMagn = 0; 603e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->magnEnergy = 0; 604e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevQMagn = 0; 605e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->qNoise = 0; 606e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevQNoise = 0; 607e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 608e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->energyIn = 0; 609e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->scaleEnergyIn = 0; 610e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 611e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->whiteNoiseLevel = 0; 612e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->pinkNoiseNumerator = 0; 613e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->pinkNoiseExp = 0; 614e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->minNorm = 15; // Start with full scale 615e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->zeroInputSignal = 0; 616e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 617e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //default mode 618e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_set_policy_core(inst, 0); 619e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 620e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef NS_FILEDEBUG 621e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->infile=fopen("indebug.pcm","wb"); 622e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->outfile=fopen("outdebug.pcm","wb"); 623e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->file1=fopen("file1.pcm","wb"); 624e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->file2=fopen("file2.pcm","wb"); 625e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->file3=fopen("file3.pcm","wb"); 626e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->file4=fopen("file4.pcm","wb"); 627e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->file5=fopen("file5.pcm","wb"); 628e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 629e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 630e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initFlag = 1; 631e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 632e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 633e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 634e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 635e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint WebRtcNsx_set_policy_core(NsxInst_t *inst, int mode) 636e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 637e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // allow for modes:0,1,2,3 638e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (mode < 0 || mode > 3) 639e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 640e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 641e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 642e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 643e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->aggrMode = mode; 644e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (mode == 0) 645e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 646e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->overdrive = 256; // Q8(1.0) 647e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->denoiseBound = 8192; // Q14(0.5) 648e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->gainMap = 0; // No gain compensation 649e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (mode == 1) 650e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 651e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->overdrive = 256; // Q8(1.0) 652e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->denoiseBound = 4096; // Q14(0.25) 653e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->factor2Table = kFactor2Aggressiveness1; 654e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->gainMap = 1; 655e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (mode == 2) 656e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 657e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->overdrive = 282; // ~= Q8(1.1) 658e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->denoiseBound = 2048; // Q14(0.125) 659e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->factor2Table = kFactor2Aggressiveness2; 660e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->gainMap = 1; 661e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (mode == 3) 662e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 663e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->overdrive = 320; // Q8(1.25) 664e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->denoiseBound = 1475; // ~= Q14(0.09) 665e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->factor2Table = kFactor2Aggressiveness3; 666e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->gainMap = 1; 667e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 668e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 669e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 670e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 671e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_NoiseEstimation(NsxInst_t *inst, WebRtc_UWord16 *magn, WebRtc_UWord32 *noise, 672e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 *qNoise) 673e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 674e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 numerator; 675e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 676e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 lmagn[HALF_ANAL_BLOCKL], counter, countDiv, countProd, delta, zeros, frac; 677e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 log2, tabind, logval, tmp16, tmp16no1, tmp16no2; 678e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 log2Const = 22713; // Q15 679e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 widthFactor = 21845; 680e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 681e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i, s, offset; 682e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 683e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numerator = FACTOR_Q16; 684e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 685e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tabind = inst->stages - inst->normData; 686e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tabind < 0) 687e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 688e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logval = -kLogTable[-tabind]; 689e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 690e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 691e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logval = kLogTable[tabind]; 692e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 693e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 694e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // lmagn(i)=log(magn(i))=log(2)*log2(magn(i)) 695e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // magn is in Q(-stages), and the real lmagn values are: 696e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages) 697e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // lmagn in Q8 698e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 699e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 700e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (magn[i]) 701e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 702e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]); 703e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)((((WebRtc_UWord32)magn[i] << zeros) & 0x7FFFFFFF) >> 23); 704e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(magn(i)) 705e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); 706e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(magn(i))*log(2) 707e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lmagn[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2, log2Const, 15); 708e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // + log(2^stages) 709e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lmagn[i] += logval; 710e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 711e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 712e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lmagn[i] = logval;//0; 713e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 714e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 715e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 716e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // loop over simultaneous estimates 717e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (s = 0; s < SIMULT; s++) 718e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 719e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent offset = s * inst->magnLen; 720e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 721e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Get counter values from state 722e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent counter = inst->noiseEstCounter[s]; 723e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent countDiv = kCounterDiv[counter]; 724e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent countProd = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(counter, countDiv); 725e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 726e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // quant_est(...) 727e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 728e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 729e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute delta 730e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->noiseEstDensity[offset + i] > 512) 731e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 732e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delta = WebRtcSpl_DivW32W16ResW16(numerator, 733e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstDensity[offset + i]); 734e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 735e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 736e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delta = FACTOR_Q7; 737e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 738e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 739e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update log quantile estimate 740e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delta, countDiv, 14); 741e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (lmagn[i] > inst->noiseEstLogQuantile[offset + i]) 742e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 743e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // +=QUANTILE*delta/(inst->counter[s]+1) QUANTILE=0.25, =1 in Q2 744e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // CounterDiv=1/inst->counter[s] in Q15 745e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16 += 2; 746e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 2); 747e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstLogQuantile[offset + i] += tmp16no1; 748e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 749e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 750e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16 += 1; 751e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 1); 752e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // *(1-QUANTILE), in Q2 QUANTILE=0.25, 1-0.25=0.75=3 in Q2 753e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, 3, 1); 754e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstLogQuantile[offset + i] -= tmp16no2; 755e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 756e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 757e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update density estimate 758e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i]) 759e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent < WIDTH_Q8) 760e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 761e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( 762e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstDensity[offset + i], countProd, 15); 763e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(widthFactor, 764e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent countDiv, 15); 765e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2; 766e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 767e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end loop over magnitude spectrum 768e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 769e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (counter >= END_STARTUP_LONG) 770e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 771e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstCounter[s] = 0; 772e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex >= END_STARTUP_LONG) 773e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 774e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_UpdateNoiseEstimate(inst, offset); 775e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 776e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 777e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseEstCounter[s]++; 778e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 779e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end loop over simultaneous estimates 780e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 781e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Sequentially update the noise during startup 782e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_LONG) 783e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 784e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_UpdateNoiseEstimate(inst, offset); 785e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 786e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 787e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 788e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 789e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise[i] = (WebRtc_UWord32)(inst->noiseEstQuantile[i]); // Q(qNoise) 790e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 791e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (*qNoise) = (WebRtc_Word16)inst->qNoise; 792e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 793e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 794e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Extract thresholds for feature parameters 795e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// histograms are computed over some window_size (given by window_pars) 796e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// thresholds and weights are extracted every window 797e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// flag 0 means update histogram only, flag 1 means compute the thresholds/weights 798e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// threshold and weights are returned in: inst->priorModelPars 799e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_FeatureParameterExtraction(NsxInst_t *inst, int flag) 800e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 801e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpU32; 802e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 histIndex; 803e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 posPeak1SpecFlatFX, posPeak2SpecFlatFX; 804e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 posPeak1SpecDiffFX, posPeak2SpecDiffFX; 805e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 806e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32; 807e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 fluctLrtFX, thresFluctLrtFX; 808e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 avgHistLrtFX, avgSquareHistLrtFX, avgHistLrtComplFX; 809e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 810e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 j; 811e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 numHistLrt; 812e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 813e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i; 814e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int useFeatureSpecFlat, useFeatureSpecDiff, featureSum; 815e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int maxPeak1, maxPeak2; 816e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int weightPeak1SpecFlat, weightPeak2SpecFlat; 817e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int weightPeak1SpecDiff, weightPeak2SpecDiff; 818e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 819e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //update histograms 820e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (!flag) 821e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 822e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // LRT 823e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Type casting to UWord32 is safe since negative values will not be wrapped to larger 824e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // values than HIST_PAR_EST 825e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent histIndex = (WebRtc_UWord32)(inst->featureLogLrt); 826e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (histIndex < HIST_PAR_EST) 827e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 828e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->histLrt[histIndex]++; 829e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 830e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Spectral flatness 831e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // (inst->featureSpecFlat*20)>>10 = (inst->featureSpecFlat*5)>>8 832e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent histIndex = WEBRTC_SPL_RSHIFT_U32(inst->featureSpecFlat * 5, 8); 833e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (histIndex < HIST_PAR_EST) 834e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 835e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->histSpecFlat[histIndex]++; 836e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 837e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Spectral difference 838e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent histIndex = HIST_PAR_EST; 839e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->timeAvgMagnEnergy) 840e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 841e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Guard against division by zero 842e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // If timeAvgMagnEnergy == 0 we have no normalizing statistics and therefore can't 843e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update the histogram 844e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent histIndex = WEBRTC_SPL_UDIV((inst->featureSpecDiff * 5) >> inst->stages, 845e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergy); 846e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 847e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (histIndex < HIST_PAR_EST) 848e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 849e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->histSpecDiff[histIndex]++; 850e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 851e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 852e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 853e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // extract parameters for speech/noise probability 854e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (flag) 855e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 856e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent useFeatureSpecDiff = 1; 857e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //for LRT feature: 858e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute the average over inst->featureExtractionParams.rangeAvgHistLrt 859e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgHistLrtFX = 0; 860e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSquareHistLrtFX = 0; 861e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numHistLrt = 0; 862e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < BIN_SIZE_LRT; i++) 863e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 864e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = (2 * i + 1); 865e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j); 866e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgHistLrtFX += tmp32; 867e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numHistLrt += inst->histLrt[i]; 868e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j); 869e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 870e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgHistLrtComplFX = avgHistLrtFX; 871e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (; i < HIST_PAR_EST; i++) 872e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 873e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = (2 * i + 1); 874e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j); 875e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgHistLrtComplFX += tmp32; 876e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j); 877e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 878e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fluctLrtFX = WEBRTC_SPL_MUL(avgSquareHistLrtFX, numHistLrt); 879e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fluctLrtFX -= WEBRTC_SPL_MUL(avgHistLrtFX, avgHistLrtComplFX); 880e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent thresFluctLrtFX = THRES_FLUCT_LRT * numHistLrt; 881e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // get threshold for LRT feature: 882e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32 = (FACTOR_1_LRT_DIFF * (WebRtc_UWord32)avgHistLrtFX); 883e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((fluctLrtFX < thresFluctLrtFX) || (numHistLrt == 0) || (tmpU32 884e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent > (WebRtc_UWord32)(100 * numHistLrt))) 885e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 886e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdLogLrt = inst->maxLrt; //very low fluctuation, so likely noise 887e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 888e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 889e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = (WebRtc_Word32)((tmpU32 << (9 + inst->stages)) / numHistLrt / 25); 890e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // check if value is within min/max range 891e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdLogLrt = WEBRTC_SPL_SAT(inst->maxLrt, tmp32, inst->minLrt); 892e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 893e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (fluctLrtFX < thresFluctLrtFX) 894e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 895e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Do not use difference feature if fluctuation of LRT feature is very low: 896e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // most likely just noise state 897e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent useFeatureSpecDiff = 0; 898e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 899e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 900e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // for spectral flatness and spectral difference: compute the main peaks of histogram 901e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak1 = 0; 902e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = 0; 903e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecFlatFX = 0; 904e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecFlatFX = 0; 905e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecFlat = 0; 906e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecFlat = 0; 907e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 908e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // peaks for flatness 909e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < HIST_PAR_EST; i++) 910e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 911e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->histSpecFlat[i] > maxPeak1) 912e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 913e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Found new "first" peak 914e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = maxPeak1; 915e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecFlat = weightPeak1SpecFlat; 916e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecFlatFX = posPeak1SpecFlatFX; 917e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 918e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak1 = inst->histSpecFlat[i]; 919e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecFlat = inst->histSpecFlat[i]; 920e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecFlatFX = (WebRtc_UWord32)(2 * i + 1); 921e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (inst->histSpecFlat[i] > maxPeak2) 922e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 923e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Found new "second" peak 924e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = inst->histSpecFlat[i]; 925e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecFlat = inst->histSpecFlat[i]; 926e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecFlatFX = (WebRtc_UWord32)(2 * i + 1); 927e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 928e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 929e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 930e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // for spectral flatness feature 931e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent useFeatureSpecFlat = 1; 932e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // merge the two peaks if they are close 933e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((posPeak1SpecFlatFX - posPeak2SpecFlatFX < LIM_PEAK_SPACE_FLAT_DIFF) 934e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent && (weightPeak2SpecFlat * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecFlat)) 935e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 936e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecFlat += weightPeak2SpecFlat; 937e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecFlatFX = (posPeak1SpecFlatFX + posPeak2SpecFlatFX) >> 1; 938e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 939e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //reject if weight of peaks is not large enough, or peak value too small 940e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (weightPeak1SpecFlat < THRES_WEIGHT_FLAT_DIFF || posPeak1SpecFlatFX 941e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent < THRES_PEAK_FLAT) 942e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 943e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent useFeatureSpecFlat = 0; 944e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else // if selected, get the threshold 945e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 946e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute the threshold and check if value is within min/max range 947e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdSpecFlat = WEBRTC_SPL_SAT(MAX_FLAT_Q10, FACTOR_2_FLAT_Q10 948e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * posPeak1SpecFlatFX, MIN_FLAT_Q10); //Q10 949e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 950e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with flatness feature 951e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 952e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (useFeatureSpecDiff) 953e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 954e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute two peaks for spectral difference 955e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak1 = 0; 956e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = 0; 957e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecDiffFX = 0; 958e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecDiffFX = 0; 959e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecDiff = 0; 960e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecDiff = 0; 961e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // peaks for spectral difference 962e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < HIST_PAR_EST; i++) 963e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 964e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->histSpecDiff[i] > maxPeak1) 965e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 966e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Found new "first" peak 967e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = maxPeak1; 968e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecDiff = weightPeak1SpecDiff; 969e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecDiffFX = posPeak1SpecDiffFX; 970e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 971e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak1 = inst->histSpecDiff[i]; 972e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecDiff = inst->histSpecDiff[i]; 973e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecDiffFX = (WebRtc_UWord32)(2 * i + 1); 974e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (inst->histSpecDiff[i] > maxPeak2) 975e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 976e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Found new "second" peak 977e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPeak2 = inst->histSpecDiff[i]; 978e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak2SpecDiff = inst->histSpecDiff[i]; 979e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak2SpecDiffFX = (WebRtc_UWord32)(2 * i + 1); 980e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 981e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 982e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 983e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // merge the two peaks if they are close 984e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((posPeak1SpecDiffFX - posPeak2SpecDiffFX < LIM_PEAK_SPACE_FLAT_DIFF) 985e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent && (weightPeak2SpecDiff * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecDiff)) 986e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 987e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent weightPeak1SpecDiff += weightPeak2SpecDiff; 988e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent posPeak1SpecDiffFX = (posPeak1SpecDiffFX + posPeak2SpecDiffFX) >> 1; 989e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 990e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // get the threshold value and check if value is within min/max range 991e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->thresholdSpecDiff = WEBRTC_SPL_SAT(MAX_DIFF, FACTOR_1_LRT_DIFF 992e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * posPeak1SpecDiffFX, MIN_DIFF); //5x bigger 993e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //reject if weight of peaks is not large enough 994e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (weightPeak1SpecDiff < THRES_WEIGHT_FLAT_DIFF) 995e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 996e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent useFeatureSpecDiff = 0; 997e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 998e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with spectral difference feature 999e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1000e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1001e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // select the weights between the features 1002e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // inst->priorModelPars[4] is weight for LRT: always selected 1003e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent featureSum = 6 / (1 + useFeatureSpecFlat + useFeatureSpecDiff); 1004e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightLogLrt = featureSum; 1005e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightSpecFlat = useFeatureSpecFlat * featureSum; 1006e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->weightSpecDiff = useFeatureSpecDiff * featureSum; 1007e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1008e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // set histograms to zero for next update 1009e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST); 1010e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST); 1011e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST); 1012e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of flag == 1 1013e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1014e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1015e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1016e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Compute spectral flatness on input spectrum 1017e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// magn is the magnitude spectrum 1018e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// spectral flatness is returned in inst->featureSpecFlat 1019e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_ComputeSpectralFlatness(NsxInst_t *inst, WebRtc_UWord16 *magn) 1020e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1021e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpU32; 1022e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 avgSpectralFlatnessNum, avgSpectralFlatnessDen; 1023e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1024e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32; 1025e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 currentSpectralFlatness, logCurSpectralFlatness; 1026e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1027e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 zeros, frac, intPart; 1028e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1029e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i; 1030e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1031e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // for flatness 1032e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSpectralFlatnessNum = 0; 1033e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSpectralFlatnessDen = inst->sumMagn - (WebRtc_UWord32)magn[0]; // Q(normData-stages) 1034e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1035e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute log of ratio of the geometric to arithmetic mean: check for log(0) case 1036e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) 1037e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // = exp( sum(log(magn[i]))/N ) * N / sum(magn[i]) 1038e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [This is used] 1039e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 1; i < inst->magnLen; i++) 1040e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1041e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // First bin is excluded from spectrum measures. Number of bins is now a power of 2 1042e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (magn[i]) 1043e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1044e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]); 1045e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_UWord32)(magn[i]) << zeros) 1046e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent & 0x7FFFFFFF) >> 23); 1047e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(magn(i)) 1048e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32 = (WebRtc_UWord32)(((31 - zeros) << 8) + kLogTableFrac[frac]); // Q8 1049e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgSpectralFlatnessNum += tmpU32; // Q8 1050e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1051e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1052e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //if at least one frequency component is zero, treat separately 1053e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14); // Q24 1054e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecFlat -= WEBRTC_SPL_RSHIFT_U32(tmpU32, 14); // Q10 1055e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return; 1056e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1057e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1058e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //ratio and inverse log: check for case of log(0) 1059e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen); 1060e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23); 1061e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(avgSpectralFlatnessDen) 1062e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = (WebRtc_Word32)(((31 - zeros) << 8) + kLogTableFrac[frac]); // Q8 1063e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logCurSpectralFlatness = (WebRtc_Word32)avgSpectralFlatnessNum; 1064e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logCurSpectralFlatness += ((WebRtc_Word32)(inst->stages - 1) << (inst->stages + 7)); // Q(8+stages-1) 1065e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logCurSpectralFlatness -= (tmp32 << (inst->stages - 1)); 1066e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logCurSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(logCurSpectralFlatness, 10 - inst->stages); // Q17 1067e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = (WebRtc_Word32)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) 1068e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent & 0x0001FFFF)); //Q17 1069e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent intPart = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(logCurSpectralFlatness, 17); 1070e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent intPart += 7; // Shift 7 to get the output in Q10 (from Q17 = -17+10) 1071e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (intPart > 0) 1072e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1073e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent currentSpectralFlatness = WEBRTC_SPL_RSHIFT_W32(tmp32, intPart); 1074e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1075e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1076e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent currentSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(tmp32, -intPart); 1077e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1078e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1079e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //time average update of spectral flatness feature 1080e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = currentSpectralFlatness - (WebRtc_Word32)inst->featureSpecFlat; // Q10 1081e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = WEBRTC_SPL_MUL_32_16(SPECT_FLAT_TAVG_Q14, tmp32); // Q24 1082e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecFlat = (WebRtc_UWord32)((WebRtc_Word32)inst->featureSpecFlat 1083e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + WEBRTC_SPL_RSHIFT_W32(tmp32, 14)); // Q10 1084e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with flatness feature 1085e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1086e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1087e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1088e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Compute the difference measure between input spectrum and a template/learned noise spectrum 1089e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// magn_tmp is the input spectrum 1090e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// the reference/template spectrum is inst->magn_avg_pause[i] 1091e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// returns (normalized) spectral difference in inst->featureSpecDiff 1092e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_ComputeSpectralDifference(NsxInst_t *inst, WebRtc_UWord16 *magnIn) 1093e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1094e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // This is to be calculated: 1095e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause) 1096e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1097e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpU32no1, tmpU32no2; 1098e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 varMagnUFX, varPauseUFX, avgDiffNormMagnUFX; 1099e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no1, tmp32no2; 1101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 avgPauseFX, avgMagnFX, covMagnPauseFX; 1102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 maxPause, minPause; 1103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16no1; 1105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i, norm32, nShifts; 1107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgPauseFX = 0; 1109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPause = 0; 1110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent minPause = inst->avgMagnPause[0]; // Q(prevQMagn) 1111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute average quantities 1112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Compute mean of magn_pause 1115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgPauseFX += inst->avgMagnPause[i]; // in Q(prevQMagn) 1116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxPause = WEBRTC_SPL_MAX(maxPause, inst->avgMagnPause[i]); 1117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent minPause = WEBRTC_SPL_MIN(minPause, inst->avgMagnPause[i]); 1118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // normalize by replacing div of "inst->magnLen" with "inst->stages-1" shifts 1120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgPauseFX = WEBRTC_SPL_RSHIFT_W32(avgPauseFX, inst->stages - 1); 1121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgMagnFX = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(inst->sumMagn, inst->stages - 1); 1122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Largest possible deviation in magnPause for (co)var calculations 1123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MAX(maxPause - avgPauseFX, avgPauseFX - minPause); 1124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Get number of shifts to make sure we don't get wrap around in varPause 1125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = WEBRTC_SPL_MAX(0, 10 + inst->stages - WebRtcSpl_NormW32(tmp32no1)); 1126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent varMagnUFX = 0; 1128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent varPauseUFX = 0; 1129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent covMagnPauseFX = 0; 1130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Compute var and cov of magn and magn_pause 1133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = (WebRtc_Word16)((WebRtc_Word32)magnIn[i] - avgMagnFX); 1134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = inst->avgMagnPause[i] - avgPauseFX; 1135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent varMagnUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); // Q(2*qMagn) 1136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no2, tmp16no1); // Q(prevQMagn+qMagn) 1137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent covMagnPauseFX += tmp32no1; // Q(prevQMagn+qMagn) 1138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, nShifts); // Q(prevQMagn-minPause) 1139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent varPauseUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL(tmp32no1, tmp32no1); // Q(2*(prevQMagn-minPause)) 1140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //update of average magnitude spectrum: Q(-2*stages) and averaging replaced by shifts 1142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->curAvgMagnEnergy += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy, 2 * inst->normData 1143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + inst->stages - 1); 1144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgDiffNormMagnUFX = varMagnUFX; // Q(2*qMagn) 1146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((varPauseUFX) && (covMagnPauseFX)) 1147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_ABS_W32(covMagnPauseFX); // Q(prevQMagn+qMagn) 1149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32 = WebRtcSpl_NormU32(tmpU32no1) - 16; 1150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (norm32 > 0) 1151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32); // Q(prevQMagn+qMagn+norm32) 1153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, -norm32); // Q(prevQMagn+qMagn+norm32) 1156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL(tmpU32no1, tmpU32no1); // Q(2*(prevQMagn+qMagn-norm32)) 1158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts += norm32; 1160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts <<= 1; 1161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (nShifts < 0) 1162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent varPauseUFX >>= (-nShifts); // Q(2*(qMagn+norm32+minPause)) 1164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 0; 1165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no2, varPauseUFX); // Q(2*(qMagn+norm32-16+minPause)) 1167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, nShifts); 1168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgDiffNormMagnUFX -= WEBRTC_SPL_MIN(avgDiffNormMagnUFX, tmpU32no1); // Q(2*qMagn) 1170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //normalize and compute time average update of difference feature 1172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(avgDiffNormMagnUFX, 2 * inst->normData); 1173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->featureSpecDiff > tmpU32no1) 1174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecDiff - tmpU32no1, 1176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) 1177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecDiff -= WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages) 1178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1180e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no1 - inst->featureSpecDiff, 1181e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) 1182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecDiff += WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages) 1183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Compute speech/noise probability 1187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// speech/noise probability is returned in: probSpeechFinal 1188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent//snrLocPrior is the prior SNR for each frequency (in Q11) 1189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent//snrLocPost is the post SNR for each frequency (in Q11) 1190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_SpeechNoiseProb(NsxInst_t *inst, WebRtc_UWord16 *nonSpeechProbFinal, 1191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 *priorLocSnr, WebRtc_UWord32 *postLocSnr) 1192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 zeros, num, den, tmpU32no1, tmpU32no2, tmpU32no3; 1194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 invLrtFX, indPriorFX, tmp32, tmp32no1, tmp32no2, besselTmpFX32; 1196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 frac32, logTmp; 1197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 logLrtTimeAvgKsumFX; 1198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 indPriorFX16; 1200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16, tmp16no1, tmp16no2, tmpIndFX, tableIndex, frac, intPart; 1201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i, normTmp, normTmp2, nShifts; 1203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute feature based on average LR factor 1205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // this is the average over all frequencies of the smooth log LRT 1206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logLrtTimeAvgKsumFX = 0; 1207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1208e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent besselTmpFX32 = (WebRtc_Word32)postLocSnr[i]; // Q11 1210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent normTmp = WebRtcSpl_NormU32(postLocSnr[i]); 1211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent num = WEBRTC_SPL_LSHIFT_U32(postLocSnr[i], normTmp); // Q(11+normTmp) 1212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (normTmp > 10) 1213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent den = WEBRTC_SPL_LSHIFT_U32(priorLocSnr[i], normTmp - 11); // Q(normTmp) 1215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1216e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent den = WEBRTC_SPL_RSHIFT_U32(priorLocSnr[i], 11 - normTmp); // Q(normTmp) 1218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent besselTmpFX32 -= WEBRTC_SPL_UDIV(num, den); // Q11 1220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - log(snrLocPrior) - inst->logLrtTimeAvg[i]); 1222e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Here, LRT_TAVG = 0.5 1223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32(priorLocSnr[i]); 1224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac32 = (WebRtc_Word32)(((priorLocSnr[i] << zeros) & 0x7FFFFFFF) >> 19); 1225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = WEBRTC_SPL_MUL(frac32, frac32); 1226e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(tmp32, -43), 19); 1227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)frac32, 5412, 12); 1228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac32 = tmp32 + 37; 1229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // tmp32 = log2(priorLocSnr[i]) 1230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32 = (WebRtc_Word32)(((31 - zeros) << 12) + frac32) - (11 << 12); // Q12 1231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logTmp = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(tmp32, 178), 8); // log2(priorLocSnr[i])*log(2) 1232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_RSHIFT_W32(logTmp + inst->logLrtTimeAvgW32[i], 1); // Q12 1233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->logLrtTimeAvgW32[i] += (besselTmpFX32 - tmp32no1); // Q12 1234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent logLrtTimeAvgKsumFX += inst->logLrtTimeAvgW32[i]; // Q12 1236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureLogLrt = WEBRTC_SPL_RSHIFT_W32(logLrtTimeAvgKsumFX * 5, inst->stages + 10); // 5 = BIN_SIZE_LRT / 2 1238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with computation of LR factor 1239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1240e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 1241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute the indicator functions 1242e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 1243e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // average LRT feature 1245e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 1246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // indicator0 = 0.5 * (tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0)) + 1.0); 1247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 16384; // Q14(1.0) 1248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = logLrtTimeAvgKsumFX - inst->thresholdLogLrt; // Q12 1249e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 7 - inst->stages; // WIDTH_PR_MAP_SHIFT - inst->stages + 5; 1250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //use larger width in tanh map for pause regions 1251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmp32no1 < 0) 1252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1253e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 0; 1254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = -tmp32no1; 1255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //widthPrior = widthPrior * 2.0; 1256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts++; 1257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_SHIFT_W32(tmp32no1, nShifts); // Q14 1259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute indicator function: sigmoid map 1260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 14); 1261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((tableIndex < 16) && (tableIndex >= 0)) 1262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = kIndicatorTable[tableIndex]; 1264e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; 1265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(tmp32no1 & 0x00003fff); // Q14 1266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14); 1267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpIndFX == 0) 1268e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 - tmp16no2; // Q14 1270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 + tmp16no2; // Q14 1273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent indPriorFX = WEBRTC_SPL_MUL_16_16(inst->weightLogLrt, tmpIndFX); // 6*Q14 1276e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //spectral flatness feature 1278e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->weightSpecFlat) 1279e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1280e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL(inst->featureSpecFlat, 400); // Q10 1281e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 16384; // Q14(1.0) 1282e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //use larger width in tanh map for pause regions 1283e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = inst->thresholdSpecFlat - tmpU32no1; //Q10 1284e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 4; 1285e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->thresholdSpecFlat < tmpU32no1) 1286e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1287e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 0; 1288e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = tmpU32no1 - inst->thresholdSpecFlat; 1289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //widthPrior = widthPrior * 2.0; 1290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts++; 1291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = (WebRtc_Word32)WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2, 1293e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts), 25); //Q14 1294e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2, nShifts), 25); //Q14 1295e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute indicator function: sigmoid map 1296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 1297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // indicator1 = 0.5 * (tanh(sgnMap * widthPrior * (threshPrior1 - tmpFloat1)) + 1.0); 1298e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14); 1299e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tableIndex < 16) 1300e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = kIndicatorTable[tableIndex]; 1302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; 1303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14 1304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14); 1305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpIndFX) 1306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 + tmp16no2; // Q14 1308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 - tmp16no2; // Q14 1311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecFlat, tmpIndFX); // 6*Q14 1314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //for template spectral-difference 1317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->weightSpecDiff) 1318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = 0; 1320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->featureSpecDiff) 1321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent normTmp = WEBRTC_SPL_MIN(20 - inst->stages, 1323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_NormU32(inst->featureSpecDiff)); 1324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(inst->featureSpecDiff, normTmp); // Q(normTmp-2*stages) 1325e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->timeAvgMagnEnergy, 20 - inst->stages 1326e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - normTmp); 1327e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no2) 1328e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1329e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q14?? Q(20 - inst->stages) 1330e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1331e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1332e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = (WebRtc_UWord32)(0x7fffffff); 1333e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1334e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1335e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = WEBRTC_SPL_UDIV(WEBRTC_SPL_LSHIFT_U32(inst->thresholdSpecDiff, 17), 25); 1336e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = tmpU32no1 - tmpU32no3; 1337e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 1; 1338e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 16384; // Q14(1.0) 1339e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //use larger width in tanh map for pause regions 1340e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no2 & 0x80000000) 1341e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1342e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 0; 1343e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = tmpU32no3 - tmpU32no1; 1344e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //widthPrior = widthPrior * 2.0; 1345e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts--; 1346e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1347e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, nShifts); 1348e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute indicator function: sigmoid map 1349e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent /* FLOAT code 1350e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent indicator2 = 0.5 * (tanh(widthPrior * (tmpFloat1 - threshPrior2)) + 1.0); 1351e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */ 1352e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14); 1353e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tableIndex < 16) 1354e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1355e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = kIndicatorTable[tableIndex]; 1356e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; 1357e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14 1358e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, frac, 1359e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14); 1360e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpIndFX) 1361e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1362e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 + tmp16no2; 1363e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1364e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1365e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpIndFX = 8192 - tmp16no2; 1366e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1367e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1368e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecDiff, tmpIndFX); // 6*Q14 1369e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1370e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1371e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //combine the indicator function with the feature weights 1372e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 1373e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // indPrior = 1 - (weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 + weightIndPrior2 * indicator2); 1374e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent indPriorFX16 = WebRtcSpl_DivW32W16ResW16(98307 - indPriorFX, 6); // Q14 1375e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with computing indicator function 1376e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1377e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute the prior probability 1378e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 1379e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // inst->priorNonSpeechProb += PRIOR_UPDATE * (indPriorNonSpeech - inst->priorNonSpeechProb); 1380e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16 = indPriorFX16 - inst->priorNonSpeechProb; // Q14 1381e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->priorNonSpeechProb += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PRIOR_UPDATE_Q14, 1382e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16, 14); // Q14 1383e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1384e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //final speech probability: combine prior model with LR factor: 1385e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1386e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1387e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 1388e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // invLrt = exp(inst->logLrtTimeAvg[i]); 1389e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // invLrt = inst->priorSpeechProb * invLrt; 1390e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // nonSpeechProbFinal[i] = (1.0 - inst->priorSpeechProb) / (1.0 - inst->priorSpeechProb + invLrt); 1391e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // invLrt = (1.0 - inst->priorNonSpeechProb) * invLrt; 1392e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // nonSpeechProbFinal[i] = inst->priorNonSpeechProb / (inst->priorNonSpeechProb + invLrt); 1393e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nonSpeechProbFinal[i] = 0; // Q8 1394e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((inst->logLrtTimeAvgW32[i] < 65300) && (inst->priorNonSpeechProb > 0)) 1395e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1396e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(inst->logLrtTimeAvgW32[i], 23637), 1397e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14); // Q12 1398e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent intPart = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 12); 1399e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (intPart < -8) 1400e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1401e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent intPart = -8; 1402e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1403e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)(tmp32no1 & 0x00000fff); // Q12 1404e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Quadratic approximation of 2^frac 1405e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_RSHIFT_W32(frac * frac * 44, 19); // Q12 1406e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 += WEBRTC_SPL_MUL_16_16_RSFT(frac, 84, 7); // Q12 1407e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent invLrtFX = WEBRTC_SPL_LSHIFT_W32(1, 8 + intPart) 1408e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + WEBRTC_SPL_SHIFT_W32(tmp32no2, intPart - 4); // Q8 1409e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1410e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent normTmp = WebRtcSpl_NormW32(invLrtFX); 1411e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent normTmp2 = WebRtcSpl_NormW16((16384 - inst->priorNonSpeechProb)); 1412e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (normTmp + normTmp2 < 15) 1413e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1414e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent invLrtFX = WEBRTC_SPL_RSHIFT_W32(invLrtFX, 15 - normTmp2 - normTmp); // Q(normTmp+normTmp2-7) 1415e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q(normTmp+normTmp2+7) 1416e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent invLrtFX = WEBRTC_SPL_SHIFT_W32(tmp32no1, 7 - normTmp - normTmp2); // Q14 1417e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1418e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1419e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q22 1420e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent invLrtFX = WEBRTC_SPL_RSHIFT_W32(tmp32no1, 8); // Q14 1421e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1422e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1423e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inst->priorNonSpeechProb, 8); // Q22 1424e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nonSpeechProbFinal[i] = (WebRtc_UWord16)WEBRTC_SPL_DIV(tmp32no1, 1425e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_Word32)inst->priorNonSpeechProb 1426e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + invLrtFX); // Q8 1427e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (7 - normTmp - normTmp2 > 0) 1428e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1429e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nonSpeechProbFinal[i] = 0; // Q8 1430e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1431e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1432e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1433e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1434e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1435e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent// Transform input (speechFrame) to frequency domain magnitude (magnU16) 1436e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_DataAnalysis(NsxInst_t *inst, short *speechFrame, WebRtc_UWord16 *magnU16) 1437e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1438e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1439e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpU32no1, tmpU32no2; 1440e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1441e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp_1_w32 = 0; 1442e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp_2_w32 = 0; 1443e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 sum_log_magn = 0; 1444e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 sum_log_i_log_magn = 0; 1445e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1446e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 sum_log_magn_u16 = 0; 1447e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 tmp_u16 = 0; 1448e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1449e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 sum_log_i = 0; 1450e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 sum_log_i_square = 0; 1451e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 frac = 0; 1452e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 log2 = 0; 1453e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 matrix_determinant = 0; 1454e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 winData[ANAL_BLOCKL_MAX], maxWinData; 1455e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 realImag[ANAL_BLOCKL_MAX << 1]; 1456e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1457e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i, j; 1458e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int outCFFT; 1459e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int zeros; 1460e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int net_norm = 0; 1461e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int right_shifts_in_magnU16 = 0; 1462e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int right_shifts_in_initMagnEst = 0; 1463e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1464e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // For lower band do all processing 1465e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update analysis buffer for L band 1466e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer, inst->analysisBuffer + inst->blockLen10ms, 1467e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen - inst->blockLen10ms); 1468e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer + inst->anaLen - inst->blockLen10ms, 1469e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent speechFrame, inst->blockLen10ms); 1470e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1471e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Window data before FFT 1472e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->anaLen; i++) 1473e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1474e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent winData[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i], 1475e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->analysisBuffer[i], 1476e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 14); // Q0 1477e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1478e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Get input energy 1479e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->energyIn = WebRtcSpl_Energy(winData, (int)inst->anaLen, &(inst->scaleEnergyIn)); 1480e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1481e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Reset zero input flag 1482e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->zeroInputSignal = 0; 1483e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Acquire norm for winData 1484e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxWinData = WebRtcSpl_MaxAbsValueW16(winData, inst->anaLen); 1485e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->normData = WebRtcSpl_NormW16(maxWinData); 1486e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (maxWinData == 0) 1487e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1488e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Treat zero input separately. 1489e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->zeroInputSignal = 1; 1490e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return; 1491e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1492e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1493e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Determine the net normalization in the frequency domain 1494e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent net_norm = inst->stages - inst->normData; 1495e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Track lowest normalization factor and use it to prevent wrap around in shifting 1496e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_magnU16 = inst->normData - inst->minNorm; 1497e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_initMagnEst = WEBRTC_SPL_MAX(-right_shifts_in_magnU16, 0); 1498e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->minNorm -= right_shifts_in_initMagnEst; 1499e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_magnU16 = WEBRTC_SPL_MAX(right_shifts_in_magnU16, 0); 1500e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1501e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // create realImag as winData interleaved with zeros (= imag. part), normalize it 1502e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->anaLen; i++) 1503e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1504e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = WEBRTC_SPL_LSHIFT_W16(i, 1); 1505e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[j] = WEBRTC_SPL_LSHIFT_W16(winData[i], inst->normData); // Q(normData) 1506e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[j + 1] = 0; // Insert zeros in imaginary part 1507e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1508e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1509e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // bit-reverse position of elements in array and FFT the array 1510e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ComplexBitReverse(realImag, inst->stages); // Q(normData-stages) 1511e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outCFFT = WebRtcSpl_ComplexFFT(realImag, inst->stages, 1); 1512e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1513e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->imag[0] = 0; // Q(normData-stages) 1514e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->imag[inst->anaLen2] = 0; 1515e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[0] = realImag[0]; // Q(normData-stages) 1516e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[inst->anaLen2] = realImag[inst->anaLen]; 1517e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Q(2*(normData-stages)) 1518e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->magnEnergy = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[0], inst->real[0]); 1519e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->magnEnergy += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[inst->anaLen2], 1520e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[inst->anaLen2]); 1521e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent magnU16[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[0]); // Q(normData-stages) 1522e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent magnU16[inst->anaLen2] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[inst->anaLen2]); 1523e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->sumMagn = (WebRtc_UWord32)magnU16[0]; // Q(normData-stages) 1524e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->sumMagn += (WebRtc_UWord32)magnU16[inst->anaLen2]; 1525e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1526e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Gather information during startup for noise parameter estimation 1527e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_SHORT) 1528e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1529e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Switch initMagnEst to Q(minNorm-stages) 1530e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[0] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[0], 1531e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_initMagnEst); 1532e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[inst->anaLen2] = 1533e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[inst->anaLen2], 1534e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_initMagnEst); // Q(minNorm-stages) 1535e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1536e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift magnU16 to same domain as initMagnEst 1537e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[0], 1538e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_magnU16); // Q(minNorm-stages) 1539e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[inst->anaLen2], 1540e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_magnU16); // Q(minNorm-stages) 1541e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1542e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update initMagnEst 1543e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[0] += tmpU32no1; // Q(minNorm-stages) 1544e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[inst->anaLen2] += tmpU32no2; // Q(minNorm-stages) 1545e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1546e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent log2 = 0; 1547e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (magnU16[inst->anaLen2]) 1548e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1549e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate log2(magnU16[inst->anaLen2]) 1550e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[inst->anaLen2]); 1551e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[inst->anaLen2] << zeros) & 1552e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0x7FFFFFFF) >> 23); // Q8 1553e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(magnU16(i)) in Q8 1554e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); 1555e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1556e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1557e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_magn = (WebRtc_Word32)log2; // Q8 1558e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // sum_log_i_log_magn in Q17 1559e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i_log_magn = (WEBRTC_SPL_MUL_16_16(kLogIndex[inst->anaLen2], log2) >> 3); 1560e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1561e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1562e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 1; i < inst->anaLen2; i++) 1563e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1564e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = WEBRTC_SPL_LSHIFT_W16(i, 1); 1565e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[i] = realImag[j]; 1566e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->imag[i] = -realImag[j + 1]; 1567e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // magnitude spectrum 1568e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // energy in Q(2*(normData-stages)) 1569e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j], realImag[j]); 1570e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j + 1], realImag[j + 1]); 1571e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) 1572e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1573e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent magnU16[i] = (WebRtc_UWord16)WebRtcSpl_Sqrt(tmpU32no1); // Q(normData-stages) 1574e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->sumMagn += (WebRtc_UWord32)magnU16[i]; // Q(normData-stages) 1575e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_SHORT) 1576e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1577e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Switch initMagnEst to Q(minNorm-stages) 1578e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[i] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i], 1579e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_initMagnEst); 1580e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1581e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift magnU16 to same domain as initMagnEst, i.e., Q(minNorm-stages) 1582e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[i], 1583e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_magnU16); 1584e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update initMagnEst 1585e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->initMagnEst[i] += tmpU32no1; // Q(minNorm-stages) 1586e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1587e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (i >= kStartBand) 1588e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1589e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // For pink noise estimation. Collect data neglecting lower frequency band 1590e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent log2 = 0; 1591e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (magnU16[i]) 1592e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1593e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[i]); 1594e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[i] << zeros) & 1595e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 0x7FFFFFFF) >> 23); 1596e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // log2(magnU16(i)) in Q8 1597e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); 1598e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1599e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_magn += (WebRtc_Word32)log2; // Q8 1600e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // sum_log_i_log_magn in Q17 1601e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i_log_magn += (WEBRTC_SPL_MUL_16_16(kLogIndex[i], log2) >> 3); 1602e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1603e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1604e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1605e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1606e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute simplified noise model during startup 1607e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_SHORT) 1608e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1609e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Estimate White noise 1610e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Switch whiteNoiseLevel to Q(minNorm-stages) 1611e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->whiteNoiseLevel = WEBRTC_SPL_RSHIFT_U32(inst->whiteNoiseLevel, 1612e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent right_shifts_in_initMagnEst); 1613e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1614e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update the average magnitude spectrum, used as noise estimate. 1615e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL_32_16(inst->sumMagn, inst->overdrive); 1616e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages + 8); 1617e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1618e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Replacing division above with 'stages' shifts 1619e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift to same Q-domain as whiteNoiseLevel 1620e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, right_shifts_in_magnU16); 1621e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // This operation is safe from wrap around as long as END_STARTUP_SHORT < 128 1622e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(END_STARTUP_SHORT < 128); 1623e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) 1624e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1625e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Estimate Pink noise parameters 1626e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Denominator used in both parameter estimates. 1627e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // The value is only dependent on the size of the frequency band (kStartBand) 1628e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // and to reduce computational complexity stored in a table (kDeterminantEstMatrix[]) 1629e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 1630e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i = kSumLogIndex[kStartBand]; // Q5 1631e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 1632e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->fs == 8000) 1633e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1634e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Adjust values to shorter blocks in narrow band. 1635e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 = (WebRtc_Word32)matrix_determinant; 1636e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 += WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], sum_log_i, 9); 1637e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], kSumLogIndex[65], 10); 1638e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 -= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)sum_log_i_square, 4); 1639e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)(inst->magnLen 1640e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - kStartBand), kSumSquareLogIndex[65], 2); 1641e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent matrix_determinant = (WebRtc_Word16)tmp_1_w32; 1642e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i -= kSumLogIndex[65]; // Q5 1643e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_i_square -= kSumSquareLogIndex[65]; // Q2 1644e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1645e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1646e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Necessary number of shifts to fit sum_log_magn in a word16 1647e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = 16 - WebRtcSpl_NormW32(sum_log_magn); 1648e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (zeros < 0) 1649e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1650e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent zeros = 0; 1651e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1652e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 = WEBRTC_SPL_LSHIFT_W32(sum_log_magn, 1); // Q9 1653e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sum_log_magn_u16 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(tmp_1_w32, zeros);//Q(9-zeros) 1654e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1655e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate and update pinkNoiseNumerator. Result in Q11. 1656e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i_square, sum_log_magn_u16); // Q(11-zeros) 1657e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32((WebRtc_UWord32)sum_log_i_log_magn, 12); // Q5 1658e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1659e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift the largest value of sum_log_i and tmp32no3 before multiplication 1660e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_u16 = WEBRTC_SPL_LSHIFT_U16((WebRtc_UWord16)sum_log_i, 1); // Q6 1661e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((WebRtc_UWord32)sum_log_i > tmpU32no1) 1662e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1663e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_u16 = WEBRTC_SPL_RSHIFT_U16(tmp_u16, zeros); 1664e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1665e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 1666e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1667e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, zeros); 1668e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1669e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 -= (WebRtc_Word32)WEBRTC_SPL_UMUL_32_16(tmpU32no1, tmp_u16); // Q(11-zeros) 1670e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent matrix_determinant = WEBRTC_SPL_RSHIFT_W16(matrix_determinant, zeros); // Q(-zeros) 1671e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q11 1672e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)net_norm, 11); // Q11 1673e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmp_2_w32 < 0) 1674e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1675e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 = 0; 1676e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1677e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->pinkNoiseNumerator += tmp_2_w32; // Q11 1678e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1679e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate and update pinkNoiseExp. Result in Q14. 1680e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i, sum_log_magn_u16); // Q(14-zeros) 1681e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 = WEBRTC_SPL_RSHIFT_W32(sum_log_i_log_magn, 3 + zeros); 1682e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 = WEBRTC_SPL_MUL((WebRtc_Word32)(inst->magnLen - kStartBand), 1683e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32); 1684e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_2_w32 -= tmp_1_w32; // Q(14-zeros) 1685e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmp_2_w32 > 0) 1686e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1687e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // If the exponential parameter is negative force it to zero, which means a 1688e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // flat spectrum. 1689e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp_1_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q14 1690e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->pinkNoiseExp += WEBRTC_SPL_SAT(16384, tmp_1_w32, 0); // Q14 1691e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1692e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1693e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1694e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1695e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid WebRtcNsx_DataSynthesis(NsxInst_t *inst, short *outFrame) 1696e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1697e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no1; 1698e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 energyOut; 1699e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1700e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 realImag[ANAL_BLOCKL_MAX << 1]; 1701e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16no1, tmp16no2; 1702e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 energyRatio; 1703e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 gainFactor, gainFactor1, gainFactor2; 1704e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1705e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i, j; 1706e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int outCIFFT; 1707e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int scaleEnergyOut = 0; 1708e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1709e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->zeroInputSignal) 1710e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1711e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // synthesize the special case of zero input 1712e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // read out fully processed segment 1713e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->blockLen10ms; i++) 1714e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1715e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outFrame[i] = inst->synthesisBuffer[i]; // Q0 1716e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1717e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update synthesis buffer 1718e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer, 1719e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->synthesisBuffer + inst->blockLen10ms, 1720e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen - inst->blockLen10ms); 1721e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, 1722e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockLen10ms); 1723e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return; 1724e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1725e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Filter the data in the frequency domain 1726e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1727e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1728e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->real[i], 1729e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages) 1730e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->imag[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->imag[i], 1731e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages) 1732e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1733e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // back to time domain 1734e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Create spectrum 1735e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[0] = inst->real[0]; 1736e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[1] = -inst->imag[0]; 1737e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 1; i < inst->anaLen2; i++) 1738e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1739e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = WEBRTC_SPL_LSHIFT_W16(i, 1); 1740e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = (inst->anaLen << 1) - j; 1741e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[j] = inst->real[i]; 1742e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[j + 1] = -inst->imag[i]; 1743e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[tmp16no1] = inst->real[i]; 1744e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[tmp16no1 + 1] = inst->imag[i]; 1745e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1746e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[inst->anaLen] = inst->real[inst->anaLen2]; 1747e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent realImag[inst->anaLen + 1] = -inst->imag[inst->anaLen2]; 1748e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1749e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // bit-reverse position of elements in array and IFFT it 1750e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ComplexBitReverse(realImag, inst->stages); 1751e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outCIFFT = WebRtcSpl_ComplexIFFT(realImag, inst->stages, 1); 1752e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1753e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->anaLen; i++) 1754e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1755e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent j = WEBRTC_SPL_LSHIFT_W16(i, 1); 1756e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)realImag[j], outCIFFT - inst->normData); 1757e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1, 1758e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_WORD16_MIN); 1759e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1760e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1761e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //scale factor: only do it after END_STARTUP_LONG time 1762e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor = 8192; // 8192 = Q13(1.0) 1763e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->gainMap == 1 && 1764e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockIndex > END_STARTUP_LONG && 1765e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->energyIn > 0) 1766e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1767e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent energyOut = WebRtcSpl_Energy(inst->real, (int)inst->anaLen, &scaleEnergyOut); // Q(-scaleEnergyOut) 1768e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000)) 1769e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1770e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut 1771e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - inst->scaleEnergyIn); 1772e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 1773e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1774e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->energyIn = WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 8 + scaleEnergyOut 1775e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - inst->scaleEnergyIn); // Q(-8-scaleEnergyOut) 1776e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1777e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1778e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(inst->energyIn > 0); 1779e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent energyRatio = (WebRtc_Word16)WEBRTC_SPL_DIV(energyOut 1780e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 1), inst->energyIn); // Q8 1781e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1782e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // original FLOAT code 1783e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (gain > blim) { 1784e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor1=1.0+1.3*(gain-blim); 1785e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (gain*factor1 > 1.0) { // FLOAT 1786e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor1 = 1.0/gain; // FLOAT 1787e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1788e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1789e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // else { 1790e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor1=1.0; // FLOAT 1791e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1792e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 1793e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (gain > blim) { 1794e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor2=1.0; //FLOAT 1795e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1796e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // else { 1797e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // //don't reduce scale too much for pause regions: attenuation here should be controlled by flooring 1798e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor2=1.0-0.3*(blim-gain); // FLOAT 1799e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (gain <= inst->denoiseBound) { 1800e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor2=1.0-0.3*(blim-inst->denoiseBound); // FLOAT 1801e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1802e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 1803e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1804e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // all done in lookup tables now 1805e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor1 = kFactor1Table[energyRatio]; // Q8 1806e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor2 = inst->factor2Table[energyRatio]; // Q8 1807e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1808e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //combine both scales with speech/noise prob: note prior (priorSpeechProb) is not frequency dependent 1809e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1810e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*factor2; // original code 1811e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(16384 - inst->priorNonSpeechProb, 1812e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor1, 14); // Q13 16384 = Q14(1.0) 1813e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->priorNonSpeechProb, 1814e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor2, 14); // Q13; 1815e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainFactor = tmp16no1 + tmp16no2; // Q13 1816e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // out of flag_gain_map==1 1817e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1818e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // synthesis 1819e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->anaLen; i++) 1820e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1821e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i], 1822e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->real[i], 14); // Q0, window in Q14 1823e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, gainFactor, 13); // Q0 1824e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Down shift with rounding 1825e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1, 1826e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_WORD16_MIN); // Q0 1827e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->synthesisBuffer[i] = WEBRTC_SPL_ADD_SAT_W16(inst->synthesisBuffer[i], tmp16no2); // Q0 1828e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1829e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1830e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // read out fully processed segment 1831e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->blockLen10ms; i++) 1832e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1833e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outFrame[i] = inst->synthesisBuffer[i]; // Q0 1834e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1835e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update synthesis buffer 1836e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms, 1837e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen - inst->blockLen10ms); 1838e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, 1839e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockLen10ms); 1840e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 1841e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1842e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint WebRtcNsx_ProcessCore(NsxInst_t *inst, short *speechFrame, short *speechFrameHB, 1843e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent short *outFrame, short *outFrameHB) 1844e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 1845e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // main routine for noise suppression 1846e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1847e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpU32no1, tmpU32no2, tmpU32no3; 1848e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 satMax, maxNoiseU32; 1849e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 tmpMagnU32, tmpNoiseU32; 1850e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 nearMagnEst; 1851e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 noiseUpdateU32; 1852e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 noiseU32[HALF_ANAL_BLOCKL]; 1853e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 postLocSnr[HALF_ANAL_BLOCKL]; 1854e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 priorLocSnr[HALF_ANAL_BLOCKL]; 1855e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 prevNearSnr[HALF_ANAL_BLOCKL]; 1856e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 curNearSnr; 1857e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 priorSnr; 1858e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 noise_estimate = 0; 1859e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 noise_estimate_avg = 0; 1860e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 numerator = 0; 1861e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1862e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 tmp32no1, tmp32no2; 1863e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word32 pink_noise_num_avg = 0; 1864e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1865e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 tmpU16no1; 1866e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 magnU16[HALF_ANAL_BLOCKL]; 1867e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 prevNoiseU16[HALF_ANAL_BLOCKL]; 1868e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 nonSpeechProbFinal[HALF_ANAL_BLOCKL]; 1869e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 gammaNoise, prevGammaNoise; 1870e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord16 noiseSupFilterTmp[HALF_ANAL_BLOCKL]; 1871e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1872e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 qMagn, qNoise; 1873e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 avgProbSpeechHB, gainModHB, avgFilterGainHB, gainTimeDomainHB; 1874e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 tmp16no1; 1875e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 int_part = 0; 1876e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 frac_part = 0; 1877e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_Word16 pink_noise_exp_avg = 0; 1878e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1879e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int i; 1880e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int nShifts, postShifts; 1881e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int norm32no1, norm32no2; 1882e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int flag, sign; 1883e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int q_domain_to_use = 0; 1884e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1885e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef NS_FILEDEBUG 1886e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fwrite(spframe, sizeof(short), inst->blockLen10ms, inst->infile); 1887e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 1888e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1889e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Check that initialization has been done 1890e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->initFlag != 1) 1891e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1892e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 1893e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1894e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Check for valid pointers based on sampling rate 1895e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((inst->fs == 32000) && (speechFrameHB == NULL)) 1896e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1897e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 1898e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1899e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1900e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Store speechFrame and transform to frequency domain 1901e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_DataAnalysis(inst, speechFrame, magnU16); 1902e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1903e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->zeroInputSignal) 1904e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1905e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_DataSynthesis(inst, outFrame); 1906e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1907e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->fs == 32000) 1908e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1909e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update analysis buffer for H band 1910e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // append new data to buffer FX 1911e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms, 1912e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->anaLen - inst->blockLen10ms); 1913e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms, 1914e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent speechFrameHB, inst->blockLen10ms); 1915e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->blockLen10ms; i++) 1916e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1917e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outFrameHB[i] = inst->dataBufHBFX[i]; // Q0 1918e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1919e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of H band gain computation 1920e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 1921e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1922e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1923e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update block index when we have something to process 1924e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockIndex++; 1925e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 1926e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1927e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Norm of magn 1928e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent qMagn = inst->normData - inst->stages; 1929e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1930e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Compute spectral flatness on input spectrum 1931e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_ComputeSpectralFlatness(inst, magnU16); 1932e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1933e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // quantile noise estimate 1934e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_NoiseEstimation(inst, magnU16, noiseU32, &qNoise); 1935e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1936e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //noise estimate from previous frame 1937e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1938e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1939e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent prevNoiseU16[i] = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], 11); // Q(prevQNoise) 1940e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1941e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1942e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_SHORT) 1943e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1944e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Noise Q-domain to be used later; see description at end of section. 1945e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent q_domain_to_use = WEBRTC_SPL_MIN((int)qNoise, inst->minNorm - inst->stages); 1946e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1947e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate frequency independent parts in parametric noise estimate and calculate 1948e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // the estimate for the lower frequency band (same values for all frequency bins) 1949e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->pinkNoiseExp) 1950e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1951e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_exp_avg = (WebRtc_Word16)WebRtcSpl_DivW32W16(inst->pinkNoiseExp, 1952e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_Word16)(inst->blockIndex + 1)); // Q14 1953e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_num_avg = WebRtcSpl_DivW32W16(inst->pinkNoiseNumerator, 1954e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_Word16)(inst->blockIndex + 1)); // Q11 1955e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_CalcParametricNoiseEstimate(inst, 1956e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_exp_avg, 1957e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_num_avg, 1958e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent kStartBand, 1959e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent &noise_estimate, 1960e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent &noise_estimate_avg); 1961e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1962e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 1963e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1964e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Use white noise estimate if we have poor pink noise parameter estimates 1965e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_estimate = inst->whiteNoiseLevel; // Q(minNorm-stages) 1966e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_estimate_avg = noise_estimate / (inst->blockIndex + 1); // Q(minNorm-stages) 1967e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1968e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 1969e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1970e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Estimate the background noise using the pink noise parameters if permitted 1971e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((inst->pinkNoiseExp) && (i >= kStartBand)) 1972e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1973e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Reset noise_estimate 1974e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_estimate = 0; 1975e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_estimate_avg = 0; 1976e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate the parametric noise estimate for current frequency bin 1977e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_CalcParametricNoiseEstimate(inst, 1978e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_exp_avg, 1979e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent pink_noise_num_avg, 1980e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent i, 1981e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent &noise_estimate, 1982e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent &noise_estimate_avg); 1983e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 1984e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Calculate parametric Wiener filter 1985e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseSupFilterTmp[i] = inst->denoiseBound; 1986e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->initMagnEst[i]) 1987e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1988e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // numerator = (initMagnEst - noise_estimate * overdrive) 1989e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Result in Q(8+minNorm-stages) 1990e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL_32_16(noise_estimate, inst->overdrive); 1991e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numerator = WEBRTC_SPL_LSHIFT_U32(inst->initMagnEst[i], 8); 1992e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (numerator > tmpU32no1) 1993e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 1994e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Suppression filter coefficient larger than zero, so calculate. 1995e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numerator -= tmpU32no1; 1996e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 1997e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Determine number of left shifts in numerator for best accuracy after 1998e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // division 1999e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = WebRtcSpl_NormU32(numerator); 2000e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = WEBRTC_SPL_SAT(6, nShifts, 0); 2001e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2002e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift numerator to Q(nShifts+8+minNorm-stages) 2003e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numerator = WEBRTC_SPL_LSHIFT_U32(numerator, nShifts); 2004e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2005e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift denominator to Q(nShifts-6+minNorm-stages) 2006e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i], 6 - nShifts); 2007e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UDIV(numerator, tmpU32no1); // Q14 2008e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseSupFilterTmp[i] = (WebRtc_UWord16)WEBRTC_SPL_SAT(16384, tmpU32no2, 2009e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_UWord32)(inst->denoiseBound)); // Q14 2010e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2011e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2012e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Weight quantile noise 'noiseU32' with modeled noise 'noise_estimate_avg' 2013e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 'noiseU32 is in Q(qNoise) and 'noise_estimate' in Q(minNorm-stages) 2014e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // To guarantee that we do not get wrap around when shifting to the same domain 2015e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // we use the lowest one. Furthermore, we need to save 6 bits for the weighting. 2016e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 'noise_estimate_avg' can handle this operation by construction, but 'noiseU32' 2017e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // may not. 2018e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2019e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift 'noiseU32' to 'q_domain_to_use' 2020e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], (int)qNoise - q_domain_to_use); 2021e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift 'noise_estimate_avg' to 'q_domain_to_use' 2022e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noise_estimate_avg, inst->minNorm - inst->stages 2023e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - q_domain_to_use); 2024e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Make a simple check to see if we have enough room for weighting 'tmpU32no1' 2025e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // without wrap around 2026e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 0; 2027e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no1 & 0xfc000000) { 2028e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 6); 2029e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 6); 2030e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 6; 2031e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2032e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Add them together and divide by startup length 2033e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseU32[i] = WebRtcSpl_DivU32U16(tmpU32no1 + tmpU32no2, END_STARTUP_SHORT); 2034e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift back if necessary 2035e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], nShifts); 2036e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2037e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update new Q-domain for 'noiseU32' 2038e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent qNoise = q_domain_to_use; 2039e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2040e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute average signal during END_STARTUP_LONG time: 2041e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // used to normalize spectral difference measure 2042e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_LONG) 2043e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2044e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // substituting division with shift ending up in Q(-2*stages) 2045e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergyTmp 2046e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy, 2047e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2 * inst->normData + inst->stages - 1); 2048e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergy = WebRtcSpl_DivU32U16(inst->timeAvgMagnEnergyTmp, 2049e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->blockIndex + 1); 2050e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2051e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2052e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //start processing at frames == converged+1 2053e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // STEP 1: compute prior and post SNR based on quantile noise estimates 2054e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2055e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // compute direct decision (DD) estimate of prior SNR: needed for new method 2056e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent satMax = (WebRtc_UWord32)1048575;// Largest possible value without getting overflow despite shifting 12 steps 2057e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent postShifts = 6 + qMagn - qNoise; 2058e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = 5 - inst->prevQMagn + inst->prevQNoise; 2059e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 2060e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2061e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT: 2062e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // post SNR 2063e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // postLocSnr[i] = 0.0; 2064e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (magn[i] > noise[i]) 2065e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // { 2066e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // postLocSnr[i] = magn[i] / (noise[i] + 0.0001); 2067e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 2068e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // previous post SNR 2069e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // previous estimate: based on previous frame with gain filter (smooth is previous filter) 2070e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 2071e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // prevNearSnr[i] = inst->prevMagnU16[i] / (inst->noisePrev[i] + 0.0001) * (inst->smooth[i]); 2072e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 2073e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // DD estimate is sum of two terms: current estimate and previous estimate 2074e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // directed decision update of priorSnr (or we actually store [2*priorSnr+1]) 2075e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 2076e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // priorLocSnr[i] = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * (postLocSnr[i] - 1.0); 2077e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2078e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // calculate post SNR: output in Q11 2079e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent postLocSnr[i] = 2048; // 1.0 in Q11 2080e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], 6); // Q(6+qMagn) 2081e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (postShifts < 0) 2082e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2083e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], -postShifts); // Q(6+qMagn) 2084e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2085e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2086e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], postShifts); // Q(6+qMagn) 2087e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2088e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no1 > tmpU32no2) 2089e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2090e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Current magnitude larger than noise 2091e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, 11); // Q(17+qMagn) 2092e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no2) 2093e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2094e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11 2095e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent postLocSnr[i] = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 2096e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2097e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2098e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent postLocSnr[i] = satMax; 2099e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // calculate prevNearSnr[i] and save for later instead of recalculating it later 2103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nearMagnEst = WEBRTC_SPL_UMUL_16_16(inst->prevMagnU16[i], inst->noiseSupFilter[i]); // Q(prevQMagn+14) 2104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(nearMagnEst, 3); // Q(prevQMagn+17) 2105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], nShifts); // Q(prevQMagn+6) 2106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no2) 2108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_DIV(tmpU32no1, tmpU32no2); // Q11 2110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 2111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = satMax; // Q11 2114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent prevNearSnr[i] = tmpU32no1; // Q11 2116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //directed decision update of priorSnr 2118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 2119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL_32_16(postLocSnr[i] - 2048, ONE_MINUS_DD_PR_SNR_Q11); // Q22 2120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent priorSnr = tmpU32no1 + tmpU32no2 + 512; // Q22 (added 512 for rounding) 2121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // priorLocSnr = 1 + 2*priorSnr 2122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent priorLocSnr[i] = 2048 + WEBRTC_SPL_RSHIFT_U32(priorSnr, 10); // Q11 2123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of loop over frequencies 2124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with step 1: DD computation of prior and post SNR 2125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // STEP 2: compute speech/noise likelihood 2127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute difference of input spectrum with learned/estimated noise spectrum 2129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_ComputeSpectralDifference(inst, magnU16); 2130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute histograms for determination of parameters (thresholds and weights for features) 2131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //parameters are extracted once every window time (=inst->modelUpdate) 2132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //counter update 2133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->cntThresUpdate++; 2134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent flag = (int)(inst->cntThresUpdate == inst->modelUpdate); 2135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //update histogram 2136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_FeatureParameterExtraction(inst, flag); 2137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute model parameters 2138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (flag) 2139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->cntThresUpdate = 0; // Reset counter 2141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //update every window: 2142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // get normalization for spectral difference for next window estimate 2143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shift to Q(-2*stages) 2145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->curAvgMagnEnergy = WEBRTC_SPL_RSHIFT_U32(inst->curAvgMagnEnergy, STAT_UPDATES); 2146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = (inst->curAvgMagnEnergy + inst->timeAvgMagnEnergy + 1) >> 1; //Q(-2*stages) 2148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Update featureSpecDiff 2149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((tmpU32no1 != inst->timeAvgMagnEnergy) && (inst->featureSpecDiff)) 2150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32no1 = 0; 2152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = tmpU32no1; 2153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent while (0xFFFF0000 & tmpU32no3) 2154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 >>= 1; 2156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32no1++; 2157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = inst->featureSpecDiff; 2159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent while (0xFFFF0000 & tmpU32no2) 2160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 >>= 1; 2162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32no1++; 2163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = WEBRTC_SPL_UMUL(tmpU32no3, tmpU32no2); 2165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = WEBRTC_SPL_UDIV(tmpU32no3, inst->timeAvgMagnEnergy); 2166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (WebRtcSpl_NormU32(tmpU32no3) < norm32no1) 2167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecDiff = 0x007FFFFF; 2169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->featureSpecDiff = WEBRTC_SPL_MIN(0x007FFFFF, 2172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_LSHIFT_U32(tmpU32no3, norm32no1)); 2173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->timeAvgMagnEnergy = tmpU32no1; // Q(-2*stages) 2177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->curAvgMagnEnergy = 0; 2178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2180e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //compute speech/noise probability 2181e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_SpeechNoiseProb(inst, nonSpeechProbFinal, priorLocSnr, postLocSnr); 2182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //time-avg parameter for noise update 2184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gammaNoise = NOISE_UPDATE_Q8; // Q8 2185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxNoiseU32 = 0; 2187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent postShifts = inst->prevQNoise - qMagn; 2188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = inst->prevQMagn - qMagn; 2189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 2190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // temporary noise update: use it for speech frames if update value is less than previous 2192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // the formula has been rewritten into: 2193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) 2194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (postShifts < 0) 2196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(magnU16[i], -postShifts); // Q(prevQNoise) 2198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], postShifts); // Q(prevQNoise) 2201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (prevNoiseU16[i] > tmpU32no2) 2203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sign = -1; 2205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = prevNoiseU16[i] - tmpU32no2; 2206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2208e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sign = 1; 2209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = tmpU32no2 - prevNoiseU16[i]; 2210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseUpdateU32 = inst->prevNoiseU32[i]; // Q(prevQNoise+11) 2212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = 0; 2213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if ((tmpU32no1) && (nonSpeechProbFinal[i])) 2214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // This value will be used later, if gammaNoise changes 2216e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no3 = WEBRTC_SPL_UMUL_32_16(tmpU32no1, nonSpeechProbFinal[i]); // Q(prevQNoise+8) 2217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (0x7c000000 & tmpU32no3) 2218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shifting required before multiplication 2220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 2221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11) 2222e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // We can do shifting after multiplication 2225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 2226e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11) 2227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (sign > 0) 2229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseUpdateU32 += tmpU32no2; // Q(prevQNoise+11) 2231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // This operation is safe. We can never get wrap around, since worst 2234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // case scenario means magnU16 = 0 2235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseUpdateU32 -= tmpU32no2; // Q(prevQNoise+11) 2236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //increase gamma (i.e., less noise update) for frame likely to be speech 2240e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent prevGammaNoise = gammaNoise; 2241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gammaNoise = NOISE_UPDATE_Q8; 2242e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //time-constant based on speech/noise state 2243e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //increase gamma (i.e., less noise update) for frames likely to be speech 2244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (nonSpeechProbFinal[i] < ONE_MINUS_PROB_RANGE_Q8) 2245e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gammaNoise = GAMMA_NOISE_TRANS_AND_SPEECH_Q8; 2247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2249e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (prevGammaNoise != gammaNoise) 2250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // new noise update 2252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // this line is the same as above, only that the result is stored in a different variable and the gammaNoise 2253e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // has changed 2254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // 2255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) 2256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (0x7c000000 & tmpU32no3) 2258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Shifting required before multiplication 2260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 2261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11) 2262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2264e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // We can do shifting after multiplication 2265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 2266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11) 2267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2268e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (sign > 0) 2269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = inst->prevNoiseU32[i] + tmpU32no2; // Q(prevQNoise+11) 2271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = inst->prevNoiseU32[i] - tmpU32no2; // Q(prevQNoise+11) 2274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (noiseUpdateU32 > tmpU32no1) 2276e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseUpdateU32 = tmpU32no1; // Q(prevQNoise+11) 2278e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2279e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2280e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noiseU32[i] = noiseUpdateU32; // Q(prevQNoise+11) 2281e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (noiseUpdateU32 > maxNoiseU32) 2282e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2283e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent maxNoiseU32 = noiseUpdateU32; 2284e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2285e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2286e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // conservative noise update 2287e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // original FLOAT code 2288e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (prob_speech < PROB_RANGE) { 2289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // inst->avgMagnPause[i] = inst->avgMagnPause[i] + (1.0 - gamma_pause)*(magn[i] - inst->avgMagnPause[i]); 2290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 2291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 = WEBRTC_SPL_SHIFT_W32(inst->avgMagnPause[i], -nShifts); 2293e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (nonSpeechProbFinal[i] > ONE_MINUS_PROB_RANGE_Q8) 2294e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2295e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (nShifts < 0) 2296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = (WebRtc_Word32)magnU16[i] - tmp32no2; // Q(qMagn) 2298e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts) 2299e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + 128, 8); // Q(qMagn) 2300e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)magnU16[i], nShifts) 2303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - inst->avgMagnPause[i]; // Q(qMagn+nShifts) 2304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts) 2305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + (128 << nShifts), 8 + nShifts); // Q(qMagn) 2306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmp32no2 += tmp32no1; // Q(qMagn) 2308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->avgMagnPause[i] = tmp32no2; 2310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of frequency loop 2311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32no1 = WebRtcSpl_NormU32(maxNoiseU32); 2313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent qNoise = inst->prevQNoise + norm32no1 - 5; 2314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // done with step 2: noise update 2315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // STEP 3: compute dd update of prior snr and post snr based on new noise estimate 2317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent nShifts = inst->prevQNoise + 11 - qMagn; 2318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 2319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT code 2321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // post and prior SNR 2322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // curNearSnr = 0.0; 2323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (magn[i] > noise[i]) 2324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // { 2325e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // curNearSnr = magn[i] / (noise[i] + 0.0001) - 1.0; 2326e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 2327e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // DD estimate is sum of two terms: current estimate and previous estimate 2328e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // directed decision update of snrPrior 2329e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // snrPrior = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * curNearSnr; 2330e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // gain filter 2331e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // tmpFloat1 = inst->overdrive + snrPrior; 2332e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // tmpFloat2 = snrPrior / tmpFloat1; 2333e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // theFilter[i] = tmpFloat2; 2334e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2335e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // calculate curNearSnr again, this is necessary because a new noise estimate has been made since then. for the original 2336e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent curNearSnr = 0; // Q11 2337e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (nShifts < 0) 2338e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2339e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // This case is equivalent with magn < noise which implies curNearSnr = 0; 2340e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpMagnU32 = (WebRtc_UWord32)magnU16[i]; // Q(qMagn) 2341e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpNoiseU32 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], -nShifts); // Q(qMagn) 2342e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else if (nShifts > 17) 2343e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2344e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], 17); // Q(qMagn+17) 2345e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpNoiseU32 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], nShifts - 17); // Q(qMagn+17) 2346e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2347e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2348e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], nShifts); // Q(qNoise_prev+11) 2349e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpNoiseU32 = noiseU32[i]; // Q(qNoise_prev+11) 2350e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2351e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpMagnU32 > tmpNoiseU32) 2352e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2353e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = tmpMagnU32 - tmpNoiseU32; // Q(qCur) 2354e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent norm32no2 = WEBRTC_SPL_MIN(11, WebRtcSpl_NormU32(tmpU32no1)); 2355e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32no2); // Q(qCur+norm32no2) 2356e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpNoiseU32, 11 - norm32no2); // Q(qCur+norm32no2-11) 2357e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (tmpU32no2) 2358e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2359e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11 2360e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2361e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent curNearSnr = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 2362e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2363e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2364e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //directed decision update of priorSnr 2365e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // FLOAT 2366e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr; 2367e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2368e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 2369e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q22 2370e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent priorSnr = tmpU32no1 + tmpU32no2; // Q22 2371e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2372e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //gain filter 2373e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = (WebRtc_UWord32)(inst->overdrive) 2374e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent + WEBRTC_SPL_RSHIFT_U32(priorSnr + 8192, 14); // Q8 2375e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU16no1 = (WebRtc_UWord16)WEBRTC_SPL_UDIV(priorSnr + (tmpU32no1 >> 1), tmpU32no1); // Q14 2376e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBound); // 16384 = Q14(1.0) // Q14 2377e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2378e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Weight in the parametric Wiener filter during startup 2379e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->blockIndex < END_STARTUP_SHORT) 2380e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2381e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Weight the two suppression filters 2382e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = WEBRTC_SPL_UMUL_16_16(inst->noiseSupFilter[i], 2383e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_UWord16)inst->blockIndex); 2384e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no2 = WEBRTC_SPL_UMUL_16_16(noiseSupFilterTmp[i], 2385e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent (WebRtc_UWord16)(END_STARTUP_SHORT 2386e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - inst->blockIndex)); 2387e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 += tmpU32no2; 2388e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->noiseSupFilter[i] = (WebRtc_UWord16)WebRtcSpl_DivU32U16(tmpU32no1, 2389e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent END_STARTUP_SHORT); 2390e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2391e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of loop over frequencies 2392e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //done with step3 2393e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2394e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // save noise and magnitude spectrum for next frame 2395e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevQNoise = qNoise; 2396e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevQMagn = qMagn; 2397e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (norm32no1 > 5) 2398e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2399e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 2400e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2401e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevNoiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], norm32no1 - 5); // Q(qNoise+11) 2402e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) 2403e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2404e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2405e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2406e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->magnLen; i++) 2407e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2408e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevNoiseU32[i] = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], 5 - norm32no1); // Q(qNoise+11) 2409e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) 2410e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2411e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2412e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2413e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtcNsx_DataSynthesis(inst, outFrame); 2414e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef NS_FILEDEBUG 2415e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fwrite(outframe, sizeof(short), inst->blockLen10ms, inst->outfile); 2416e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif 2417e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2418e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //for H band: 2419e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // only update data buffer, then apply time-domain gain is applied derived from L band 2420e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (inst->fs == 32000) 2421e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2422e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // update analysis buffer for H band 2423e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // append new data to buffer FX 2424e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms, inst->anaLen - inst->blockLen10ms); 2425e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms, speechFrameHB, inst->blockLen10ms); 2426e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // range for averaging low band quantities for H band gain 2427e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2428e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainTimeDomainHB = 16384; // 16384 = Q14(1.0) 2429e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //average speech prob from low band 2430e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //average filter gain from low band 2431e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //avg over second half (i.e., 4->8kHz) of freq. spectrum 2432e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 = 0; // Q12 2433e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU16no1 = 0; // Q8 2434e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++) 2435e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2436e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU16no1 += nonSpeechProbFinal[i]; // Q8 2437e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent tmpU32no1 += (WebRtc_UWord32)(inst->noiseSupFilter[i]); // Q14 2438e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2439e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgProbSpeechHB = (WebRtc_Word16)(4096 2440e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent - WEBRTC_SPL_RSHIFT_U16(tmpU16no1, inst->stages - 7)); // Q12 2441e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent avgFilterGainHB = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages - 3); // Q14 2442e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2443e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // original FLOAT code 2444e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // gain based on speech probability: 2445e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0; 2446e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // between 0 and 1 2447e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2448e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // gain based on speech probability: 2449e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // original expression: "0.5 * (1 + tanh(2x-1))" 2450e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // avgProbSpeechHB has been anyway saturated to a value between 0 and 1 so the other cases don't have to be dealt with 2451e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // avgProbSpeechHB and gainModHB are in Q12, 3607 = Q12(0.880615234375) which is a zero point of 2452e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // |0.5 * (1 + tanh(2x-1)) - x| - |0.5 * (1 + tanh(2x-1)) - 0.880615234375| meaning that from that point the error of approximating 2453e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // the expression with f(x) = x would be greater than the error of approximating the expression with f(x) = 0.880615234375 2454e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // error: "|0.5 * (1 + tanh(2x-1)) - x| from x=0 to 0.880615234375" -> http://www.wolframalpha.com/input/?i=|0.5+*+(1+%2B+tanh(2x-1))+-+x|+from+x%3D0+to+0.880615234375 2455e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // and: "|0.5 * (1 + tanh(2x-1)) - 0.880615234375| from x=0.880615234375 to 1" -> http://www.wolframalpha.com/input/?i=+|0.5+*+(1+%2B+tanh(2x-1))+-+0.880615234375|+from+x%3D0.880615234375+to+1 2456e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainModHB = WEBRTC_SPL_MIN(avgProbSpeechHB, 3607); 2457e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2458e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // // original FLOAT code 2459e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // //combine gain with low band gain 2460e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // if (avg_prob_speech < (float)0.5) { 2461e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // gain_time_domain_HB=(float)0.5*gain_mod+(float)0.5*avg_filter_gain; 2462e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 2463e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // else { 2464e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // gain_time_domain_HB=(float)0.25*gain_mod+(float)0.75*avg_filter_gain; 2465e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // } 2466e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2467e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2468e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //combine gain with low band gain 2469e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (avgProbSpeechHB < 2048) 2470e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { // 2048 = Q12(0.5) 2471e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // the next two lines in float are "gain_time_domain = 0.5 * gain_mod + 0.5 * avg_filter_gain"; Q2(0.5) = 2 equals one left shift 2472e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainTimeDomainHB = (gainModHB << 1) + (avgFilterGainHB >> 1); // Q14 2473e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else 2474e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2475e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // "gain_time_domain = 0.25 * gain_mod + 0.75 * agv_filter_gain;" 2476e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainTimeDomainHB = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, avgFilterGainHB, 2); // 3 = Q2(0.75); Q14 2477e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainTimeDomainHB += gainModHB; // Q14 2478e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2479e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //make sure gain is within flooring range 2480e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gainTimeDomainHB 2481e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = WEBRTC_SPL_SAT(16384, gainTimeDomainHB, (WebRtc_Word16)(inst->denoiseBound)); // 16384 = Q14(1.0) 2482e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2483e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2484e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent //apply gain 2485e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (i = 0; i < inst->blockLen10ms; i++) 2486e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 2487e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent outFrameHB[i] 2488e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainTimeDomainHB, inst->dataBufHBFX[i], 14); // Q0 2489e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 2490e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } // end of H band gain computation 2491e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 2492e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 2493e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 2494