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