forked from LinuxDigger/WebRTC_Resampler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resampler.h
369 lines (305 loc) · 11.1 KB
/
resampler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef _WEBRTC_RESAMPLER_H_
#define _WEBRTC_RESAMPLER_H_
#ifndef nullptr
#define nullptr NULL
#endif
#include <stdio.h>
#include <stddef.h>
// Processor architecture detection. For more info on what's defined, see:
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
// http://www.agner.org/optimize/calling_conventions.pdf
// or with gcc, run: "echo | gcc -E -dM -"
#if defined(_M_X64) || defined(__x86_64__)
#define WEBRTC_ARCH_X86_FAMILY
#define WEBRTC_ARCH_64_BITS
#define WEBRTC_ARCH_LITTLE_ENDIAN
#elif defined(__aarch64__)
#define WEBRTC_ARCH_ARM_FAMILY
#define WEBRTC_ARCH_64_BITS
#define WEBRTC_ARCH_LITTLE_ENDIAN
#elif defined(_M_IX86) || defined(__i386__)
#define WEBRTC_ARCH_X86_FAMILY
#define WEBRTC_ARCH_X86
#define WEBRTC_ARCH_32_BITS
#define WEBRTC_ARCH_LITTLE_ENDIAN
#elif defined(__ARMEL__)
#define WEBRTC_ARCH_ARM_FAMILY
#define WEBRTC_ARCH_32_BITS
#define WEBRTC_ARCH_LITTLE_ENDIAN
#elif defined(__MIPSEL__)
#define WEBRTC_ARCH_MIPS_FAMILY
#if defined(__LP64__)
#define WEBRTC_ARCH_64_BITS
#else
#define WEBRTC_ARCH_32_BITS
#endif
#define WEBRTC_ARCH_LITTLE_ENDIAN
#elif defined(__pnacl__)
#define WEBRTC_ARCH_32_BITS
#define WEBRTC_ARCH_LITTLE_ENDIAN
#else
#error Please add support for your architecture in typedefs.h
#endif
#if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN))
#error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN
#endif
// TODO(zhongwei.yao): WEBRTC_CPU_DETECTION is only used in one place; we should
// probably just remove it.
#if (defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__))
#define WEBRTC_CPU_DETECTION
#endif
#include <stdint.h>
// Annotate a function indicating the caller must examine the return value.
// Use like:
// int foo() RTC_WARN_UNUSED_RESULT;
// To explicitly ignore a result, cast to void.
// TODO(kwiberg): Remove when we can use [[nodiscard]] from C++17.
#if defined(__clang__)
#define RTC_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#elif defined(__GNUC__)
// gcc has a __warn_unused_result__ attribute, but you can't quiet it by
// casting to void, so we don't use it.
#define RTC_WARN_UNUSED_RESULT
#else
#define RTC_WARN_UNUSED_RESULT
#endif
// Put after a variable that might not be used, to prevent compiler warnings:
// int result ATTRIBUTE_UNUSED = DoSomething();
// assert(result == 17);
// Deprecated since it only works with GCC & clang. See RTC_UNUSED below.
// TODO(terelius): Remove.
#ifndef ATTRIBUTE_UNUSED
#if defined(__GNUC__) || defined(__clang__)
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#else
#define ATTRIBUTE_UNUSED
#endif
#endif
// Macro to be used for switch-case fallthrough (required for enabling
// -Wimplicit-fallthrough warning on Clang).
#ifndef FALLTHROUGH
#if defined(__clang__)
#define FALLTHROUGH() [[clang::fallthrough]]
#else
#define FALLTHROUGH() do { } while (0)
#endif
#endif
#ifndef NO_RETURN
// Annotate a function that will not return control flow to the caller.
#if defined(_MSC_VER)
#define NO_RETURN __declspec(noreturn)
#elif defined(__GNUC__)
#define NO_RETURN __attribute__ ((__noreturn__))
#else
#define NO_RETURN
#endif
#endif
// Prevent the compiler from warning about an unused variable. For example:
// int result = DoSomething();
// assert(result == 17);
// RTC_UNUSED(result);
// Note: In most cases it is better to remove the unused variable rather than
// suppressing the compiler warning.
#ifndef RTC_UNUSED
#define RTC_UNUSED(x) static_cast<void>(x)
#endif // RTC_UNUSED
/*******************************************************************
* resample_by_2_fast.c
* Functions for internal use in the other resample functions
******************************************************************/
void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out,
int32_t *state);
void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len,
int32_t *out, int32_t *state);
void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len,
int16_t *out, int32_t *state);
void WebRtcSpl_LPBy2ShortToInt(const int16_t *in, int32_t len,
int32_t *out, int32_t *state);
#include <string.h>
// C + the 32 most significant bits of A * B
#define WEBRTC_SPL_SCALEDIFF32(A, B, C) \
((C) + ((B) >> 16) * (A) + (((uint32_t)((B) & 0x0000FFFF) * (A)) >> 16))
#ifdef __cplusplus
extern "C" {
#endif
/************************************************************
*
* RESAMPLING FUNCTIONS AND THEIR STRUCTS ARE DEFINED BELOW
*
************************************************************/
/*******************************************************************
* resample.c
*
* Includes the following resampling combinations
* 22 kHz -> 16 kHz
* 16 kHz -> 22 kHz
* 22 kHz -> 8 kHz
* 8 kHz -> 22 kHz
*
******************************************************************/
// state structure for 22 -> 16 resampler
typedef struct {
int32_t S_22_44[8];
int32_t S_44_32[8];
int32_t S_32_16[8];
} WebRtcSpl_State22khzTo16khz;
void WebRtcSpl_Resample22khzTo16khz(const int16_t *in,
int16_t *out,
WebRtcSpl_State22khzTo16khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz *state);
// state structure for 16 -> 22 resampler
typedef struct {
int32_t S_16_32[8];
int32_t S_32_22[8];
} WebRtcSpl_State16khzTo22khz;
void WebRtcSpl_Resample16khzTo22khz(const int16_t *in,
int16_t *out,
WebRtcSpl_State16khzTo22khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz *state);
// state structure for 22 -> 8 resampler
typedef struct {
int32_t S_22_22[16];
int32_t S_22_16[8];
int32_t S_16_8[8];
} WebRtcSpl_State22khzTo8khz;
void WebRtcSpl_Resample22khzTo8khz(const int16_t *in, int16_t *out,
WebRtcSpl_State22khzTo8khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz *state);
// state structure for 8 -> 22 resampler
typedef struct {
int32_t S_8_16[8];
int32_t S_16_11[8];
int32_t S_11_22[8];
} WebRtcSpl_State8khzTo22khz;
void WebRtcSpl_Resample8khzTo22khz(const int16_t *in, int16_t *out,
WebRtcSpl_State8khzTo22khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz *state);
/*******************************************************************
* resample_fractional.c
* Functions for internal use in the other resample functions
*
* Includes the following resampling combinations
* 48 kHz -> 32 kHz
* 32 kHz -> 24 kHz
* 44 kHz -> 32 kHz
*
******************************************************************/
void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K);
void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K);
void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K);
/*******************************************************************
* resample_48khz.c
*
* Includes the following resampling combinations
* 48 kHz -> 16 kHz
* 16 kHz -> 48 kHz
* 48 kHz -> 8 kHz
* 8 kHz -> 48 kHz
*
******************************************************************/
typedef struct {
int32_t S_48_48[16];
int32_t S_48_32[8];
int32_t S_32_16[8];
} WebRtcSpl_State48khzTo16khz;
void WebRtcSpl_Resample48khzTo16khz(const int16_t *in, int16_t *out,
WebRtcSpl_State48khzTo16khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz *state);
typedef struct {
int32_t S_16_32[8];
int32_t S_32_24[8];
int32_t S_24_48[8];
} WebRtcSpl_State16khzTo48khz;
void WebRtcSpl_Resample16khzTo48khz(const int16_t *in, int16_t *out,
WebRtcSpl_State16khzTo48khz *state,
int32_t *tmpmem);
void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz *state);
/*******************************************************************
* resample_by_2.c
*
* Includes down and up sampling by a factor of two.
*
******************************************************************/
void WebRtcSpl_DownsampleBy2(const int16_t *in, size_t len,
int16_t *out, int32_t *filtState);
void WebRtcSpl_UpsampleBy2(const int16_t *in, size_t len,
int16_t *out, int32_t *filtState);
#ifdef __cplusplus
}
#endif // __cplusplus
// All methods return 0 on success and -1 on failure.
class Resampler {
public:
Resampler();
Resampler(size_t inFreq, size_t outFreq, size_t num_channels);
~Resampler();
// Reset all states
int Reset(size_t inFreq, size_t outFreq, size_t num_channels);
// Reset all states if any parameter has changed
int ResetIfNeeded(size_t inFreq, size_t outFreq, size_t num_channels);
// Resample samplesIn to samplesOut.
int Push(const int16_t *samplesIn, size_t lengthIn, int16_t *samplesOut,
size_t maxLen, size_t &outLen); // NOLINT: to avoid changing APIs
private:
enum ResamplerMode {
kResamplerMode1To1,
kResamplerMode1To2,
kResamplerMode1To3,
kResamplerMode1To4,
kResamplerMode1To6,
kResamplerMode1To12,
kResamplerMode2To3,
kResamplerMode2To11,
kResamplerMode4To11,
kResamplerMode8To11,
kResamplerMode11To16,
kResamplerMode11To32,
kResamplerMode2To1,
kResamplerMode3To1,
kResamplerMode4To1,
kResamplerMode6To1,
kResamplerMode12To1,
kResamplerMode3To2,
kResamplerMode11To2,
kResamplerMode11To4,
kResamplerMode11To8
};
// Computes the resampler mode for a given sampling frequency pair.
// Returns -1 for unsupported frequency pairs.
static int ComputeResamplerMode(int in_freq_hz,
int out_freq_hz,
ResamplerMode *mode);
// Generic pointers since we don't know what states we'll need
void *state1_;
void *state2_;
void *state3_;
// Storage if needed
int16_t *in_buffer_;
int16_t *out_buffer_;
size_t in_buffer_size_;
size_t out_buffer_size_;
size_t in_buffer_size_max_;
size_t out_buffer_size_max_;
size_t my_in_frequency_khz_;
size_t my_out_frequency_khz_;
ResamplerMode my_mode_;
size_t num_channels_;
// Extra instance for stereo
Resampler *slave_left_;
Resampler *slave_right_;
};
#endif