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