• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef fooresamplerhfoo
2 #define fooresamplerhfoo
3 
4 /***
5   This file is part of PulseAudio.
6 
7   Copyright 2004-2006 Lennart Poettering
8 
9   PulseAudio is free software; you can redistribute it and/or modify
10   it under the terms of the GNU Lesser General Public License as published
11   by the Free Software Foundation; either version 2.1 of the License,
12   or (at your option) any later version.
13 
14   PulseAudio is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   General Public License for more details.
18 
19   You should have received a copy of the GNU Lesser General Public License
20   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
21 ***/
22 
23 #include <pulse/sample.h>
24 #include <pulse/channelmap.h>
25 #include <pulsecore/memblock.h>
26 #include <pulsecore/memchunk.h>
27 #include <pulsecore/sconv.h>
28 #include <pulsecore/remap.h>
29 #include <pulsecore/filter/lfe-filter.h>
30 
31 typedef struct pa_resampler pa_resampler;
32 typedef struct pa_resampler_impl pa_resampler_impl;
33 
34 struct pa_resampler_impl {
35     void (*free)(pa_resampler *r);
36     void (*update_rates)(pa_resampler *r);
37 
38     /* Returns the number of leftover frames in the input buffer. */
39     unsigned (*resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_n_frames, pa_memchunk *out, unsigned *out_n_frames);
40 
41     void (*reset)(pa_resampler *r);
42     void *data;
43 };
44 
45 typedef enum pa_resample_method {
46     PA_RESAMPLER_INVALID                 = -1,
47     PA_RESAMPLER_SRC_SINC_BEST_QUALITY   = 0, /* = SRC_SINC_BEST_QUALITY */
48     PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = 1, /* = SRC_SINC_MEDIUM_QUALITY */
49     PA_RESAMPLER_SRC_SINC_FASTEST        = 2, /* = SRC_SINC_FASTEST */
50     PA_RESAMPLER_SRC_ZERO_ORDER_HOLD     = 3, /* = SRC_ZERO_ORDER_HOLD */
51     PA_RESAMPLER_SRC_LINEAR              = 4, /* = SRC_LINEAR */
52     PA_RESAMPLER_TRIVIAL,
53     PA_RESAMPLER_SPEEX_FLOAT_BASE,
54     PA_RESAMPLER_SPEEX_FLOAT_MAX = PA_RESAMPLER_SPEEX_FLOAT_BASE + 10,
55     PA_RESAMPLER_SPEEX_FIXED_BASE,
56     PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10,
57     PA_RESAMPLER_FFMPEG,
58     PA_RESAMPLER_AUTO, /* automatic select based on sample format */
59     PA_RESAMPLER_COPY,
60     PA_RESAMPLER_PEAKS,
61     PA_RESAMPLER_SOXR_MQ,
62     PA_RESAMPLER_SOXR_HQ,
63     PA_RESAMPLER_SOXR_VHQ,
64     PA_RESAMPLER_MAX
65 } pa_resample_method_t;
66 
67 typedef enum pa_resample_flags {
68     PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
69     PA_RESAMPLER_NO_REMAP      = 0x0002U,  /* implies NO_REMIX */
70     PA_RESAMPLER_NO_REMIX      = 0x0004U,
71     PA_RESAMPLER_NO_FILL_SINK  = 0x0010U,
72     PA_RESAMPLER_PRODUCE_LFE   = 0x0020U,
73     PA_RESAMPLER_CONSUME_LFE   = 0x0040U,
74 } pa_resample_flags_t;
75 
76 /* Currently, the soxr reampler has the largest delay of all supported resamplers.
77  * The maximum value below has been obtained empirically and contains a safety
78  * margin of about 3ms. If the resampler configuration is changed or additional
79  * resamplers are added, the constant must be re-evaluated. */
80 #define PA_RESAMPLER_MAX_DELAY_USEC 33000
81 
82 struct pa_resampler {
83     pa_resample_method_t method;
84     pa_resample_flags_t flags;
85 
86     pa_sample_spec i_ss, o_ss;
87     pa_channel_map i_cm, o_cm;
88     size_t i_fz, o_fz, w_fz, w_sz;
89     pa_mempool *mempool;
90 
91     pa_memchunk to_work_format_buf;
92     pa_memchunk remap_buf;
93     pa_memchunk resample_buf;
94     pa_memchunk from_work_format_buf;
95     size_t to_work_format_buf_size;
96     size_t remap_buf_size;
97     size_t resample_buf_size;
98     size_t from_work_format_buf_size;
99 
100     /* points to buffer before resampling stage, remap or to_work */
101     pa_memchunk *leftover_buf;
102     size_t *leftover_buf_size;
103 
104     /* have_leftover points to leftover_in_remap or leftover_in_to_work */
105     bool *have_leftover;
106     bool leftover_in_remap;
107     bool leftover_in_to_work;
108 
109     pa_sample_format_t work_format;
110     uint8_t work_channels;
111 
112     pa_convert_func_t to_work_format_func;
113     pa_convert_func_t from_work_format_func;
114 
115     pa_remap_t remap;
116     bool map_required;
117 
118     double in_frames;
119     double out_frames;
120     unsigned gcd;
121 
122     pa_lfe_filter_t *lfe_filter;
123 
124     pa_resampler_impl impl;
125 };
126 
127 pa_resampler* pa_resampler_new(
128         pa_mempool *pool,
129         const pa_sample_spec *a,
130         const pa_channel_map *am,
131         const pa_sample_spec *b,
132         const pa_channel_map *bm,
133 	unsigned crossover_freq,
134         pa_resample_method_t resample_method,
135         pa_resample_flags_t flags);
136 
137 void pa_resampler_free(pa_resampler *r);
138 
139 /* Returns the size of an input memory block which is required to return the specified amount of output data */
140 size_t pa_resampler_request(pa_resampler *r, size_t out_length);
141 
142 /* Inverse of pa_resampler_request() */
143 size_t pa_resampler_result(pa_resampler *r, size_t in_length);
144 
145 /* Returns the maximum size of input blocks we can process without needing bounce buffers larger than the mempool tile size. */
146 size_t pa_resampler_max_block_size(pa_resampler *r);
147 
148 /* Pass the specified memory chunk to the resampler and return the newly resampled data */
149 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out);
150 
151 /* Change the input rate of the resampler object */
152 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate);
153 
154 /* Change the output rate of the resampler object */
155 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate);
156 
157 /* Reinitialize state of the resampler, possibly due to seeking or other discontinuities */
158 void pa_resampler_reset(pa_resampler *r);
159 
160 /* Prepare resampler for use by running some old data through it. */
161 size_t pa_resampler_prepare(pa_resampler *r, pa_memblockq *history_queue, size_t amount);
162 
163 /* Rewind resampler */
164 size_t pa_resampler_rewind(pa_resampler *r, size_t out_bytes, pa_memblockq *history_queue, size_t amount);
165 
166 /* Return the resampling method of the resampler object */
167 pa_resample_method_t pa_resampler_get_method(pa_resampler *r);
168 
169 /* Try to parse the resampler method */
170 pa_resample_method_t pa_parse_resample_method(const char *string);
171 
172 /* return a human readable string for the specified resampling method. Inverse of pa_parse_resample_method() */
173 const char *pa_resample_method_to_string(pa_resample_method_t m);
174 
175 /* Return 1 when the specified resampling method is supported */
176 int pa_resample_method_supported(pa_resample_method_t m);
177 
178 /* Get delay of the resampler in input frames */
179 double pa_resampler_get_delay(pa_resampler *r, bool allow_negative);
180 
181 /* Get delay of the resampler in usec */
182 pa_usec_t pa_resampler_get_delay_usec(pa_resampler *r);
183 
184 /* Get the GCD of input and outpu rate */
185 unsigned pa_resampler_get_gcd(pa_resampler *r);
186 
187 /* Get maximum number of history frames */
188 size_t pa_resampler_get_max_history(pa_resampler *r);
189 
190 const pa_channel_map* pa_resampler_input_channel_map(pa_resampler *r);
191 const pa_sample_spec* pa_resampler_input_sample_spec(pa_resampler *r);
192 const pa_channel_map* pa_resampler_output_channel_map(pa_resampler *r);
193 const pa_sample_spec* pa_resampler_output_sample_spec(pa_resampler *r);
194 
195 /* Implementation specific init functions */
196 int pa_resampler_ffmpeg_init(pa_resampler *r);
197 int pa_resampler_libsamplerate_init(pa_resampler *r);
198 int pa_resampler_peaks_init(pa_resampler *r);
199 int pa_resampler_speex_init(pa_resampler *r);
200 int pa_resampler_trivial_init(pa_resampler*r);
201 int pa_resampler_soxr_init(pa_resampler *r);
202 
203 /* Resampler-specific quirks */
204 bool pa_speex_is_fixed_point(void);
205 
206 #endif
207