chiark / gitweb /
doxygen: clean up function documentation.
[disorder] / lib / resample.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2009 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /** @file lib/resample.c
20  * @brief Audio resampling
21  *
22  * General purpose audio format conversion.  Rate conversion only works if the
23  * SRC samplerate library is available, but the bitness/channel/endianness
24  * conversion works regardless.
25  */
26
27 #include "common.h"
28 #include "resample.h"
29 #include "log.h"
30 #include "mem.h"
31
32 /** @brief Number of intermediate-format samples */
33 #define SAMPLES 1024
34
35 /** @brief Multiplier for signed formats to allow easy switching */
36 #define SIGNED 4
37
38 /** @brief Initialize a resampler
39  * @param rs Resampler
40  * @param input_bits Bits/sample in input
41  * @param input_channels Number of input channels
42  * @param input_signed Whether input samples are signed or unsigned
43  * @param input_rate Frames/second in input
44  * @param input_endian Input endianness (@c ENDIAN_BIG or @c ENDIAN_LITTLE)
45  * @param output_bits Bits/sample in output
46  * @param output_channels Number of output channels
47  * @param output_rate Frames/second in output
48  * @param output_signed Whether output samples are signed or unsigned
49  * @param output_endian Output endianness (@c ENDIAN_BIG or @c ENDIAN_LITTLE)
50  *
51  * For formats with more than two channels it's assume that the first
52  * two channels are left and right.  No particular meaning is attached
53  * to additional channels other than to assume channel N in an input
54  * means the same as channel N in an output, for N>1.
55  */
56 void resample_init(struct resampler *rs,
57                     int input_bits, int input_channels,
58                     int input_rate, int input_signed,
59                     int input_endian,
60                     int output_bits, int output_channels,
61                     int output_rate, int output_signed,
62                     int output_endian) {
63   memset(rs, 0, sizeof *rs);
64   assert(input_bits == 8 || input_bits == 16);
65   assert(output_bits == 8 || output_bits == 16);
66   assert(input_endian == ENDIAN_BIG || input_endian == ENDIAN_LITTLE);
67   assert(output_endian == ENDIAN_BIG || output_endian == ENDIAN_LITTLE);
68   assert(ENDIAN_BIG >= 0 && ENDIAN_BIG < SIGNED);
69   assert(ENDIAN_LITTLE >= 0 && ENDIAN_LITTLE < SIGNED);
70   rs->input_bits = input_bits;
71   rs->input_channels = input_channels;
72   rs->input_rate = input_rate;
73   rs->input_signed = SIGNED * !!input_signed;
74   rs->input_endian = input_endian;
75   rs->output_bits = output_bits;
76   rs->output_channels = output_channels;
77   rs->output_rate = output_rate;
78   rs->output_signed = SIGNED * !!output_signed;
79   rs->output_endian = output_endian;
80   rs->input_bytes_per_sample = (rs->input_bits + 7) / 8;
81   rs->input_bytes_per_frame = rs->input_channels * rs->input_bytes_per_sample;
82   if(rs->input_rate != rs->output_rate) {
83 #if HAVE_SAMPLERATE_H
84     int error_;
85     rs->state = src_new(SRC_SINC_BEST_QUALITY, rs->output_channels, &error_);
86     if(!rs->state)
87       disorder_fatal(0, "calling src_new: %s", src_strerror(error_));
88 #else
89     disorder_fatal(0, "need to resample audio data but libsamplerate not available");
90 #endif
91   }
92 }
93
94 /** @brief Destroy a resampler
95  * @param rs Resampler
96  */
97 void resample_close(struct resampler *rs) {
98 #if HAVE_SAMPLERATE_H
99   if(rs->state)
100     src_delete(rs->state);
101 #else
102   rs = 0;                               /* quieten compiler */
103 #endif
104 }
105
106 /** @brief Get one sample value and normalize it to [-1,1]
107  * @param rs Resampler state
108  * @param bytes Pointer to input data
109  * @param where Where to store result
110  * @return Number of bytes consumed
111  */
112 static size_t resample_get_sample(const struct resampler *rs,
113                                   const uint8_t *bytes,
114                                   float *where) {
115   switch(rs->input_bits + rs->input_signed + rs->input_endian) {
116   case 8+ENDIAN_BIG:
117   case 8+ENDIAN_LITTLE:
118     *where = (bytes[0] - 128)/ 128.0;
119     return 1;
120   case 8+SIGNED+ENDIAN_BIG:
121   case 8+SIGNED+ENDIAN_LITTLE:
122     *where = (int8_t)bytes[0] / 128.0;
123     return 1;
124   case 16+ENDIAN_BIG:
125     *where = (bytes[0] * 256 + bytes[1] - 32768)/ 32768.0;
126     return 2;
127     break;
128   case 16+ENDIAN_LITTLE:
129     *where = (bytes[1] * 256 + bytes[0] - 32768)/ 32768.0;
130     return 2;
131     break;
132   case 16+SIGNED+ENDIAN_BIG:
133     *where = (int16_t)(bytes[0] * 256 + bytes[1])/ 32768.0;
134     return 2;
135     break;
136   case 16+SIGNED+ENDIAN_LITTLE:
137     *where = (int16_t)(bytes[1] * 256 + bytes[0])/ 32768.0;
138     return 2;
139     break;
140   default:
141     assert(!"unsupported sample format");
142   }
143 }
144
145 static inline int clip(int n, int min, int max) {
146   if(n >= min) {
147     if(n <= max)
148       return n;
149     else
150       return max;
151   } else
152     return min;
153 }
154
155 /** @brief Store one sample value
156  * @param rs Resampler state
157  * @param sample Sample value
158  * @param bytes Where to store it
159  * @return Number of bytes stored
160  *
161  * The value is clipped naively if it will not fit.
162  */
163 static size_t resample_put_sample(const struct resampler *rs,
164                                   float sample,
165                                   uint8_t *bytes) {
166   unsigned value;
167   switch(rs->output_bits + rs->output_signed + rs->output_endian) {
168   case 8+ENDIAN_BIG:
169   case 8+ENDIAN_LITTLE:
170     *bytes = clip(sample * 128.0 + 128, 0, 255);
171     return 1;
172   case 8+SIGNED+ENDIAN_BIG:
173   case 8+SIGNED+ENDIAN_LITTLE:
174     *bytes = clip((int)(sample * 128.0), -128, 127);
175     return 1;
176   case 16+ENDIAN_BIG:                   /* unsigned */
177     value = clip(sample * 32768.0 + 32768, 0, 65535);
178     *bytes++ = value >> 8;
179     *bytes++ = value;
180     return 2;
181   case 16+ENDIAN_LITTLE:
182     value = clip(sample * 32768.0 + 32768, 0, 65535);
183     *bytes++ = value;
184     *bytes++ = value >> 8;
185     return 2;
186   case 16+SIGNED+ENDIAN_BIG:
187     value = clip(sample * 32768.0, -32768, 32767);
188     *bytes++ = value >> 8;
189     *bytes++ = value;
190     return 2;
191   case 16+SIGNED+ENDIAN_LITTLE:
192     value = clip(sample * 32768.0, -32768, 32767);
193     *bytes++ = value;
194     *bytes++ = value >> 8;
195     return 2;
196   default:
197     assert(!"unsupported sample format");
198   }
199 }
200
201 /** @brief Convert input samples to floats
202  * @param rs Resampler state
203  * @param bytes Input bytes
204  * @param nframes Number of input frames
205  * @param floats Where to store converted data
206  *
207  * @p floats must be big enough.  As well as converting to floats this
208  * also converts to the output's channel format.
209  *
210  * Excess input channels are just discarded.  If there are insufficient input
211  * channels the last one is duplicated as often as necessary to make up the
212  * numbers.  This is a rather naff heuristic and may be improved in a future
213  * version, but mostly in DisOrder the output is pretty much always stereo and
214  * the input either mono or stereo, so the result isn't actually going to be
215  * too bad.
216  */
217 static void resample_prepare_input(const struct resampler *rs,
218                                    const uint8_t *bytes,
219                                    size_t nframes,
220                                    float *floats) {
221   while(nframes > 0) {
222     int n;
223
224     for(n = 0; n < rs->input_channels && n < rs->output_channels; ++n) {
225       bytes += resample_get_sample(rs, bytes, floats);
226       ++floats;
227     }
228     if(n < rs->input_channels) {
229       /* More input channels; discard them */
230       bytes += (rs->input_channels - n) * rs->input_bytes_per_sample;
231     } else if(n < rs->output_channels) {
232       /* More output channels; duplicate the last input channel */
233       for(; n < rs->output_channels; ++n) {
234         *floats = floats[-1];
235         ++floats;
236       }
237     }
238     --nframes;
239   }
240 }
241
242 /** @brief Convert between sample formats
243  * @param rs Resampler state
244  * @param bytes Bytes to convert
245  * @param nbytes Number of bytes to convert
246  * @param eof Set an end of input stream
247  * @param converted Called with converted data (possibly more than once)
248  * @param cd Passed to @p cd
249  * @return Number of bytes consumed
250  */
251 size_t resample_convert(const struct resampler *rs,
252                         const uint8_t *bytes,
253                         size_t nbytes,
254                         int eof,
255                         void (*converted)(uint8_t *bytes,
256                                           size_t nbytes,
257                                           void *cd),
258                         void *cd) {
259   size_t nframesin = nbytes / (rs->input_bytes_per_frame);
260   size_t nsamplesout;
261   float *input = xcalloc(nframesin * rs->output_channels, sizeof (float));
262   float *output = 0;
263
264   resample_prepare_input(rs, bytes, nframesin, input);
265 #if HAVE_SAMPLERATE_H
266   if(rs->state) {
267     /* A sample-rate conversion must be performed */
268     SRC_DATA data;
269     memset(&data, 0, sizeof data);
270     /* Compute how many frames are expected to come out. */
271     size_t maxframesout = nframesin * rs->output_rate / rs->input_rate + 1;
272     output = xcalloc(maxframesout * rs->output_channels, sizeof(float));
273     data.data_in = input;
274     data.data_out = output;
275     data.input_frames = nframesin;
276     data.output_frames = maxframesout;
277     data.end_of_input = eof;
278     data.src_ratio = (double)rs->output_rate / rs->input_rate;
279     D(("nframesin=%zu maxframesout=%zu eof=%d ratio=%d.%06d",
280        nframesin, maxframesout, eof,
281        (int)data.src_ratio,
282        ((int)(data.src_ratio * 1000000) % 1000000)));
283     int error_ = src_process(rs->state, &data);
284     if(error_)
285       disorder_fatal(0, "calling src_process: %s", src_strerror(error_));
286     nframesin = data.input_frames_used;
287     nsamplesout = data.output_frames_gen * rs->output_channels;
288     D(("new nframesin=%zu nsamplesout=%zu", nframesin, nsamplesout));
289   }
290 #endif
291   if(!output) {
292     /* No sample-rate conversion required */
293     output = input;
294     nsamplesout = nframesin * rs->output_channels;
295   }
296   const float *op = output;
297   while(nsamplesout > 0) {
298     uint8_t buffer[4096];
299     size_t bufused = 0;
300
301     while(bufused < sizeof buffer && nsamplesout > 0) {
302       bufused += resample_put_sample(rs, *op++, buffer + bufused);
303       --nsamplesout;
304     }
305     converted(buffer, bufused, cd);
306   }
307   if(output != input)
308     xfree(output);
309   xfree(input);
310   eof = 0;             /* quieten compiler */
311   /* Report how many input bytes were actually consumed */
312   //fprintf(stderr, "converted %zu frames\n", nframesin);
313   return nframesin * rs->input_bytes_per_frame;
314 }
315
316 /*
317 Local Variables:
318 c-basic-offset:2
319 comment-column:40
320 fill-column:79
321 indent-tabs-mode:nil
322 End:
323 */