blob: 78868248fc3d606343ea54d316e42a544b3d7175
1 | #include <math.h> |
2 | #include <cutils/log.h> |
3 | |
4 | #include "audio_resampler.h" |
5 | |
6 | #define LOG_TAG "usb_audio_resampler" |
7 | |
8 | //Clip from 16.16 fixed-point to 0.15 fixed-point. |
9 | inline static short clip(int x) { |
10 | if (x < -32768) { |
11 | return -32768; |
12 | } else if (x > 32767) { |
13 | return 32767; |
14 | } else { |
15 | return x; |
16 | } |
17 | } |
18 | |
19 | int resampler_init(struct resample_para *resample) { |
20 | |
21 | ALOGD("%s, Init Resampler: input_sr = %d, output_sr = %d \n", |
22 | __FUNCTION__,resample->input_sr,resample->output_sr); |
23 | |
24 | static const double kPhaseMultiplier = 1L << 28; |
25 | |
26 | resample->FractionStep = (unsigned int) (resample->input_sr * kPhaseMultiplier |
27 | / resample->output_sr); |
28 | resample->SampleFraction = 0; |
29 | resample->lastsample_left = 0; |
30 | resample->lastsample_right = 0; |
31 | return 0; |
32 | } |
33 | |
34 | int resample_process(struct resample_para *resample, unsigned int in_frame, |
35 | short* input, short* output) { |
36 | unsigned int inputIndex = 0; |
37 | unsigned int outputIndex = 0; |
38 | unsigned int FractionStep = resample->FractionStep; |
39 | |
40 | static const unsigned int kPhaseMask = (1LU << 28) - 1; |
41 | unsigned int frac = resample->SampleFraction; |
42 | short lastsample_left = resample->lastsample_left; |
43 | short lastsample_right = resample->lastsample_right; |
44 | |
45 | if(resample->channels == 2){ |
46 | while (inputIndex == 0) { |
47 | *output++ = clip((int) lastsample_left + |
48 | ((((int) input[0] - (int) lastsample_left) * ((int) frac >> 13)) >> 15)); |
49 | *output++ = clip((int) lastsample_right + |
50 | ((((int) input[1] - (int) lastsample_right) * ((int) frac >> 13)) >> 15)); |
51 | |
52 | frac += FractionStep; |
53 | inputIndex += (frac >> 28); |
54 | frac = (frac & kPhaseMask); |
55 | outputIndex++; |
56 | } |
57 | |
58 | while (inputIndex < in_frame) { |
59 | *output++ = clip((int) input[2 * inputIndex - 2] + ((((int) input[2 * inputIndex] |
60 | - (int) input[2 * inputIndex - 2]) * ((int) frac >> 13)) >> 15)); |
61 | *output++ = clip((int) input[2 * inputIndex - 1] + ((((int) input[2 * inputIndex + 1] |
62 | - (int) input[2 * inputIndex - 1]) * ((int) frac >> 13)) >> 15)); |
63 | |
64 | frac += FractionStep; |
65 | inputIndex += (frac >> 28); |
66 | frac = (frac & kPhaseMask); |
67 | outputIndex++; |
68 | } |
69 | |
70 | resample->lastsample_left = input[2 * in_frame - 2]; |
71 | resample->lastsample_right = input[2 * in_frame - 1]; |
72 | resample->SampleFraction = frac; |
73 | }else{ |
74 | //left channel as output |
75 | while (inputIndex == 0) { |
76 | *output++ = clip((int) lastsample_left + |
77 | ((((int) input[0] - (int) lastsample_left) * ((int) frac >> 13)) >> 15)); |
78 | |
79 | frac += FractionStep; |
80 | inputIndex += (frac >> 28); |
81 | frac = (frac & kPhaseMask); |
82 | outputIndex++; |
83 | } |
84 | |
85 | while (inputIndex < in_frame) { |
86 | *output++ = clip((int) input[2 * inputIndex - 2] + ((((int) input[2 * inputIndex] |
87 | - (int) input[2 * inputIndex - 2]) * ((int) frac >> 13)) >> 15)); |
88 | |
89 | frac += FractionStep; |
90 | inputIndex += (frac >> 28); |
91 | frac = (frac & kPhaseMask); |
92 | outputIndex++; |
93 | } |
94 | |
95 | resample->lastsample_left = input[2 * in_frame - 2]; |
96 | resample->SampleFraction = frac; |
97 | } |
98 | |
99 | return outputIndex; |
100 | } |
101 | |
102 | |
103 | |
104 |