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