1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12 /* 13 * A wrapper for resampling a numerous amount of sampling combinations. 14 */ 15 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include "signal_processing_library.h" 20 #include "resampler.h" 21 22 23 namespace webrtc 24 { 25 26 Resampler::Resampler() 27 { 28 state1_ = NULL; 29 state2_ = NULL; 30 state3_ = NULL; 31 in_buffer_ = NULL; 32 out_buffer_ = NULL; 33 in_buffer_size_ = 0; 34 out_buffer_size_ = 0; 35 in_buffer_size_max_ = 0; 36 out_buffer_size_max_ = 0; 37 // we need a reset before we will work 38 my_in_frequency_khz_ = 0; 39 my_out_frequency_khz_ = 0; 40 my_mode_ = kResamplerMode1To1; 41 my_type_ = kResamplerInvalid; 42 slave_left_ = NULL; 43 slave_right_ = NULL; 44 } 45 46 Resampler::Resampler(int inFreq, int outFreq, ResamplerType type) 47 { 48 state1_ = NULL; 49 state2_ = NULL; 50 state3_ = NULL; 51 in_buffer_ = NULL; 52 out_buffer_ = NULL; 53 in_buffer_size_ = 0; 54 out_buffer_size_ = 0; 55 in_buffer_size_max_ = 0; 56 out_buffer_size_max_ = 0; 57 // we need a reset before we will work 58 my_in_frequency_khz_ = 0; 59 my_out_frequency_khz_ = 0; 60 my_mode_ = kResamplerMode1To1; 61 my_type_ = kResamplerInvalid; 62 slave_left_ = NULL; 63 slave_right_ = NULL; 64 65 Reset(inFreq, outFreq, type); 66 } 67 68 Resampler::~Resampler() 69 { 70 if (state1_) 71 { 72 free(state1_); 73 } 74 if (state2_) 75 { 76 free(state2_); 77 } 78 if (state3_) 79 { 80 free(state3_); 81 } 82 if (in_buffer_) 83 { 84 free(in_buffer_); 85 } 86 if (out_buffer_) 87 { 88 free(out_buffer_); 89 } 90 if (slave_left_) 91 { 92 delete slave_left_; 93 } 94 if (slave_right_) 95 { 96 delete slave_right_; 97 } 98 } 99 100 int Resampler::ResetIfNeeded(int inFreq, int outFreq, ResamplerType type) 101 { 102 int tmpInFreq_kHz = inFreq / 1000; 103 int tmpOutFreq_kHz = outFreq / 1000; 104 105 if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_) 106 || (type != my_type_)) 107 { 108 return Reset(inFreq, outFreq, type); 109 } else 110 { 111 return 0; 112 } 113 } 114 115 int Resampler::Reset(int inFreq, int outFreq, ResamplerType type) 116 { 117 118 if (state1_) 119 { 120 free(state1_); 121 state1_ = NULL; 122 } 123 if (state2_) 124 { 125 free(state2_); 126 state2_ = NULL; 127 } 128 if (state3_) 129 { 130 free(state3_); 131 state3_ = NULL; 132 } 133 if (in_buffer_) 134 { 135 free(in_buffer_); 136 in_buffer_ = NULL; 137 } 138 if (out_buffer_) 139 { 140 free(out_buffer_); 141 out_buffer_ = NULL; 142 } 143 if (slave_left_) 144 { 145 delete slave_left_; 146 slave_left_ = NULL; 147 } 148 if (slave_right_) 149 { 150 delete slave_right_; 151 slave_right_ = NULL; 152 } 153 154 in_buffer_size_ = 0; 155 out_buffer_size_ = 0; 156 in_buffer_size_max_ = 0; 157 out_buffer_size_max_ = 0; 158 159 // This might be overridden if parameters are not accepted. 160 my_type_ = type; 161 162 // Start with a math exercise, Euclid's algorithm to find the gcd: 163 164 int a = inFreq; 165 int b = outFreq; 166 int c = a % b; 167 while (c != 0) 168 { 169 a = b; 170 b = c; 171 c = a % b; 172 } 173 // b is now the gcd; 174 175 // We need to track what domain we're in. 176 my_in_frequency_khz_ = inFreq / 1000; 177 my_out_frequency_khz_ = outFreq / 1000; 178 179 // Scale with GCD 180 inFreq = inFreq / b; 181 outFreq = outFreq / b; 182 183 // Do we need stereo? 184 if ((my_type_ & 0xf0) == 0x20) 185 { 186 // Change type to mono 187 type = static_cast<ResamplerType>( 188 ((static_cast<int>(type) & 0x0f) + 0x10)); 189 slave_left_ = new Resampler(inFreq, outFreq, type); 190 slave_right_ = new Resampler(inFreq, outFreq, type); 191 } 192 193 if (inFreq == outFreq) 194 { 195 my_mode_ = kResamplerMode1To1; 196 } else if (inFreq == 1) 197 { 198 switch (outFreq) 199 { 200 case 2: 201 my_mode_ = kResamplerMode1To2; 202 break; 203 case 3: 204 my_mode_ = kResamplerMode1To3; 205 break; 206 case 4: 207 my_mode_ = kResamplerMode1To4; 208 break; 209 case 6: 210 my_mode_ = kResamplerMode1To6; 211 break; 212 case 12: 213 my_mode_ = kResamplerMode1To12; 214 break; 215 default: 216 my_type_ = kResamplerInvalid; 217 return -1; 218 } 219 } else if (outFreq == 1) 220 { 221 switch (inFreq) 222 { 223 case 2: 224 my_mode_ = kResamplerMode2To1; 225 break; 226 case 3: 227 my_mode_ = kResamplerMode3To1; 228 break; 229 case 4: 230 my_mode_ = kResamplerMode4To1; 231 break; 232 case 6: 233 my_mode_ = kResamplerMode6To1; 234 break; 235 case 12: 236 my_mode_ = kResamplerMode12To1; 237 break; 238 default: 239 my_type_ = kResamplerInvalid; 240 return -1; 241 } 242 } else if ((inFreq == 2) && (outFreq == 3)) 243 { 244 my_mode_ = kResamplerMode2To3; 245 } else if ((inFreq == 2) && (outFreq == 11)) 246 { 247 my_mode_ = kResamplerMode2To11; 248 } else if ((inFreq == 4) && (outFreq == 11)) 249 { 250 my_mode_ = kResamplerMode4To11; 251 } else if ((inFreq == 8) && (outFreq == 11)) 252 { 253 my_mode_ = kResamplerMode8To11; 254 } else if ((inFreq == 3) && (outFreq == 2)) 255 { 256 my_mode_ = kResamplerMode3To2; 257 } else if ((inFreq == 11) && (outFreq == 2)) 258 { 259 my_mode_ = kResamplerMode11To2; 260 } else if ((inFreq == 11) && (outFreq == 4)) 261 { 262 my_mode_ = kResamplerMode11To4; 263 } else if ((inFreq == 11) && (outFreq == 16)) 264 { 265 my_mode_ = kResamplerMode11To16; 266 } else if ((inFreq == 11) && (outFreq == 32)) 267 { 268 my_mode_ = kResamplerMode11To32; 269 } else if ((inFreq == 11) && (outFreq == 8)) 270 { 271 my_mode_ = kResamplerMode11To8; 272 } else 273 { 274 my_type_ = kResamplerInvalid; 275 return -1; 276 } 277 278 // Now create the states we need 279 switch (my_mode_) 280 { 281 case kResamplerMode1To1: 282 // No state needed; 283 break; 284 case kResamplerMode1To2: 285 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 286 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 287 break; 288 case kResamplerMode1To3: 289 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); 290 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_); 291 break; 292 case kResamplerMode1To4: 293 // 1:2 294 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 295 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 296 // 2:4 297 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 298 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 299 break; 300 case kResamplerMode1To6: 301 // 1:2 302 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 303 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 304 // 2:6 305 state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); 306 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_); 307 break; 308 case kResamplerMode1To12: 309 // 1:2 310 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 311 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 312 // 2:4 313 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 314 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 315 // 4:12 316 state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); 317 WebRtcSpl_ResetResample16khzTo48khz( 318 (WebRtcSpl_State16khzTo48khz*) state3_); 319 break; 320 case kResamplerMode2To3: 321 // 2:6 322 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); 323 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_); 324 // 6:3 325 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 326 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 327 break; 328 case kResamplerMode2To11: 329 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 330 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 331 332 state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); 333 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_); 334 break; 335 case kResamplerMode4To11: 336 state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); 337 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_); 338 break; 339 case kResamplerMode8To11: 340 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz)); 341 WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_); 342 break; 343 case kResamplerMode11To16: 344 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 345 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 346 347 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); 348 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_); 349 break; 350 case kResamplerMode11To32: 351 // 11 -> 22 352 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 353 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 354 355 // 22 -> 16 356 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); 357 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_); 358 359 // 16 -> 32 360 state3_ = malloc(8 * sizeof(WebRtc_Word32)); 361 memset(state3_, 0, 8 * sizeof(WebRtc_Word32)); 362 363 break; 364 case kResamplerMode2To1: 365 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 366 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 367 break; 368 case kResamplerMode3To1: 369 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); 370 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_); 371 break; 372 case kResamplerMode4To1: 373 // 4:2 374 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 375 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 376 // 2:1 377 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 378 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 379 break; 380 case kResamplerMode6To1: 381 // 6:2 382 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); 383 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_); 384 // 2:1 385 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 386 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 387 break; 388 case kResamplerMode12To1: 389 // 12:4 390 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); 391 WebRtcSpl_ResetResample48khzTo16khz( 392 (WebRtcSpl_State48khzTo16khz*) state1_); 393 // 4:2 394 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 395 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 396 // 2:1 397 state3_ = malloc(8 * sizeof(WebRtc_Word32)); 398 memset(state3_, 0, 8 * sizeof(WebRtc_Word32)); 399 break; 400 case kResamplerMode3To2: 401 // 3:6 402 state1_ = malloc(8 * sizeof(WebRtc_Word32)); 403 memset(state1_, 0, 8 * sizeof(WebRtc_Word32)); 404 // 6:2 405 state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); 406 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_); 407 break; 408 case kResamplerMode11To2: 409 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); 410 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_); 411 412 state2_ = malloc(8 * sizeof(WebRtc_Word32)); 413 memset(state2_, 0, 8 * sizeof(WebRtc_Word32)); 414 415 break; 416 case kResamplerMode11To4: 417 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); 418 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_); 419 break; 420 case kResamplerMode11To8: 421 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); 422 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_); 423 break; 424 425 } 426 427 return 0; 428 } 429 430 // Synchronous resampling, all output samples are written to samplesOut 431 int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16* samplesOut, 432 int maxLen, int &outLen) 433 { 434 // Check that the resampler is not in asynchronous mode 435 if (my_type_ & 0x0f) 436 { 437 return -1; 438 } 439 440 // Do we have a stereo signal? 441 if ((my_type_ & 0xf0) == 0x20) 442 { 443 444 // Split up the signal and call the slave object for each channel 445 446 WebRtc_Word16* left = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2); 447 WebRtc_Word16* right = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2); 448 WebRtc_Word16* out_left = (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16)); 449 WebRtc_Word16* out_right = 450 (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16)); 451 int res = 0; 452 for (int i = 0; i < lengthIn; i += 2) 453 { 454 left[i >> 1] = samplesIn[i]; 455 right[i >> 1] = samplesIn[i + 1]; 456 } 457 458 // It's OK to overwrite the local parameter, since it's just a copy 459 lengthIn = lengthIn / 2; 460 461 int actualOutLen_left = 0; 462 int actualOutLen_right = 0; 463 // Do resampling for right channel 464 res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left); 465 res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right); 466 if (res || (actualOutLen_left != actualOutLen_right)) 467 { 468 free(left); 469 free(right); 470 free(out_left); 471 free(out_right); 472 return -1; 473 } 474 475 // Reassemble the signal 476 for (int i = 0; i < actualOutLen_left; i++) 477 { 478 samplesOut[i * 2] = out_left[i]; 479 samplesOut[i * 2 + 1] = out_right[i]; 480 } 481 outLen = 2 * actualOutLen_left; 482 483 free(left); 484 free(right); 485 free(out_left); 486 free(out_right); 487 488 return 0; 489 } 490 491 // Containers for temp samples 492 WebRtc_Word16* tmp; 493 WebRtc_Word16* tmp_2; 494 // tmp data for resampling routines 495 WebRtc_Word32* tmp_mem; 496 497 switch (my_mode_) 498 { 499 case kResamplerMode1To1: 500 memcpy(samplesOut, samplesIn, lengthIn * sizeof(WebRtc_Word16)); 501 outLen = lengthIn; 502 break; 503 case kResamplerMode1To2: 504 if (maxLen < (lengthIn * 2)) 505 { 506 return -1; 507 } 508 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_); 509 outLen = lengthIn * 2; 510 return 0; 511 case kResamplerMode1To3: 512 513 // We can only handle blocks of 160 samples 514 // Can be fixed, but I don't think it's needed 515 if ((lengthIn % 160) != 0) 516 { 517 return -1; 518 } 519 if (maxLen < (lengthIn * 3)) 520 { 521 return -1; 522 } 523 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32)); 524 525 for (int i = 0; i < lengthIn; i += 160) 526 { 527 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3, 528 (WebRtcSpl_State16khzTo48khz *)state1_, 529 tmp_mem); 530 } 531 outLen = lengthIn * 3; 532 free(tmp_mem); 533 return 0; 534 case kResamplerMode1To4: 535 if (maxLen < (lengthIn * 4)) 536 { 537 return -1; 538 } 539 540 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn); 541 // 1:2 542 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 543 // 2:4 544 WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (WebRtc_Word32*)state2_); 545 outLen = lengthIn * 4; 546 free(tmp); 547 return 0; 548 case kResamplerMode1To6: 549 // We can only handle blocks of 80 samples 550 // Can be fixed, but I don't think it's needed 551 if ((lengthIn % 80) != 0) 552 { 553 return -1; 554 } 555 if (maxLen < (lengthIn * 6)) 556 { 557 return -1; 558 } 559 560 //1:2 561 562 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32)); 563 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn); 564 565 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 566 outLen = lengthIn * 2; 567 568 for (int i = 0; i < outLen; i += 160) 569 { 570 WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3, 571 (WebRtcSpl_State16khzTo48khz *)state2_, 572 tmp_mem); 573 } 574 outLen = outLen * 3; 575 free(tmp_mem); 576 free(tmp); 577 578 return 0; 579 case kResamplerMode1To12: 580 // We can only handle blocks of 40 samples 581 // Can be fixed, but I don't think it's needed 582 if ((lengthIn % 40) != 0) { 583 return -1; 584 } 585 if (maxLen < (lengthIn * 12)) { 586 return -1; 587 } 588 589 tmp_mem = (WebRtc_Word32*) malloc(336 * sizeof(WebRtc_Word32)); 590 tmp = (WebRtc_Word16*) malloc(sizeof(WebRtc_Word16) * 4 * lengthIn); 591 //1:2 592 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, 593 (WebRtc_Word32*) state1_); 594 outLen = lengthIn * 2; 595 //2:4 596 WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, (WebRtc_Word32*) state2_); 597 outLen = outLen * 2; 598 // 4:12 599 for (int i = 0; i < outLen; i += 160) { 600 // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples 601 // as input and outputs a resampled block of 480 samples. The 602 // data is now actually in 32 kHz sampling rate, despite the 603 // function name, and with a resampling factor of three becomes 604 // 96 kHz. 605 WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3, 606 (WebRtcSpl_State16khzTo48khz*) state3_, 607 tmp_mem); 608 } 609 outLen = outLen * 3; 610 free(tmp_mem); 611 free(tmp); 612 613 return 0; 614 case kResamplerMode2To3: 615 if (maxLen < (lengthIn * 3 / 2)) 616 { 617 return -1; 618 } 619 // 2:6 620 // We can only handle blocks of 160 samples 621 // Can be fixed, but I don't think it's needed 622 if ((lengthIn % 160) != 0) 623 { 624 return -1; 625 } 626 tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 3)); 627 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32)); 628 for (int i = 0; i < lengthIn; i += 160) 629 { 630 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3, 631 (WebRtcSpl_State16khzTo48khz *)state1_, 632 tmp_mem); 633 } 634 lengthIn = lengthIn * 3; 635 // 6:3 636 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_); 637 outLen = lengthIn / 2; 638 free(tmp); 639 free(tmp_mem); 640 return 0; 641 case kResamplerMode2To11: 642 643 // We can only handle blocks of 80 samples 644 // Can be fixed, but I don't think it's needed 645 if ((lengthIn % 80) != 0) 646 { 647 return -1; 648 } 649 if (maxLen < ((lengthIn * 11) / 2)) 650 { 651 return -1; 652 } 653 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn); 654 // 1:2 655 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 656 lengthIn *= 2; 657 658 tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32)); 659 660 for (int i = 0; i < lengthIn; i += 80) 661 { 662 WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4, 663 (WebRtcSpl_State8khzTo22khz *)state2_, 664 tmp_mem); 665 } 666 outLen = (lengthIn * 11) / 4; 667 free(tmp_mem); 668 free(tmp); 669 return 0; 670 case kResamplerMode4To11: 671 672 // We can only handle blocks of 80 samples 673 // Can be fixed, but I don't think it's needed 674 if ((lengthIn % 80) != 0) 675 { 676 return -1; 677 } 678 if (maxLen < ((lengthIn * 11) / 4)) 679 { 680 return -1; 681 } 682 tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32)); 683 684 for (int i = 0; i < lengthIn; i += 80) 685 { 686 WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4, 687 (WebRtcSpl_State8khzTo22khz *)state1_, 688 tmp_mem); 689 } 690 outLen = (lengthIn * 11) / 4; 691 free(tmp_mem); 692 return 0; 693 case kResamplerMode8To11: 694 // We can only handle blocks of 160 samples 695 // Can be fixed, but I don't think it's needed 696 if ((lengthIn % 160) != 0) 697 { 698 return -1; 699 } 700 if (maxLen < ((lengthIn * 11) / 8)) 701 { 702 return -1; 703 } 704 tmp_mem = (WebRtc_Word32*)malloc(88 * sizeof(WebRtc_Word32)); 705 706 for (int i = 0; i < lengthIn; i += 160) 707 { 708 WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8, 709 (WebRtcSpl_State16khzTo22khz *)state1_, 710 tmp_mem); 711 } 712 outLen = (lengthIn * 11) / 8; 713 free(tmp_mem); 714 return 0; 715 716 case kResamplerMode11To16: 717 // We can only handle blocks of 110 samples 718 if ((lengthIn % 110) != 0) 719 { 720 return -1; 721 } 722 if (maxLen < ((lengthIn * 16) / 11)) 723 { 724 return -1; 725 } 726 727 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32)); 728 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2)); 729 730 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 731 732 for (int i = 0; i < (lengthIn * 2); i += 220) 733 { 734 WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160, 735 (WebRtcSpl_State22khzTo16khz *)state2_, 736 tmp_mem); 737 } 738 739 outLen = (lengthIn * 16) / 11; 740 741 free(tmp_mem); 742 free(tmp); 743 return 0; 744 745 case kResamplerMode11To32: 746 747 // We can only handle blocks of 110 samples 748 if ((lengthIn % 110) != 0) 749 { 750 return -1; 751 } 752 if (maxLen < ((lengthIn * 32) / 11)) 753 { 754 return -1; 755 } 756 757 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32)); 758 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2)); 759 760 // 11 -> 22 kHz in samplesOut 761 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_); 762 763 // 22 -> 16 in tmp 764 for (int i = 0; i < (lengthIn * 2); i += 220) 765 { 766 WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160, 767 (WebRtcSpl_State22khzTo16khz *)state2_, 768 tmp_mem); 769 } 770 771 // 16 -> 32 in samplesOut 772 WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut, 773 (WebRtc_Word32*)state3_); 774 775 outLen = (lengthIn * 32) / 11; 776 777 free(tmp_mem); 778 free(tmp); 779 return 0; 780 781 case kResamplerMode2To1: 782 if (maxLen < (lengthIn / 2)) 783 { 784 return -1; 785 } 786 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_); 787 outLen = lengthIn / 2; 788 return 0; 789 case kResamplerMode3To1: 790 // We can only handle blocks of 480 samples 791 // Can be fixed, but I don't think it's needed 792 if ((lengthIn % 480) != 0) 793 { 794 return -1; 795 } 796 if (maxLen < (lengthIn / 3)) 797 { 798 return -1; 799 } 800 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32)); 801 802 for (int i = 0; i < lengthIn; i += 480) 803 { 804 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3, 805 (WebRtcSpl_State48khzTo16khz *)state1_, 806 tmp_mem); 807 } 808 outLen = lengthIn / 3; 809 free(tmp_mem); 810 return 0; 811 case kResamplerMode4To1: 812 if (maxLen < (lengthIn / 4)) 813 { 814 return -1; 815 } 816 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * lengthIn / 2); 817 // 4:2 818 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 819 // 2:1 820 WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (WebRtc_Word32*)state2_); 821 outLen = lengthIn / 4; 822 free(tmp); 823 return 0; 824 825 case kResamplerMode6To1: 826 // We can only handle blocks of 480 samples 827 // Can be fixed, but I don't think it's needed 828 if ((lengthIn % 480) != 0) 829 { 830 return -1; 831 } 832 if (maxLen < (lengthIn / 6)) 833 { 834 return -1; 835 } 836 837 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32)); 838 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn) / 3); 839 840 for (int i = 0; i < lengthIn; i += 480) 841 { 842 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3, 843 (WebRtcSpl_State48khzTo16khz *)state1_, 844 tmp_mem); 845 } 846 outLen = lengthIn / 3; 847 free(tmp_mem); 848 WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (WebRtc_Word32*)state2_); 849 free(tmp); 850 outLen = outLen / 2; 851 return 0; 852 case kResamplerMode12To1: 853 // We can only handle blocks of 480 samples 854 // Can be fixed, but I don't think it's needed 855 if ((lengthIn % 480) != 0) { 856 return -1; 857 } 858 if (maxLen < (lengthIn / 12)) { 859 return -1; 860 } 861 862 tmp_mem = (WebRtc_Word32*) malloc(496 * sizeof(WebRtc_Word32)); 863 tmp = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 3); 864 tmp_2 = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 6); 865 // 12:4 866 for (int i = 0; i < lengthIn; i += 480) { 867 // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples 868 // as input and outputs a resampled block of 160 samples. The 869 // data is now actually in 96 kHz sampling rate, despite the 870 // function name, and with a resampling factor of 1/3 becomes 871 // 32 kHz. 872 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3, 873 (WebRtcSpl_State48khzTo16khz*) state1_, 874 tmp_mem); 875 } 876 outLen = lengthIn / 3; 877 free(tmp_mem); 878 // 4:2 879 WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2, 880 (WebRtc_Word32*) state2_); 881 outLen = outLen / 2; 882 free(tmp); 883 // 2:1 884 WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut, 885 (WebRtc_Word32*) state3_); 886 free(tmp_2); 887 outLen = outLen / 2; 888 return 0; 889 case kResamplerMode3To2: 890 if (maxLen < (lengthIn * 2 / 3)) 891 { 892 return -1; 893 } 894 // 3:6 895 tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 2)); 896 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_); 897 lengthIn *= 2; 898 // 6:2 899 // We can only handle blocks of 480 samples 900 // Can be fixed, but I don't think it's needed 901 if ((lengthIn % 480) != 0) 902 { 903 free(tmp); 904 return -1; 905 } 906 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32)); 907 for (int i = 0; i < lengthIn; i += 480) 908 { 909 WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3, 910 (WebRtcSpl_State48khzTo16khz *)state2_, 911 tmp_mem); 912 } 913 outLen = lengthIn / 3; 914 free(tmp); 915 free(tmp_mem); 916 return 0; 917 case kResamplerMode11To2: 918 // We can only handle blocks of 220 samples 919 // Can be fixed, but I don't think it's needed 920 if ((lengthIn % 220) != 0) 921 { 922 return -1; 923 } 924 if (maxLen < ((lengthIn * 2) / 11)) 925 { 926 return -1; 927 } 928 tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32)); 929 tmp = (WebRtc_Word16*)malloc((lengthIn * 4) / 11 * sizeof(WebRtc_Word16)); 930 931 for (int i = 0; i < lengthIn; i += 220) 932 { 933 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11, 934 (WebRtcSpl_State22khzTo8khz *)state1_, 935 tmp_mem); 936 } 937 lengthIn = (lengthIn * 4) / 11; 938 939 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_); 940 outLen = lengthIn / 2; 941 942 free(tmp_mem); 943 free(tmp); 944 return 0; 945 case kResamplerMode11To4: 946 // We can only handle blocks of 220 samples 947 // Can be fixed, but I don't think it's needed 948 if ((lengthIn % 220) != 0) 949 { 950 return -1; 951 } 952 if (maxLen < ((lengthIn * 4) / 11)) 953 { 954 return -1; 955 } 956 tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32)); 957 958 for (int i = 0; i < lengthIn; i += 220) 959 { 960 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11, 961 (WebRtcSpl_State22khzTo8khz *)state1_, 962 tmp_mem); 963 } 964 outLen = (lengthIn * 4) / 11; 965 free(tmp_mem); 966 return 0; 967 case kResamplerMode11To8: 968 // We can only handle blocks of 160 samples 969 // Can be fixed, but I don't think it's needed 970 if ((lengthIn % 220) != 0) 971 { 972 return -1; 973 } 974 if (maxLen < ((lengthIn * 8) / 11)) 975 { 976 return -1; 977 } 978 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32)); 979 980 for (int i = 0; i < lengthIn; i += 220) 981 { 982 WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11, 983 (WebRtcSpl_State22khzTo16khz *)state1_, 984 tmp_mem); 985 } 986 outLen = (lengthIn * 8) / 11; 987 free(tmp_mem); 988 return 0; 989 break; 990 991 } 992 return 0; 993 } 994 995 // Asynchronous resampling, input 996 int Resampler::Insert(WebRtc_Word16 * samplesIn, int lengthIn) 997 { 998 if (my_type_ != kResamplerAsynchronous) 999 { 1000 return -1; 1001 } 1002 int sizeNeeded, tenMsblock; 1003 1004 // Determine need for size of outBuffer 1005 sizeNeeded = out_buffer_size_ + ((lengthIn + in_buffer_size_) * my_out_frequency_khz_) 1006 / my_in_frequency_khz_; 1007 if (sizeNeeded > out_buffer_size_max_) 1008 { 1009 // Round the value upwards to complete 10 ms blocks 1010 tenMsblock = my_out_frequency_khz_ * 10; 1011 sizeNeeded = (sizeNeeded / tenMsblock + 1) * tenMsblock; 1012 out_buffer_ = (WebRtc_Word16*)realloc(out_buffer_, sizeNeeded * sizeof(WebRtc_Word16)); 1013 out_buffer_size_max_ = sizeNeeded; 1014 } 1015 1016 // If we need to use inBuffer, make sure all input data fits there. 1017 1018 tenMsblock = my_in_frequency_khz_ * 10; 1019 if (in_buffer_size_ || (lengthIn % tenMsblock)) 1020 { 1021 // Check if input buffer size is enough 1022 if ((in_buffer_size_ + lengthIn) > in_buffer_size_max_) 1023 { 1024 // Round the value upwards to complete 10 ms blocks 1025 sizeNeeded = ((in_buffer_size_ + lengthIn) / tenMsblock + 1) * tenMsblock; 1026 in_buffer_ = (WebRtc_Word16*)realloc(in_buffer_, 1027 sizeNeeded * sizeof(WebRtc_Word16)); 1028 in_buffer_size_max_ = sizeNeeded; 1029 } 1030 // Copy in data to input buffer 1031 memcpy(in_buffer_ + in_buffer_size_, samplesIn, lengthIn * sizeof(WebRtc_Word16)); 1032 1033 // Resample all available 10 ms blocks 1034 int lenOut; 1035 int dataLenToResample = (in_buffer_size_ / tenMsblock) * tenMsblock; 1036 Push(in_buffer_, dataLenToResample, out_buffer_ + out_buffer_size_, 1037 out_buffer_size_max_ - out_buffer_size_, lenOut); 1038 out_buffer_size_ += lenOut; 1039 1040 // Save the rest 1041 memmove(in_buffer_, in_buffer_ + dataLenToResample, 1042 (in_buffer_size_ - dataLenToResample) * sizeof(WebRtc_Word16)); 1043 in_buffer_size_ -= dataLenToResample; 1044 } else 1045 { 1046 // Just resample 1047 int lenOut; 1048 Push(in_buffer_, lengthIn, out_buffer_ + out_buffer_size_, 1049 out_buffer_size_max_ - out_buffer_size_, lenOut); 1050 out_buffer_size_ += lenOut; 1051 } 1052 1053 return 0; 1054 } 1055 1056 // Asynchronous resampling output, remaining samples are buffered 1057 int Resampler::Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen) 1058 { 1059 if (my_type_ != kResamplerAsynchronous) 1060 { 1061 return -1; 1062 } 1063 1064 // Check that we have enough data 1065 if (desiredLen <= out_buffer_size_) 1066 { 1067 // Give out the date 1068 memcpy(samplesOut, out_buffer_, desiredLen * sizeof(WebRtc_Word32)); 1069 1070 // Shuffle down remaining 1071 memmove(out_buffer_, out_buffer_ + desiredLen, 1072 (out_buffer_size_ - desiredLen) * sizeof(WebRtc_Word16)); 1073 1074 // Update remaining size 1075 out_buffer_size_ -= desiredLen; 1076 1077 return 0; 1078 } else 1079 { 1080 return -1; 1081 } 1082 } 1083 1084 } // namespace webrtc 1085