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