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
|
/* Copyright 2012 Dietrich Epp <depp@zdome.net> */
#pragma once
#include "types.h"
#include "param.h"
#include <vector>
/* Bits used for interpolating between two filters. The scalar
implementation supports up to 16 bits, but the SIMD implementations
generally only support 14 so the values can fit in a signed 16-bit
word. We bring all implementations to the same accuracy in order
to ensure that all implementations produce the same results. */
#define INTERP_BITS 14
/*
Filter types
*/
enum lfr_ftype_t {
LFR_FTYPE_S16,
LFR_FTYPE_F32
};
/*
Array of FIR filters.
Let N=2^log2nfilt, M=nsamp.
This is an array of N+1 filters, 0..N, with each filter M samples
long. Filter number I will be centered on the sample with offset:
floor(M/2) + I/N
This means that filter N will be a copy of filter 0, except shifted
to the right by one sample. This extra filter makes the
interpolation code simpler.
*/
/*
Information queries that a filter responds to. Each query gives an
integer or floating point result, automatically cast to the type
requested.
*/
enum LFR_INFO_TYPE {
/*
The size of the filter, also known as the filter's order. This
does not include oversampling. The resampler will read this
many samples, starting with the current position (rounded down),
whenever it calculates a sample.
In other words, this is the amount of overlap needed when
resampling consecutive buffers.
*/
LFR_INFO_SIZE,
/*
Filter delay. Note that lfr_filter_delay returns a fixed point
number and is usually preferable.
*/
LFR_INFO_DELAY,
/*
The is the number of bytes used by filter coefficients.
*/
LFR_INFO_MEMSIZE,
/*
The normalized pass frequency the filter was designed with.
*/
LFR_INFO_FPASS,
/*
The normalized stop frequency the filter was designed with.
*/
LFR_INFO_FSTOP,
/*
The stopband attenuation, in dB, that the filter was designed
with.
*/
LFR_INFO_ATTEN,
LFR_INFO_COUNT
};
/*
* A filter for resampling audio.
*/
struct lfr_filter {
/*
FIR filter coefficient data type.
*/
lfr_ftype_t type;
/*
FIR filter data.
*/
std::vector<char> data;
/*
Length of each filter, in samples. This is chosen to make each
filter size a multiple of the SIMD register size. Most SIMD
implementations today use 16 byte registers, so this will
usually be a multiple of 8 or 4, depending on the coefficient
type.
*/
int nsamp;
/*
Base 2 logarithm of the number of different filters. There is
always an additional filter at the end of the filter array to
simplify interpolation, this extra filter is a copy of the first
filter shifted right by one sample.
*/
int log2nfilt;
/*
Filter delay. Filters are causal, so this should be
non-negative.
*/
lfr_fixed_t delay;
/*
Design parameters of the filter.
*/
double f_pass, f_stop, atten;
lfr_filter(lfr_param& param);
int geti(LFR_INFO_TYPE iname, bool convert = true) const;
double getf(LFR_INFO_TYPE iname, bool convert = true) const;
/*
Resample an audio buffer. Note that this function may need to
create intermediate buffers if there is no function which can
directly operate on the input and output formats. No intermediate
buffers will be necessary if the following conditions are met:
- Input and output formats are identical.
- Sample format is either S16_NATIVE or F32_NATIVE.
- The number of channels is either 1 (mono) or 2 (stereo).
pos: Current position relative to the start of the input buffer,
expressed as a 32.32 fixed point number. On return, this will
contain the updated position. Positions outside the input buffer
are acceptable, it will be treated as if the input buffer were
padded with an unlimited number of zeroes on either side.
inv_ratio: Inverse of the resampling ratio, expressed as a 32.32
fixed point number. This number is equal to the input sample rate
divided by the output sample rate.
dither: State of the PRNG used for dithering.
nchan: Number of interleaved channels.
out, in: Input and output buffers. The buffers are not permitted to
alias each other.
outlen, inlen: Length of buffers, in frames. Note that the length
type is 'int' instead of 'size_t'; this matches the precision of
buffer positions.
outfmt, infmt: Format of input and output buffers.
filter: A suitable low-pass filter for resampling at the given
ratio.
*/
void resample(
lfr_fixed_t *pos, lfr_fixed_t inv_ratio,
unsigned *dither, int nchan,
void *out, lfr_fmt_t outfmt, int outlen,
const void *in, lfr_fmt_t infmt, int inlen);
private:
/*
Create a Kaiser-windowed sinc filter.
*/
void setup_window(double cutoff, double beta);
};
|