1 /*
2 * MOC - music on console
3 * Copyright (C) 2005 Damian Pietras <daper@daper.net>
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 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Code for conversion between float and fixed point types is based on
11 * libsamplerate:
12 * Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
13 */
14
15 /* For future: audio conversion should be performed in order:
16 * channels -> rate -> format
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 /* for lrintf() */
24 #define _ISOC9X_SOURCE 1
25 #define _ISOC99_SOURCE 1
26 #define __USE_ISOC9X 1
27 #define __USE_ISOC99 1
28
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include <string.h>
33 #include <strings.h>
34
35 #ifdef HAVE_SAMPLERATE
36 # include <samplerate.h>
37 #endif
38
39 #define DEBUG
40
41 #include "common.h"
42 #include "audio_conversion.h"
43 #include "log.h"
44 #include "options.h"
45 #include "compat.h"
46
float_to_u8(const float * in,unsigned char * out,const size_t samples)47 static void float_to_u8 (const float *in, unsigned char *out,
48 const size_t samples)
49 {
50 size_t i;
51
52 assert (in != NULL);
53 assert (out != NULL);
54
55 for (i = 0; i < samples; i++) {
56 float f = in[i] * INT32_MAX;
57
58 if (f >= INT32_MAX)
59 out[i] = UINT8_MAX;
60 else if (f <= INT32_MIN)
61 out[i] = 0;
62 else {
63 #ifdef HAVE_LRINTF
64 out[i] = (unsigned int)((lrintf(f) >> 24) - INT8_MIN);
65 #else
66 out[i] = (unsigned int)(((int)f >> 24) - INT8_MIN);
67 #endif
68 }
69 }
70 }
71
float_to_s8(const float * in,char * out,const size_t samples)72 static void float_to_s8 (const float *in, char *out, const size_t samples)
73 {
74 size_t i;
75
76 assert (in != NULL);
77 assert (out != NULL);
78
79 for (i = 0; i < samples; i++) {
80 float f = in[i] * INT32_MAX;
81
82 if (f >= INT32_MAX)
83 out[i] = INT8_MAX;
84 else if (f <= INT32_MIN)
85 out[i] = INT8_MIN;
86 else {
87 #ifdef HAVE_LRINTF
88 out[i] = lrintf(f) >> 24;
89 #else
90 out[i] = (int)f >> 24;
91 #endif
92 }
93 }
94 }
95
float_to_u16(const float * in,unsigned char * out,const size_t samples)96 static void float_to_u16 (const float *in, unsigned char *out,
97 const size_t samples)
98 {
99 size_t i;
100
101 assert (in != NULL);
102 assert (out != NULL);
103
104 for (i = 0; i < samples; i++) {
105 uint16_t *out_val = (uint16_t *)(out + i * sizeof (uint16_t));
106 float f = in[i] * INT32_MAX;
107
108 if (f >= INT32_MAX)
109 *out_val = UINT16_MAX;
110 else if (f <= INT32_MIN)
111 *out_val = 0;
112 else {
113 #ifdef HAVE_LRINTF
114 *out_val = (unsigned int)((lrintf(f) >> 16) - INT16_MIN);
115 #else
116 *out_val = (unsigned int)(((int)f >> 16) - INT16_MIN);
117 #endif
118 }
119 }
120 }
121
float_to_s16(const float * in,char * out,const size_t samples)122 static void float_to_s16 (const float *in, char *out, const size_t samples)
123 {
124 size_t i;
125
126 assert (in != NULL);
127 assert (out != NULL);
128
129 for (i = 0; i < samples; i++) {
130 int16_t *out_val = (int16_t *)(out + i * sizeof (int16_t));
131 float f = in[i] * INT32_MAX;
132
133 if (f >= INT32_MAX)
134 *out_val = INT16_MAX;
135 else if (f <= INT32_MIN)
136 *out_val = INT16_MIN;
137 else {
138 #ifdef HAVE_LRINTF
139 *out_val = lrintf(f) >> 16;
140 #else
141 *out_val = ((int)f >> 16);
142 #endif
143 }
144 }
145 }
146
float_to_u32(const float * in,unsigned char * out,const size_t samples)147 static void float_to_u32 (const float *in, unsigned char *out,
148 const size_t samples)
149 {
150 size_t i;
151
152 /* maximum and minimum values of 32-bit samples */
153 const unsigned int U32_MAX = (1 << 24) - 1;
154 const int S32_MAX = (1 << 23) - 1;
155 const int S32_MIN = -(1 << 23);
156
157 assert (in != NULL);
158 assert (out != NULL);
159
160 for (i = 0; i < samples; i++) {
161 uint32_t *out_val = (uint32_t *)(out + i * sizeof (uint32_t));
162 float f = in[i] * S32_MAX;
163
164 if (f >= S32_MAX)
165 *out_val = U32_MAX << 8;
166 else if (f <= S32_MIN)
167 *out_val = 0;
168 else {
169 #ifdef HAVE_LRINTF
170 *out_val = (uint32_t)(lrintf(f) - S32_MIN) << 8;
171 #else
172 *out_val = (uint32_t)((int32_t)f - S32_MIN) << 8;
173 #endif
174 }
175 }
176 }
177
float_to_s32(const float * in,char * out,const size_t samples)178 static void float_to_s32 (const float *in, char *out, const size_t samples)
179 {
180 size_t i;
181
182 /* maximum and minimum values of 32-bit samples */
183 const int S32_MAX = (1 << 23) - 1;
184 const int S32_MIN = -(1 << 23);
185
186 assert (in != NULL);
187 assert (out != NULL);
188
189 for (i = 0; i < samples; i++) {
190 int32_t *out_val = (int32_t *)(out + i * sizeof (int32_t));
191 float f = in[i] * S32_MAX;
192
193 if (f >= S32_MAX)
194 *out_val = S32_MAX << 8;
195 else if (f <= S32_MIN)
196 *out_val = S32_MIN << 8;
197 else {
198 #ifdef HAVE_LRINTF
199 *out_val = lrintf(f) << 8;
200 #else
201 *out_val = (int32_t)f << 8;
202 #endif
203 }
204 }
205 }
206
u8_to_float(const unsigned char * in,float * out,const size_t samples)207 static void u8_to_float (const unsigned char *in, float *out,
208 const size_t samples)
209 {
210 size_t i;
211
212 assert (in != NULL);
213 assert (out != NULL);
214
215 for (i = 0; i < samples; i++)
216 out[i] = (((int)*in++) + INT8_MIN) / (float)(INT8_MAX + 1);
217 }
218
s8_to_float(const char * in,float * out,const size_t samples)219 static void s8_to_float (const char *in, float *out, const size_t samples)
220 {
221 size_t i;
222
223 assert (in != NULL);
224 assert (out != NULL);
225
226 for (i = 0; i < samples; i++)
227 out[i] = *in++ / (float)(INT8_MAX + 1);
228 }
229
u16_to_float(const unsigned char * in,float * out,const size_t samples)230 static void u16_to_float (const unsigned char *in, float *out,
231 const size_t samples)
232 {
233 size_t i;
234 const uint16_t *in_16 = (uint16_t *)in;
235
236 assert (in != NULL);
237 assert (out != NULL);
238
239 for (i = 0; i < samples; i++)
240 out[i] = ((int)*in_16++ + INT16_MIN) / (float)(INT16_MAX + 1);
241 }
242
s16_to_float(const char * in,float * out,const size_t samples)243 static void s16_to_float (const char *in, float *out, const size_t samples)
244 {
245 size_t i;
246 const int16_t *in_16 = (int16_t *)in;
247
248 assert (in != NULL);
249 assert (out != NULL);
250
251 for (i = 0; i < samples; i++)
252 out[i] = *in_16++ / (float)(INT16_MAX + 1);
253 }
254
u32_to_float(const unsigned char * in,float * out,const size_t samples)255 static void u32_to_float (const unsigned char *in, float *out,
256 const size_t samples)
257 {
258 size_t i;
259 const uint32_t *in_32 = (uint32_t *)in;
260
261 assert (in != NULL);
262 assert (out != NULL);
263
264 for (i = 0; i < samples; i++)
265 out[i] = ((float)*in_32++ + (float)INT32_MIN) / ((float)INT32_MAX + 1.0);
266 }
267
s32_to_float(const char * in,float * out,const size_t samples)268 static void s32_to_float (const char *in, float *out, const size_t samples)
269 {
270 size_t i;
271 const int32_t *in_32 = (int32_t *)in;
272
273 assert (in != NULL);
274 assert (out != NULL);
275
276 for (i = 0; i < samples; i++)
277 out[i] = *in_32++ / ((float)INT32_MAX + 1.0);
278 }
279
280 /* Convert fixed point samples in format fmt (size in bytes) to float.
281 * Size of converted sound is put in new_size. Returned memory is malloc()ed. */
fixed_to_float(const char * buf,const size_t size,const long fmt,size_t * new_size)282 static float *fixed_to_float (const char *buf, const size_t size,
283 const long fmt, size_t *new_size)
284 {
285 float *out = NULL;
286 char fmt_name[SFMT_STR_MAX];
287
288 assert ((fmt & SFMT_MASK_FORMAT) != SFMT_FLOAT);
289
290 switch (fmt & SFMT_MASK_FORMAT) {
291 case SFMT_U8:
292 *new_size = sizeof(float) * size;
293 out = (float *)xmalloc (*new_size);
294 u8_to_float ((unsigned char *)buf, out, size);
295 break;
296 case SFMT_S8:
297 *new_size = sizeof(float) * size;
298 out = (float *)xmalloc (*new_size);
299 s8_to_float (buf, out, size);
300 break;
301 case SFMT_U16:
302 *new_size = sizeof(float) * size / 2;
303 out = (float *)xmalloc (*new_size);
304 u16_to_float ((unsigned char *)buf, out, size / 2);
305 break;
306 case SFMT_S16:
307 *new_size = sizeof(float) * size / 2;
308 out = (float *)xmalloc (*new_size);
309 s16_to_float (buf, out, size / 2);
310 break;
311 case SFMT_U32:
312 *new_size = sizeof(float) * size / 4;
313 out = (float *)xmalloc (*new_size);
314 u32_to_float ((unsigned char *)buf, out, size / 4);
315 break;
316 case SFMT_S32:
317 *new_size = sizeof(float) * size / 4;
318 out = (float *)xmalloc (*new_size);
319 s32_to_float (buf, out, size / 4);
320 break;
321 default:
322 error ("Can't convert from %s to float!",
323 sfmt_str (fmt, fmt_name, sizeof (fmt_name)));
324 abort ();
325 }
326
327 return out;
328 }
329
330 /* Convert float samples to fixed point format fmt. Returned samples of size
331 * new_size bytes is malloc()ed. */
float_to_fixed(const float * buf,const size_t samples,const long fmt,size_t * new_size)332 static char *float_to_fixed (const float *buf, const size_t samples,
333 const long fmt, size_t *new_size)
334 {
335 char fmt_name[SFMT_STR_MAX];
336 char *new_snd = NULL;
337
338 assert ((fmt & SFMT_MASK_FORMAT) != SFMT_FLOAT);
339
340 switch (fmt & SFMT_MASK_FORMAT) {
341 case SFMT_U8:
342 *new_size = samples;
343 new_snd = (char *)xmalloc (samples);
344 float_to_u8 (buf, (unsigned char *)new_snd, samples);
345 break;
346 case SFMT_S8:
347 *new_size = samples;
348 new_snd = (char *)xmalloc (samples);
349 float_to_s8 (buf, new_snd, samples);
350 break;
351 case SFMT_U16:
352 *new_size = samples * 2;
353 new_snd = (char *)xmalloc (*new_size);
354 float_to_u16 (buf, (unsigned char *)new_snd, samples);
355 break;
356 case SFMT_S16:
357 *new_size = samples * 2;
358 new_snd = (char *)xmalloc (*new_size);
359 float_to_s16 (buf, new_snd, samples);
360 break;
361 case SFMT_U32:
362 *new_size = samples * 4;
363 new_snd = (char *)xmalloc (*new_size);
364 float_to_u32 (buf, (unsigned char *)new_snd, samples);
365 break;
366 case SFMT_S32:
367 *new_size = samples * 4;
368 new_snd = (char *)xmalloc (*new_size);
369 float_to_s32 (buf, new_snd, samples);
370 break;
371 default:
372 error ("Can't convert from float to %s!",
373 sfmt_str (fmt, fmt_name, sizeof (fmt_name)));
374 abort ();
375 }
376
377 return new_snd;
378 }
379
change_sign_8(uint8_t * buf,const size_t samples)380 static void change_sign_8 (uint8_t *buf, const size_t samples)
381 {
382 size_t i;
383
384 for (i = 0; i < samples; i++)
385 *buf++ ^= 1 << 7;
386 }
387
change_sign_16(uint16_t * buf,const size_t samples)388 static void change_sign_16 (uint16_t *buf, const size_t samples)
389 {
390 size_t i;
391
392 for (i = 0; i < samples; i++)
393 *buf++ ^= 1 << 15;
394 }
395
change_sign_32(uint32_t * buf,const size_t samples)396 static void change_sign_32 (uint32_t *buf, const size_t samples)
397 {
398 size_t i;
399
400 for (i = 0; i < samples; i++)
401 *buf++ ^= 1 << 31;
402 }
403
404 /* Change the signs of samples in format *fmt. Also changes fmt to the new
405 * format. */
change_sign(char * buf,const size_t size,long * fmt)406 static void change_sign (char *buf, const size_t size, long *fmt)
407 {
408 char fmt_name[SFMT_STR_MAX];
409
410 switch (*fmt & SFMT_MASK_FORMAT) {
411 case SFMT_S8:
412 case SFMT_U8:
413 change_sign_8 ((uint8_t *)buf, size);
414 if (*fmt & SFMT_S8)
415 *fmt = sfmt_set_fmt (*fmt, SFMT_U8);
416 else
417 *fmt = sfmt_set_fmt (*fmt, SFMT_S8);
418 break;
419 case SFMT_S16:
420 case SFMT_U16:
421 change_sign_16 ((uint16_t *)buf, size / 2);
422 if (*fmt & SFMT_S16)
423 *fmt = sfmt_set_fmt (*fmt, SFMT_U16);
424 else
425 *fmt = sfmt_set_fmt (*fmt, SFMT_S16);
426 break;
427 case SFMT_S32:
428 case SFMT_U32:
429 change_sign_32 ((uint32_t *)buf, size/4);
430 if (*fmt & SFMT_S32)
431 *fmt = sfmt_set_fmt (*fmt, SFMT_U32);
432 else
433 *fmt = sfmt_set_fmt (*fmt, SFMT_S32);
434 break;
435 default:
436 error ("Request for changing sign of unknown format: %s",
437 sfmt_str (*fmt, fmt_name, sizeof (fmt_name)));
438 abort ();
439 }
440 }
441
audio_conv_bswap_16(int16_t * buf,const size_t num)442 void audio_conv_bswap_16 (int16_t *buf, const size_t num)
443 {
444 size_t i;
445
446 for (i = 0; i < num; i++)
447 buf[i] = bswap_16 (buf[i]);
448 }
449
audio_conv_bswap_32(int32_t * buf,const size_t num)450 void audio_conv_bswap_32 (int32_t *buf, const size_t num)
451 {
452 size_t i;
453
454 for (i = 0; i < num; i++)
455 buf[i] = bswap_32 (buf[i]);
456 }
457
458 /* Swap endianness of fixed point samples. */
swap_endian(char * buf,const size_t size,const long fmt)459 static void swap_endian (char *buf, const size_t size, const long fmt)
460 {
461 if ((fmt & (SFMT_S8 | SFMT_U8 | SFMT_FLOAT)))
462 return;
463
464 switch (fmt & SFMT_MASK_FORMAT) {
465 case SFMT_S16:
466 case SFMT_U16:
467 audio_conv_bswap_16 ((int16_t *)buf, size / 2);
468 break;
469 case SFMT_S32:
470 case SFMT_U32:
471 audio_conv_bswap_32 ((int32_t *)buf, size / 4);
472 break;
473 default:
474 error ("Can't convert to native endian!");
475 abort (); /* we can't do anything smarter */
476 }
477 }
478
479 /* Initialize the audio_conversion structure for conversion between parameters
480 * from and to. Return 0 on error. */
audio_conv_new(struct audio_conversion * conv,const struct sound_params * from,const struct sound_params * to)481 int audio_conv_new (struct audio_conversion *conv,
482 const struct sound_params *from,
483 const struct sound_params *to)
484 {
485 assert (from->rate != to->rate || from->fmt != to->fmt
486 || from->channels != to->channels);
487
488 if (from->channels != to->channels) {
489
490 /* the only conversion we can do */
491 if (!(from->channels == 1 && to->channels == 2)) {
492 error ("Can't change number of channels (%d to %d)!",
493 from->channels, to->channels);
494 return 0;
495 }
496 }
497
498 if (from->rate != to->rate) {
499 #ifdef HAVE_SAMPLERATE
500 int err;
501 int resample_type = -1;
502 char *method = options_get_str ("ResampleMethod");
503
504 if (!strcasecmp(method, "SincBestQuality"))
505 resample_type = SRC_SINC_BEST_QUALITY;
506 else if (!strcasecmp(method, "SincMediumQuality"))
507 resample_type = SRC_SINC_MEDIUM_QUALITY;
508 else if (!strcasecmp(method, "SincFastest"))
509 resample_type = SRC_SINC_FASTEST;
510 else if (!strcasecmp(method, "ZeroOrderHold"))
511 resample_type = SRC_ZERO_ORDER_HOLD;
512 else if (!strcasecmp(method, "Linear"))
513 resample_type = SRC_LINEAR;
514 else
515 fatal ("Bad ResampleMethod option: %s", method);
516
517 conv->src_state = src_new (resample_type, to->channels, &err);
518 if (!conv->src_state) {
519 error ("Can't resample from %dHz to %dHz: %s",
520 from->rate, to->rate, src_strerror (err));
521 return 0;
522 }
523 #else
524 error ("Resampling not supported!");
525 return 0;
526 #endif
527 }
528 #ifdef HAVE_SAMPLERATE
529 else
530 conv->src_state = NULL;
531 #endif
532
533 conv->from = *from;
534 conv->to = *to;
535
536 #ifdef HAVE_SAMPLERATE
537 conv->resample_buf = NULL;
538 conv->resample_buf_nsamples = 0;
539 #endif
540
541 return 1;
542 }
543
544 #ifdef HAVE_SAMPLERATE
resample_sound(struct audio_conversion * conv,const float * buf,const size_t samples,const int nchannels,size_t * resampled_samples)545 static float *resample_sound (struct audio_conversion *conv, const float *buf,
546 const size_t samples, const int nchannels, size_t *resampled_samples)
547 {
548 SRC_DATA resample_data;
549 float *output;
550 float *new_input_start;
551 int output_samples = 0;
552
553 resample_data.end_of_input = 0;
554 resample_data.src_ratio = conv->to.rate / (double)conv->from.rate;
555
556 resample_data.input_frames = samples / nchannels
557 + conv->resample_buf_nsamples / nchannels;
558 resample_data.output_frames = resample_data.input_frames
559 * resample_data.src_ratio;
560
561 if (conv->resample_buf) {
562 conv->resample_buf = (float *)xrealloc (conv->resample_buf,
563 sizeof(float) * resample_data.input_frames
564 * nchannels);
565 new_input_start = conv->resample_buf
566 + conv->resample_buf_nsamples;
567 }
568 else {
569 conv->resample_buf = (float *)xmalloc (sizeof(float)
570 * resample_data.input_frames
571 * nchannels);
572 new_input_start = conv->resample_buf;
573 }
574
575 output = (float *)xmalloc (sizeof(float) * resample_data.output_frames
576 * nchannels);
577
578 /*debug ("Resampling %lu bytes of data by ratio %f", (unsigned long)size,
579 resample_data.src_ratio);*/
580
581 memcpy (new_input_start, buf, samples * sizeof(float));
582 resample_data.data_in = conv->resample_buf;
583 resample_data.data_out = output;
584
585 do {
586 int err;
587
588 if ((err = src_process(conv->src_state, &resample_data))) {
589 error ("Can't resample: %s", src_strerror (err));
590 free (output);
591 return NULL;
592 }
593
594 resample_data.data_in += resample_data.input_frames_used
595 * nchannels;
596 resample_data.input_frames -= resample_data.input_frames_used;
597 resample_data.data_out += resample_data.output_frames_gen
598 * nchannels;
599 resample_data.output_frames -= resample_data.output_frames_gen;
600 output_samples += resample_data.output_frames_gen * nchannels;
601 } while (resample_data.input_frames && resample_data.output_frames_gen
602 && resample_data.output_frames);
603
604 *resampled_samples = output_samples;
605
606 if (resample_data.input_frames) {
607 conv->resample_buf_nsamples = resample_data.input_frames
608 * nchannels;
609 if (conv->resample_buf != resample_data.data_in) {
610 float *new;
611
612 new = (float *)xmalloc (sizeof(float) *
613 conv->resample_buf_nsamples);
614 memcpy (new, resample_data.data_in, sizeof(float) *
615 conv->resample_buf_nsamples);
616 free (conv->resample_buf);
617 conv->resample_buf = new;
618 }
619 }
620 else {
621 free (conv->resample_buf);
622 conv->resample_buf = NULL;
623 conv->resample_buf_nsamples = 0;
624 }
625
626 return output;
627 }
628 #endif
629
630 /* Double the channels from */
mono_to_stereo(const char * mono,const size_t size,const long format)631 static char *mono_to_stereo (const char *mono, const size_t size,
632 const long format)
633 {
634 int Bps = sfmt_Bps (format);
635 size_t i;
636 char *stereo;
637
638 stereo = (char *)xmalloc (size * 2);
639
640 for (i = 0; i < size; i += Bps) {
641 memcpy (stereo + (i * 2), mono + i, Bps);
642 memcpy (stereo + (i * 2 + Bps), mono + i, Bps);
643 }
644
645 return stereo;
646 }
647
s32_to_s16(int32_t * in,const size_t samples)648 static int16_t *s32_to_s16 (int32_t *in, const size_t samples)
649 {
650 size_t i;
651 int16_t *new;
652
653 new = (int16_t *)xmalloc (samples * 2);
654
655 for (i = 0; i < samples; i++)
656 new[i] = in[i] >> 16;
657
658 return new;
659 }
660
u32_to_u16(uint32_t * in,const size_t samples)661 static uint16_t *u32_to_u16 (uint32_t *in, const size_t samples)
662 {
663 size_t i;
664 uint16_t *new;
665
666 new = (uint16_t *)xmalloc (samples * 2);
667
668 for (i = 0; i < samples; i++)
669 new[i] = in[i] >> 16;
670
671 return new;
672 }
673
674 /* Do the sound conversion. buf of length size is the sample buffer to
675 * convert and the size of the converted sound is put into *conv_len.
676 * Return the converted sound in malloc()ed memory. */
audio_conv(struct audio_conversion * conv,const char * buf,const size_t size,size_t * conv_len)677 char *audio_conv (struct audio_conversion *conv, const char *buf,
678 const size_t size, size_t *conv_len)
679 {
680 char *curr_sound;
681 long curr_sfmt = conv->from.fmt;
682
683 *conv_len = size;
684
685 curr_sound = (char *)xmalloc (size);
686 memcpy (curr_sound, buf, size);
687
688 if (!(curr_sfmt & SFMT_NE)) {
689 swap_endian (curr_sound, *conv_len, curr_sfmt);
690 curr_sfmt = sfmt_set_endian (curr_sfmt, SFMT_NE);
691 }
692
693 /* Special case (optimization): if we only need to convert 32bit samples
694 * to 16bit, we can do it very simply and quickly. */
695 if ((curr_sfmt & (SFMT_S32 | SFMT_U32)) &&
696 (conv->to.fmt & (SFMT_S16 | SFMT_U16)) &&
697 conv->from.rate == conv->to.rate) {
698 char *new_sound;
699
700 if ((curr_sfmt & SFMT_MASK_FORMAT) == SFMT_S32) {
701 new_sound = (char *)s32_to_s16 ((int32_t *)curr_sound,
702 *conv_len / 4);
703 curr_sfmt = sfmt_set_fmt (curr_sfmt, SFMT_S16);
704 }
705 else {
706 new_sound = (char *)u32_to_u16 ((uint32_t *)curr_sound,
707 *conv_len / 4);
708 curr_sfmt = sfmt_set_fmt (curr_sfmt, SFMT_U16);
709 }
710
711 if (curr_sound != buf)
712 free (curr_sound);
713 curr_sound = new_sound;
714 *conv_len /= 2;
715
716 logit ("Fast conversion!");
717 }
718
719 /* convert to float if necessary */
720 if ((conv->from.rate != conv->to.rate
721 || (conv->to.fmt & SFMT_MASK_FORMAT) == SFMT_FLOAT
722 || !sfmt_same_bps(conv->to.fmt, curr_sfmt))
723 && (curr_sfmt & SFMT_MASK_FORMAT) != SFMT_FLOAT) {
724 char *new_sound;
725
726 new_sound = (char *)fixed_to_float (curr_sound, *conv_len,
727 curr_sfmt, conv_len);
728 curr_sfmt = sfmt_set_fmt (curr_sfmt, SFMT_FLOAT);
729
730 if (curr_sound != buf)
731 free (curr_sound);
732 curr_sound = new_sound;
733 }
734
735 #ifdef HAVE_SAMPLERATE
736 if (conv->from.rate != conv->to.rate) {
737 char *new_sound = (char *)resample_sound (conv,
738 (float *)curr_sound,
739 *conv_len / sizeof(float), conv->to.channels,
740 conv_len);
741 *conv_len *= sizeof(float);
742 if (curr_sound != buf)
743 free (curr_sound);
744 curr_sound = new_sound;
745 }
746 #endif
747
748 if ((curr_sfmt & SFMT_MASK_FORMAT)
749 != (conv->to.fmt & SFMT_MASK_FORMAT)) {
750
751 if (sfmt_same_bps(curr_sfmt, conv->to.fmt))
752 change_sign (curr_sound, size, &curr_sfmt);
753 else {
754 char *new_sound;
755
756 assert (curr_sfmt & SFMT_FLOAT);
757
758 new_sound = float_to_fixed ((float *)curr_sound,
759 *conv_len / sizeof(float),
760 conv->to.fmt, conv_len);
761 curr_sfmt = sfmt_set_fmt (curr_sfmt, conv->to.fmt);
762
763 if (curr_sound != buf)
764 free (curr_sound);
765 curr_sound = new_sound;
766 }
767 }
768
769 if ((curr_sfmt & SFMT_MASK_ENDIANNESS)
770 != (conv->to.fmt & SFMT_MASK_ENDIANNESS)) {
771 swap_endian (curr_sound, *conv_len, curr_sfmt);
772 curr_sfmt = sfmt_set_endian (curr_sfmt,
773 conv->to.fmt & SFMT_MASK_ENDIANNESS);
774 }
775
776 if (conv->from.channels == 1 && conv->to.channels == 2) {
777 char *new_sound;
778
779 new_sound = mono_to_stereo (curr_sound, *conv_len, curr_sfmt);
780 *conv_len *= 2;
781
782 if (curr_sound != buf)
783 free (curr_sound);
784 curr_sound = new_sound;
785 }
786
787 return curr_sound;
788 }
789
audio_conv_destroy(struct audio_conversion * conv ATTR_UNUSED)790 void audio_conv_destroy (struct audio_conversion *conv ATTR_UNUSED)
791 {
792 assert (conv != NULL);
793
794 #ifdef HAVE_SAMPLERATE
795 if (conv->resample_buf)
796 free (conv->resample_buf);
797 if (conv->src_state)
798 src_delete (conv->src_state);
799 #endif
800 }
801