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     Reset(inFreq, outFreq, type);
66 }
67 
~Resampler()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 
ResetIfNeeded(int inFreq,int outFreq,ResamplerType type)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 
Reset(int inFreq,int outFreq,ResamplerType type)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
Push(const WebRtc_Word16 * samplesIn,int lengthIn,WebRtc_Word16 * samplesOut,int maxLen,int & outLen)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
Insert(WebRtc_Word16 * samplesIn,int lengthIn)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
Pull(WebRtc_Word16 * samplesOut,int desiredLen,int & outLen)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