1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Digital Sound Processing
4  *
5  * Copyright 2010-2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include <winpr/crt.h>
30 
31 #include <freerdp/types.h>
32 #include <freerdp/log.h>
33 #include <freerdp/codec/dsp.h>
34 
35 #if !defined(WITH_DSP_FFMPEG)
36 #if defined(WITH_GSM)
37 #include <gsm.h>
38 #endif
39 
40 #if defined(WITH_LAME)
41 #include <lame/lame.h>
42 #endif
43 
44 #if defined(WITH_FAAD2)
45 #include <neaacdec.h>
46 #endif
47 
48 #if defined(WITH_FAAC)
49 #include <faac.h>
50 #endif
51 
52 #if defined(WITH_SOXR)
53 #include <soxr.h>
54 #endif
55 
56 #else
57 #include "dsp_ffmpeg.h"
58 #endif
59 
60 #define TAG FREERDP_TAG("dsp")
61 
62 #if !defined(WITH_DSP_FFMPEG)
63 
64 union _ADPCM {
65 	struct
66 	{
67 		INT16 last_sample[2];
68 		INT16 last_step[2];
69 	} ima;
70 	struct
71 	{
72 		BYTE predictor[2];
73 		INT32 delta[2];
74 		INT32 sample1[2];
75 		INT32 sample2[2];
76 	} ms;
77 };
78 typedef union _ADPCM ADPCM;
79 
80 struct _FREERDP_DSP_CONTEXT
81 {
82 	BOOL encoder;
83 
84 	ADPCM adpcm;
85 	AUDIO_FORMAT format;
86 
87 	wStream* buffer;
88 	wStream* resample;
89 
90 #if defined(WITH_GSM)
91 	gsm gsm;
92 #endif
93 #if defined(WITH_LAME)
94 	lame_t lame;
95 	hip_t hip;
96 #endif
97 #if defined(WITH_FAAD2)
98 	NeAACDecHandle faad;
99 	BOOL faadSetup;
100 #endif
101 
102 #if defined(WITH_FAAC)
103 	faacEncHandle faac;
104 	unsigned long faacInputSamples;
105 	unsigned long faacMaxOutputBytes;
106 #endif
107 
108 #if defined(WITH_SOXR)
109 	soxr_t sox;
110 #endif
111 };
112 
read_int16(const BYTE * src)113 static INT16 read_int16(const BYTE* src)
114 {
115 	return (INT16)(src[0] | (src[1] << 8));
116 }
117 
write_int16(BYTE * dst,INT32 val)118 static void write_int16(BYTE* dst, INT32 val)
119 {
120 	dst[1] = (val >> 8) & 0xFF;
121 	dst[0] = val & 0xFF;
122 }
123 
freerdp_dsp_channel_mix(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,const AUDIO_FORMAT * srcFormat,const BYTE ** data,size_t * length)124 static BOOL freerdp_dsp_channel_mix(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
125                                     const AUDIO_FORMAT* srcFormat, const BYTE** data,
126                                     size_t* length)
127 {
128 	UINT32 bpp;
129 	size_t samples;
130 	size_t x, y;
131 
132 	if (!context || !data || !length)
133 		return FALSE;
134 
135 	if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
136 		return FALSE;
137 
138 	bpp = srcFormat->wBitsPerSample > 8 ? 2 : 1;
139 	samples = size / bpp;
140 
141 	if (context->format.nChannels == srcFormat->nChannels)
142 	{
143 		*data = src;
144 		*length = size;
145 		return TRUE;
146 	}
147 
148 	Stream_SetPosition(context->buffer, 0);
149 
150 	/* Destination has more channels than source */
151 	if (context->format.nChannels > srcFormat->nChannels)
152 	{
153 		switch (srcFormat->nChannels)
154 		{
155 			case 1:
156 				if (!Stream_EnsureCapacity(context->buffer, size * 2))
157 					return FALSE;
158 
159 				for (x = 0; x < samples; x++)
160 				{
161 					for (y = 0; y < bpp; y++)
162 						Stream_Write_UINT8(context->buffer, src[x * bpp + y]);
163 
164 					for (y = 0; y < bpp; y++)
165 						Stream_Write_UINT8(context->buffer, src[x * bpp + y]);
166 				}
167 
168 				Stream_SealLength(context->buffer);
169 				*data = Stream_Buffer(context->buffer);
170 				*length = Stream_Length(context->buffer);
171 				return TRUE;
172 
173 			case 2:  /* We only support stereo, so we can not handle this case. */
174 			default: /* Unsupported number of channels */
175 				return FALSE;
176 		}
177 	}
178 
179 	/* Destination has less channels than source */
180 	switch (srcFormat->nChannels)
181 	{
182 		case 2:
183 			if (!Stream_EnsureCapacity(context->buffer, size / 2))
184 				return FALSE;
185 
186 			/* Simply drop second channel.
187 			 * TODO: Calculate average */
188 			for (x = 0; x < samples; x++)
189 			{
190 				for (y = 0; y < bpp; y++)
191 					Stream_Write_UINT8(context->buffer, src[2 * x * bpp + y]);
192 			}
193 
194 			Stream_SealLength(context->buffer);
195 			*data = Stream_Buffer(context->buffer);
196 			*length = Stream_Length(context->buffer);
197 			return TRUE;
198 
199 		case 1:  /* Invalid, do we want to use a 0 channel sound? */
200 		default: /* Unsupported number of channels */
201 			return FALSE;
202 	}
203 
204 	return FALSE;
205 }
206 
207 /**
208  * Microsoft Multimedia Standards Update
209  * http://download.microsoft.com/download/9/8/6/9863C72A-A3AA-4DDB-B1BA-CA8D17EFD2D4/RIFFNEW.pdf
210  */
211 
freerdp_dsp_resample(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,const AUDIO_FORMAT * srcFormat,const BYTE ** data,size_t * length)212 static BOOL freerdp_dsp_resample(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
213                                  const AUDIO_FORMAT* srcFormat, const BYTE** data, size_t* length)
214 {
215 #if defined(WITH_SOXR)
216 	soxr_error_t error;
217 	size_t idone, odone;
218 	size_t sframes, rframes;
219 	size_t rsize;
220 	size_t j;
221 	size_t sbytes, rbytes;
222 #endif
223 	size_t srcBytesPerFrame, dstBytesPerFrame;
224 	size_t srcChannels, dstChannels;
225 	AUDIO_FORMAT format;
226 
227 	if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
228 	{
229 		WLog_ERR(TAG, "%s requires %s for sample input, got %s", __FUNCTION__,
230 		         audio_format_get_tag_string(WAVE_FORMAT_PCM),
231 		         audio_format_get_tag_string(srcFormat->wFormatTag));
232 		return FALSE;
233 	}
234 
235 	srcChannels = srcFormat->nChannels;
236 	dstChannels = context->format.nChannels;
237 	srcBytesPerFrame = (srcFormat->wBitsPerSample > 8) ? 2 : 1;
238 	dstBytesPerFrame = (context->format.wBitsPerSample > 8) ? 2 : 1;
239 	/* We want to ignore differences of source and destination format. */
240 	format = *srcFormat;
241 	format.wFormatTag = WAVE_FORMAT_UNKNOWN;
242 
243 	if (audio_format_compatible(&format, &context->format))
244 		return TRUE;
245 
246 #if defined(WITH_SOXR)
247 	sbytes = srcChannels * srcBytesPerFrame;
248 	sframes = size / sbytes;
249 	rbytes = dstBytesPerFrame * dstChannels;
250 	/* Integer rounding correct division */
251 	rframes = (sframes * context->format.nSamplesPerSec + (srcFormat->nSamplesPerSec + 1) / 2) /
252 	          srcFormat->nSamplesPerSec;
253 	rsize = rframes * rbytes;
254 
255 	if (!Stream_EnsureCapacity(context->resample, rsize))
256 		return FALSE;
257 
258 	error = soxr_process(context->sox, src, sframes, &idone, Stream_Buffer(context->resample),
259 	                     Stream_Capacity(context->resample) / rbytes, &odone);
260 	Stream_SetLength(context->resample, odone * rbytes);
261 	*data = Stream_Buffer(context->resample);
262 	*length = Stream_Length(context->resample);
263 	return (error == 0) ? TRUE : FALSE;
264 #else
265 	WINPR_UNUSED(src);
266 	WINPR_UNUSED(size);
267 	WINPR_UNUSED(data);
268 	WINPR_UNUSED(length);
269 	WLog_ERR(TAG, "Missing resample support, recompile -DWITH_SOXR=ON or -DWITH_DSP_FFMPEG=ON");
270 	return FALSE;
271 #endif
272 }
273 
274 /**
275  * Microsoft IMA ADPCM specification:
276  *
277  * http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM
278  * http://wiki.multimedia.cx/index.php?title=IMA_ADPCM
279  */
280 
281 static const INT16 ima_step_index_table[] = {
282 	-1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8
283 };
284 
285 static const INT16 ima_step_size_table[] = {
286 	7,     8,     9,     10,    11,    12,    13,    14,    16,    17,    19,   21,    23,
287 	25,    28,    31,    34,    37,    41,    45,    50,    55,    60,    66,   73,    80,
288 	88,    97,    107,   118,   130,   143,   157,   173,   190,   209,   230,  253,   279,
289 	307,   337,   371,   408,   449,   494,   544,   598,   658,   724,   796,  876,   963,
290 	1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066,  2272,  2499,  2749, 3024,  3327,
291 	3660,  4026,  4428,  4871,  5358,  5894,  6484,  7132,  7845,  8630,  9493, 10442, 11487,
292 	12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
293 };
294 
dsp_decode_ima_adpcm_sample(ADPCM * adpcm,unsigned int channel,BYTE sample)295 static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm, unsigned int channel, BYTE sample)
296 {
297 	INT32 ss;
298 	INT32 d;
299 	ss = ima_step_size_table[adpcm->ima.last_step[channel]];
300 	d = (ss >> 3);
301 
302 	if (sample & 1)
303 		d += (ss >> 2);
304 
305 	if (sample & 2)
306 		d += (ss >> 1);
307 
308 	if (sample & 4)
309 		d += ss;
310 
311 	if (sample & 8)
312 		d = -d;
313 
314 	d += adpcm->ima.last_sample[channel];
315 
316 	if (d < -32768)
317 		d = -32768;
318 	else if (d > 32767)
319 		d = 32767;
320 
321 	adpcm->ima.last_sample[channel] = (INT16)d;
322 	adpcm->ima.last_step[channel] += ima_step_index_table[sample];
323 
324 	if (adpcm->ima.last_step[channel] < 0)
325 		adpcm->ima.last_step[channel] = 0;
326 	else if (adpcm->ima.last_step[channel] > 88)
327 		adpcm->ima.last_step[channel] = 88;
328 
329 	return (UINT16)d;
330 }
331 
freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)332 static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
333                                          wStream* out)
334 {
335 	BYTE* dst;
336 	BYTE sample;
337 	UINT16 decoded;
338 	size_t out_size = size * 4;
339 	UINT32 channel;
340 	const UINT32 block_size = context->format.nBlockAlign;
341 	const UINT32 channels = context->format.nChannels;
342 	size_t i;
343 
344 	if (!Stream_EnsureCapacity(out, out_size))
345 		return FALSE;
346 
347 	dst = Stream_Pointer(out);
348 
349 	while (size > 0)
350 	{
351 		if (size % block_size == 0)
352 		{
353 			context->adpcm.ima.last_sample[0] =
354 			    (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
355 			context->adpcm.ima.last_step[0] = (INT16)(*(src + 2));
356 			src += 4;
357 			size -= 4;
358 			out_size -= 16;
359 
360 			if (channels > 1)
361 			{
362 				context->adpcm.ima.last_sample[1] =
363 				    (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
364 				context->adpcm.ima.last_step[1] = (INT16)(*(src + 2));
365 				src += 4;
366 				size -= 4;
367 				out_size -= 16;
368 			}
369 		}
370 
371 		if (channels > 1)
372 		{
373 			for (i = 0; i < 8; i++)
374 			{
375 				channel = (i < 4 ? 0 : 1);
376 				sample = ((*src) & 0x0f);
377 				decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
378 				dst[((i & 3) << 3) + (channel << 1)] = (decoded & 0xFF);
379 				dst[((i & 3) << 3) + (channel << 1) + 1] = (decoded >> 8);
380 				sample = ((*src) >> 4);
381 				decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
382 				dst[((i & 3) << 3) + (channel << 1) + 4] = (decoded & 0xFF);
383 				dst[((i & 3) << 3) + (channel << 1) + 5] = (decoded >> 8);
384 				src++;
385 			}
386 
387 			dst += 32;
388 			size -= 8;
389 		}
390 		else
391 		{
392 			sample = ((*src) & 0x0f);
393 			decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
394 			*dst++ = (decoded & 0xFF);
395 			*dst++ = (decoded >> 8);
396 			sample = ((*src) >> 4);
397 			decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
398 			*dst++ = (decoded & 0xFF);
399 			*dst++ = (decoded >> 8);
400 			src++;
401 			size--;
402 		}
403 	}
404 
405 	Stream_SetPointer(out, dst);
406 	return TRUE;
407 }
408 
409 #if defined(WITH_GSM)
freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)410 static BOOL freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
411                                       wStream* out)
412 {
413 	size_t offset = 0;
414 
415 	while (offset < size)
416 	{
417 		int rc;
418 		gsm_signal gsmBlockBuffer[160] = { 0 };
419 		rc = gsm_decode(context->gsm, (gsm_byte*)/* API does not modify */ &src[offset],
420 		                gsmBlockBuffer);
421 
422 		if (rc < 0)
423 			return FALSE;
424 
425 		if ((offset % 65) == 0)
426 			offset += 33;
427 		else
428 			offset += 32;
429 
430 		if (!Stream_EnsureRemainingCapacity(out, sizeof(gsmBlockBuffer)))
431 			return FALSE;
432 
433 		Stream_Write(out, (void*)gsmBlockBuffer, sizeof(gsmBlockBuffer));
434 	}
435 
436 	return TRUE;
437 }
438 
freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)439 static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
440                                       wStream* out)
441 {
442 	size_t offset = 0;
443 
444 	while (offset < size)
445 	{
446 		const gsm_signal* signal = (const gsm_signal*)&src[offset];
447 
448 		if (!Stream_EnsureRemainingCapacity(out, sizeof(gsm_frame)))
449 			return FALSE;
450 
451 		gsm_encode(context->gsm, (gsm_signal*)/* API does not modify */ signal,
452 		           Stream_Pointer(out));
453 
454 		if ((offset % 65) == 0)
455 			Stream_Seek(out, 33);
456 		else
457 			Stream_Seek(out, 32);
458 
459 		offset += 160;
460 	}
461 
462 	return TRUE;
463 }
464 #endif
465 
466 #if defined(WITH_LAME)
freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)467 static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
468                                    wStream* out)
469 {
470 	int rc, x;
471 	short* pcm_l;
472 	short* pcm_r;
473 	size_t buffer_size;
474 
475 	if (!context || !src || !out)
476 		return FALSE;
477 
478 	buffer_size = 2 * context->format.nChannels * context->format.nSamplesPerSec;
479 
480 	if (!Stream_EnsureCapacity(context->buffer, 2 * buffer_size))
481 		return FALSE;
482 
483 	pcm_l = (short*)Stream_Buffer(context->buffer);
484 	pcm_r = (short*)Stream_Buffer(context->buffer) + buffer_size;
485 	rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src, size,
486 	                pcm_l, pcm_r);
487 
488 	if (rc <= 0)
489 		return FALSE;
490 
491 	if (!Stream_EnsureRemainingCapacity(out, (size_t)rc * context->format.nChannels * 2))
492 		return FALSE;
493 
494 	for (x = 0; x < rc; x++)
495 	{
496 		Stream_Write_UINT16(out, (UINT16)pcm_l[x]);
497 		Stream_Write_UINT16(out, (UINT16)pcm_r[x]);
498 	}
499 
500 	return TRUE;
501 }
502 
freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)503 static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
504                                    wStream* out)
505 {
506 	size_t samples_per_channel;
507 	int rc;
508 
509 	if (!context || !src || !out)
510 		return FALSE;
511 
512 	samples_per_channel = size / context->format.nChannels / context->format.wBitsPerSample / 8;
513 
514 	/* Ensure worst case buffer size for mp3 stream taken from LAME header */
515 	if (!Stream_EnsureRemainingCapacity(out, 5 / 4 * samples_per_channel + 7200))
516 		return FALSE;
517 
518 	samples_per_channel = size / 2 /* size of a sample */ / context->format.nChannels;
519 	rc = lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
520 	                                    Stream_Pointer(out), Stream_GetRemainingCapacity(out));
521 
522 	if (rc < 0)
523 		return FALSE;
524 
525 	Stream_Seek(out, (size_t)rc);
526 	return TRUE;
527 }
528 #endif
529 
530 #if defined(WITH_FAAC)
freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)531 static BOOL freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
532                                     wStream* out)
533 {
534 	const int16_t* inSamples = (const int16_t*)src;
535 	int32_t* outSamples;
536 	unsigned int bpp;
537 	size_t nrSamples, x;
538 	int rc;
539 
540 	if (!context || !src || !out)
541 		return FALSE;
542 
543 	bpp = context->format.wBitsPerSample / 8 * context->format.nChannels;
544 	nrSamples = size / bpp;
545 
546 	if (!Stream_EnsureCapacity(context->buffer,
547 	                           nrSamples * sizeof(int32_t) * context->format.nChannels))
548 		return FALSE;
549 
550 	if (!Stream_EnsureRemainingCapacity(out, context->faacMaxOutputBytes))
551 		return FALSE;
552 
553 	outSamples = (int32_t*)Stream_Buffer(context->buffer);
554 
555 	for (x = 0; x < nrSamples * context->format.nChannels; x++)
556 		outSamples[x] = inSamples[x];
557 
558 	rc = faacEncEncode(context->faac, outSamples, nrSamples * context->format.nChannels,
559 	                   Stream_Pointer(out), Stream_GetRemainingCapacity(out));
560 
561 	if (rc < 0)
562 		return FALSE;
563 	else if (rc > 0)
564 		Stream_Seek(out, (size_t)rc);
565 
566 	return TRUE;
567 }
568 #endif
569 
570 #if defined(WITH_FAAD2)
freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)571 static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
572                                     wStream* out)
573 {
574 	NeAACDecFrameInfo info;
575 	void* output;
576 	size_t offset = 0;
577 
578 	if (!context || !src || !out)
579 		return FALSE;
580 
581 	if (!context->faadSetup)
582 	{
583 		unsigned long samplerate;
584 		unsigned char channels;
585 		long err =
586 		    NeAACDecInit(context->faad, /* API is not modifying content */ (unsigned char*)src,
587 		                 size, &samplerate, &channels);
588 
589 		if (err != 0)
590 			return FALSE;
591 
592 		if (channels != context->format.nChannels)
593 			return FALSE;
594 
595 		if (samplerate != context->format.nSamplesPerSec)
596 			return FALSE;
597 
598 		context->faadSetup = TRUE;
599 	}
600 
601 	while (offset < size)
602 	{
603 		size_t outSize;
604 		void* sample_buffer;
605 		outSize = context->format.nSamplesPerSec * context->format.nChannels *
606 		          context->format.wBitsPerSample / 8;
607 
608 		if (!Stream_EnsureRemainingCapacity(out, outSize))
609 			return FALSE;
610 
611 		sample_buffer = Stream_Pointer(out);
612 		output = NeAACDecDecode2(context->faad, &info, (unsigned char*)&src[offset], size - offset,
613 		                         &sample_buffer, Stream_GetRemainingCapacity(out));
614 
615 		if (info.error != 0)
616 			return FALSE;
617 
618 		offset += info.bytesconsumed;
619 
620 		if (info.samples == 0)
621 			continue;
622 
623 		Stream_Seek(out, info.samples * context->format.wBitsPerSample / 8);
624 	}
625 
626 	return TRUE;
627 }
628 
629 #endif
630 
631 /**
632  * 0     1     2     3
633  * 2 0   6 4   10 8  14 12   <left>
634  *
635  * 4     5     6     7
636  * 3 1   7 5   11 9  15 13   <right>
637  */
638 static const struct
639 {
640 	BYTE byte_num;
641 	BYTE byte_shift;
642 } ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
643 	                          { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
644 	                          { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
645 
dsp_encode_ima_adpcm_sample(ADPCM * adpcm,int channel,INT16 sample)646 static BYTE dsp_encode_ima_adpcm_sample(ADPCM* adpcm, int channel, INT16 sample)
647 {
648 	INT32 e;
649 	INT32 d;
650 	INT32 ss;
651 	BYTE enc;
652 	INT32 diff;
653 	ss = ima_step_size_table[adpcm->ima.last_step[channel]];
654 	d = e = sample - adpcm->ima.last_sample[channel];
655 	diff = ss >> 3;
656 	enc = 0;
657 
658 	if (e < 0)
659 	{
660 		enc = 8;
661 		e = -e;
662 	}
663 
664 	if (e >= ss)
665 	{
666 		enc |= 4;
667 		e -= ss;
668 	}
669 
670 	ss >>= 1;
671 
672 	if (e >= ss)
673 	{
674 		enc |= 2;
675 		e -= ss;
676 	}
677 
678 	ss >>= 1;
679 
680 	if (e >= ss)
681 	{
682 		enc |= 1;
683 		e -= ss;
684 	}
685 
686 	if (d < 0)
687 		diff = d + e - diff;
688 	else
689 		diff = d - e + diff;
690 
691 	diff += adpcm->ima.last_sample[channel];
692 
693 	if (diff < -32768)
694 		diff = -32768;
695 	else if (diff > 32767)
696 		diff = 32767;
697 
698 	adpcm->ima.last_sample[channel] = (INT16)diff;
699 	adpcm->ima.last_step[channel] += ima_step_index_table[enc];
700 
701 	if (adpcm->ima.last_step[channel] < 0)
702 		adpcm->ima.last_step[channel] = 0;
703 	else if (adpcm->ima.last_step[channel] > 88)
704 		adpcm->ima.last_step[channel] = 88;
705 
706 	return enc;
707 }
708 
freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)709 static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
710                                          wStream* out)
711 {
712 	int i;
713 	BYTE* dst;
714 	BYTE* start;
715 	INT16 sample;
716 	BYTE encoded;
717 	size_t out_size;
718 	size_t align;
719 	out_size = size / 2;
720 
721 	if (!Stream_EnsureRemainingCapacity(out, size))
722 		return FALSE;
723 
724 	start = dst = Stream_Pointer(out);
725 	align = (context->format.nChannels > 1) ? 32 : 4;
726 
727 	while (size > align)
728 	{
729 		if ((dst - start) % context->format.nBlockAlign == 0)
730 		{
731 			*dst++ = context->adpcm.ima.last_sample[0] & 0xFF;
732 			*dst++ = (context->adpcm.ima.last_sample[0] >> 8) & 0xFF;
733 			*dst++ = (BYTE)context->adpcm.ima.last_step[0];
734 			*dst++ = 0;
735 
736 			if (context->format.nChannels > 1)
737 			{
738 				*dst++ = context->adpcm.ima.last_sample[1] & 0xFF;
739 				*dst++ = (context->adpcm.ima.last_sample[1] >> 8) & 0xFF;
740 				*dst++ = (BYTE)context->adpcm.ima.last_step[1];
741 				*dst++ = 0;
742 			}
743 		}
744 
745 		if (context->format.nChannels > 1)
746 		{
747 			ZeroMemory(dst, 8);
748 
749 			for (i = 0; i < 16; i++)
750 			{
751 				sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
752 				src += 2;
753 				encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
754 				dst[ima_stereo_encode_map[i].byte_num] |= encoded
755 				                                          << ima_stereo_encode_map[i].byte_shift;
756 			}
757 
758 			dst += 8;
759 			size -= 32;
760 		}
761 		else
762 		{
763 			sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
764 			src += 2;
765 			encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
766 			sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
767 			src += 2;
768 			encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
769 			*dst++ = encoded;
770 			size -= 4;
771 		}
772 	}
773 
774 	Stream_SetPointer(out, dst);
775 	return TRUE;
776 }
777 
778 /**
779  * Microsoft ADPCM Specification:
780  *
781  * http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM
782  */
783 
784 static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
785 	                                               768, 614, 512, 409, 307, 230, 230, 230 };
786 
787 static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
788 
789 static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
790 
freerdp_dsp_decode_ms_adpcm_sample(ADPCM * adpcm,BYTE sample,int channel)791 static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* adpcm, BYTE sample, int channel)
792 {
793 	INT8 nibble;
794 	INT32 presample;
795 	nibble = (sample & 0x08 ? (INT8)sample - 16 : (INT8)sample);
796 	presample = ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
797 	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
798 	            256;
799 	presample += nibble * adpcm->ms.delta[channel];
800 
801 	if (presample > 32767)
802 		presample = 32767;
803 	else if (presample < -32768)
804 		presample = -32768;
805 
806 	adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
807 	adpcm->ms.sample1[channel] = presample;
808 	adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[sample] / 256;
809 
810 	if (adpcm->ms.delta[channel] < 16)
811 		adpcm->ms.delta[channel] = 16;
812 
813 	return (INT16)presample;
814 }
815 
freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)816 static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
817                                         wStream* out)
818 {
819 	BYTE* dst;
820 	BYTE sample;
821 	const size_t out_size = size * 4;
822 	const UINT32 channels = context->format.nChannels;
823 	const UINT32 block_size = context->format.nBlockAlign;
824 
825 	if (!Stream_EnsureCapacity(out, out_size))
826 		return FALSE;
827 
828 	dst = Stream_Pointer(out);
829 
830 	while (size > 0)
831 	{
832 		if (size % block_size == 0)
833 		{
834 			if (channels > 1)
835 			{
836 				context->adpcm.ms.predictor[0] = *src++;
837 				context->adpcm.ms.predictor[1] = *src++;
838 				context->adpcm.ms.delta[0] = read_int16(src);
839 				src += 2;
840 				context->adpcm.ms.delta[1] = read_int16(src);
841 				src += 2;
842 				context->adpcm.ms.sample1[0] = read_int16(src);
843 				src += 2;
844 				context->adpcm.ms.sample1[1] = read_int16(src);
845 				src += 2;
846 				context->adpcm.ms.sample2[0] = read_int16(src);
847 				src += 2;
848 				context->adpcm.ms.sample2[1] = read_int16(src);
849 				src += 2;
850 				size -= 14;
851 				write_int16(dst, context->adpcm.ms.sample2[0]);
852 				dst += 2;
853 				write_int16(dst, context->adpcm.ms.sample2[1]);
854 				dst += 2;
855 				write_int16(dst, context->adpcm.ms.sample1[0]);
856 				dst += 2;
857 				write_int16(dst, context->adpcm.ms.sample1[1]);
858 				dst += 2;
859 			}
860 			else
861 			{
862 				context->adpcm.ms.predictor[0] = *src++;
863 				context->adpcm.ms.delta[0] = read_int16(src);
864 				src += 2;
865 				context->adpcm.ms.sample1[0] = read_int16(src);
866 				src += 2;
867 				context->adpcm.ms.sample2[0] = read_int16(src);
868 				src += 2;
869 				size -= 7;
870 				write_int16(dst, context->adpcm.ms.sample2[0]);
871 				dst += 2;
872 				write_int16(dst, context->adpcm.ms.sample1[0]);
873 				dst += 2;
874 			}
875 		}
876 
877 		if (channels > 1)
878 		{
879 			sample = *src++;
880 			size--;
881 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
882 			dst += 2;
883 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
884 			dst += 2;
885 			sample = *src++;
886 			size--;
887 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
888 			dst += 2;
889 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
890 			dst += 2;
891 		}
892 		else
893 		{
894 			sample = *src++;
895 			size--;
896 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
897 			dst += 2;
898 			write_int16(dst, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
899 			dst += 2;
900 		}
901 	}
902 
903 	Stream_SetPointer(out, dst);
904 	return TRUE;
905 }
906 
freerdp_dsp_encode_ms_adpcm_sample(ADPCM * adpcm,INT32 sample,int channel)907 static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* adpcm, INT32 sample, int channel)
908 {
909 	INT32 presample;
910 	INT32 errordelta;
911 	presample = ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
912 	             (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
913 	            256;
914 	errordelta = (sample - presample) / adpcm->ms.delta[channel];
915 
916 	if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
917 		errordelta++;
918 
919 	if (errordelta > 7)
920 		errordelta = 7;
921 	else if (errordelta < -8)
922 		errordelta = -8;
923 
924 	presample += adpcm->ms.delta[channel] * errordelta;
925 
926 	if (presample > 32767)
927 		presample = 32767;
928 	else if (presample < -32768)
929 		presample = -32768;
930 
931 	adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
932 	adpcm->ms.sample1[channel] = presample;
933 	adpcm->ms.delta[channel] =
934 	    adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((BYTE)errordelta) & 0x0F)] / 256;
935 
936 	if (adpcm->ms.delta[channel] < 16)
937 		adpcm->ms.delta[channel] = 16;
938 
939 	return ((BYTE)errordelta) & 0x0F;
940 }
941 
freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT * context,const BYTE * src,size_t size,wStream * out)942 static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* context, const BYTE* src, size_t size,
943                                         wStream* out)
944 {
945 	BYTE* dst;
946 	BYTE* start;
947 	INT32 sample;
948 	size_t out_size;
949 	const size_t step = 8 + ((context->format.nChannels > 1) ? 4 : 0);
950 	out_size = size / 2;
951 
952 	if (!Stream_EnsureRemainingCapacity(out, size))
953 		return FALSE;
954 
955 	start = dst = Stream_Pointer(out);
956 
957 	if (context->adpcm.ms.delta[0] < 16)
958 		context->adpcm.ms.delta[0] = 16;
959 
960 	if (context->adpcm.ms.delta[1] < 16)
961 		context->adpcm.ms.delta[1] = 16;
962 
963 	while (size >= step)
964 	{
965 		if ((dst - start) % context->format.nBlockAlign == 0)
966 		{
967 			if (context->format.nChannels > 1)
968 			{
969 				*dst++ = context->adpcm.ms.predictor[0];
970 				*dst++ = context->adpcm.ms.predictor[1];
971 				*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
972 				*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
973 				*dst++ = (BYTE)(context->adpcm.ms.delta[1] & 0xFF);
974 				*dst++ = (BYTE)((context->adpcm.ms.delta[1] >> 8) & 0xFF);
975 				context->adpcm.ms.sample1[0] = read_int16(src + 4);
976 				context->adpcm.ms.sample1[1] = read_int16(src + 6);
977 				context->adpcm.ms.sample2[0] = read_int16(src + 0);
978 				context->adpcm.ms.sample2[1] = read_int16(src + 2);
979 				write_int16(dst + 0, context->adpcm.ms.sample1[0]);
980 				write_int16(dst + 2, context->adpcm.ms.sample1[1]);
981 				write_int16(dst + 4, context->adpcm.ms.sample2[0]);
982 				write_int16(dst + 6, context->adpcm.ms.sample2[1]);
983 				dst += 8;
984 				src += 8;
985 				size -= 8;
986 			}
987 			else
988 			{
989 				*dst++ = context->adpcm.ms.predictor[0];
990 				*dst++ = (BYTE)(context->adpcm.ms.delta[0] & 0xFF);
991 				*dst++ = (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF);
992 				context->adpcm.ms.sample1[0] = read_int16(src + 2);
993 				context->adpcm.ms.sample2[0] = read_int16(src + 0);
994 				write_int16(dst + 0, context->adpcm.ms.sample1[0]);
995 				write_int16(dst + 2, context->adpcm.ms.sample2[0]);
996 				dst += 4;
997 				src += 4;
998 				size -= 4;
999 			}
1000 		}
1001 
1002 		sample = read_int16(src);
1003 		src += 2;
1004 		*dst = (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF;
1005 		sample = read_int16(src);
1006 		src += 2;
1007 		*dst += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1008 		                                           context->format.nChannels > 1 ? 1 : 0);
1009 		dst++;
1010 		size -= 4;
1011 	}
1012 
1013 	Stream_SetPointer(out, dst);
1014 	return TRUE;
1015 }
1016 
1017 #endif
1018 
freerdp_dsp_context_new(BOOL encoder)1019 FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1020 {
1021 #if defined(WITH_DSP_FFMPEG)
1022 	return freerdp_dsp_ffmpeg_context_new(encoder);
1023 #else
1024 	FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1025 
1026 	if (!context)
1027 		return NULL;
1028 
1029 	context->buffer = Stream_New(NULL, 4096);
1030 
1031 	if (!context->buffer)
1032 		goto fail;
1033 
1034 	context->resample = Stream_New(NULL, 4096);
1035 
1036 	if (!context->resample)
1037 		goto fail;
1038 
1039 	context->encoder = encoder;
1040 #if defined(WITH_GSM)
1041 	context->gsm = gsm_create();
1042 
1043 	if (!context->gsm)
1044 		goto fail;
1045 
1046 	{
1047 		int rc;
1048 		int val = 1;
1049 		rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1050 
1051 		if (rc < 0)
1052 			goto fail;
1053 	}
1054 #endif
1055 #if defined(WITH_LAME)
1056 
1057 	if (encoder)
1058 	{
1059 		context->lame = lame_init();
1060 
1061 		if (!context->lame)
1062 			goto fail;
1063 	}
1064 	else
1065 	{
1066 		context->hip = hip_decode_init();
1067 
1068 		if (!context->hip)
1069 			goto fail;
1070 	}
1071 
1072 #endif
1073 #if defined(WITH_FAAD2)
1074 
1075 	if (!encoder)
1076 	{
1077 		context->faad = NeAACDecOpen();
1078 
1079 		if (!context->faad)
1080 			goto fail;
1081 	}
1082 
1083 #endif
1084 	return context;
1085 fail:
1086 	freerdp_dsp_context_free(context);
1087 	return NULL;
1088 #endif
1089 }
1090 
freerdp_dsp_context_free(FREERDP_DSP_CONTEXT * context)1091 void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1092 {
1093 #if defined(WITH_DSP_FFMPEG)
1094 	freerdp_dsp_ffmpeg_context_free(context);
1095 #else
1096 
1097 	if (context)
1098 	{
1099 		Stream_Free(context->buffer, TRUE);
1100 		Stream_Free(context->resample, TRUE);
1101 #if defined(WITH_GSM)
1102 		gsm_destroy(context->gsm);
1103 #endif
1104 #if defined(WITH_LAME)
1105 
1106 		if (context->encoder)
1107 			lame_close(context->lame);
1108 		else
1109 			hip_decode_exit(context->hip);
1110 
1111 #endif
1112 #if defined(WITH_FAAD2)
1113 
1114 		if (!context->encoder)
1115 			NeAACDecClose(context->faad);
1116 
1117 #endif
1118 #if defined(WITH_FAAC)
1119 
1120 		if (context->faac)
1121 			faacEncClose(context->faac);
1122 
1123 #endif
1124 #if defined(WITH_SOXR)
1125 		soxr_delete(context->sox);
1126 #endif
1127 		free(context);
1128 	}
1129 
1130 #endif
1131 }
1132 
freerdp_dsp_encode(FREERDP_DSP_CONTEXT * context,const AUDIO_FORMAT * srcFormat,const BYTE * data,size_t length,wStream * out)1133 BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
1134                         const BYTE* data, size_t length, wStream* out)
1135 {
1136 #if defined(WITH_DSP_FFMPEG)
1137 	return freerdp_dsp_ffmpeg_encode(context, srcFormat, data, length, out);
1138 #else
1139 	const BYTE* resampleData;
1140 	size_t resampleLength;
1141 	AUDIO_FORMAT format;
1142 
1143 	if (!context || !context->encoder || !srcFormat || !data || !out)
1144 		return FALSE;
1145 
1146 	format = *srcFormat;
1147 
1148 	if (!freerdp_dsp_channel_mix(context, data, length, srcFormat, &resampleData, &resampleLength))
1149 		return FALSE;
1150 
1151 	format.nChannels = context->format.nChannels;
1152 
1153 	if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1154 		return FALSE;
1155 
1156 	switch (context->format.wFormatTag)
1157 	{
1158 		case WAVE_FORMAT_PCM:
1159 			if (!Stream_EnsureRemainingCapacity(out, length))
1160 				return FALSE;
1161 
1162 			Stream_Write(out, data, length);
1163 			return TRUE;
1164 
1165 		case WAVE_FORMAT_ADPCM:
1166 			return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1167 
1168 		case WAVE_FORMAT_DVI_ADPCM:
1169 			return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1170 #if defined(WITH_GSM)
1171 
1172 		case WAVE_FORMAT_GSM610:
1173 			return freerdp_dsp_encode_gsm610(context, data, length, out);
1174 #endif
1175 #if defined(WITH_LAME)
1176 
1177 		case WAVE_FORMAT_MPEGLAYER3:
1178 			return freerdp_dsp_encode_mp3(context, data, length, out);
1179 #endif
1180 #if defined(WITH_FAAC)
1181 
1182 		case WAVE_FORMAT_AAC_MS:
1183 			return freerdp_dsp_encode_faac(context, data, length, out);
1184 #endif
1185 
1186 		default:
1187 			return FALSE;
1188 	}
1189 
1190 	return FALSE;
1191 #endif
1192 }
1193 
freerdp_dsp_decode(FREERDP_DSP_CONTEXT * context,const AUDIO_FORMAT * srcFormat,const BYTE * data,size_t length,wStream * out)1194 BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
1195                         const BYTE* data, size_t length, wStream* out)
1196 {
1197 #if defined(WITH_DSP_FFMPEG)
1198 	return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1199 #else
1200 
1201 	if (!context || context->encoder || !srcFormat || !data || !out)
1202 		return FALSE;
1203 
1204 	switch (context->format.wFormatTag)
1205 	{
1206 		case WAVE_FORMAT_PCM:
1207 			if (!Stream_EnsureRemainingCapacity(out, length))
1208 				return FALSE;
1209 
1210 			Stream_Write(out, data, length);
1211 			return TRUE;
1212 
1213 		case WAVE_FORMAT_ADPCM:
1214 			return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1215 
1216 		case WAVE_FORMAT_DVI_ADPCM:
1217 			return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1218 #if defined(WITH_GSM)
1219 
1220 		case WAVE_FORMAT_GSM610:
1221 			return freerdp_dsp_decode_gsm610(context, data, length, out);
1222 #endif
1223 #if defined(WITH_LAME)
1224 
1225 		case WAVE_FORMAT_MPEGLAYER3:
1226 			return freerdp_dsp_decode_mp3(context, data, length, out);
1227 #endif
1228 #if defined(WITH_FAAD2)
1229 
1230 		case WAVE_FORMAT_AAC_MS:
1231 			return freerdp_dsp_decode_faad(context, data, length, out);
1232 #endif
1233 
1234 		default:
1235 			return FALSE;
1236 	}
1237 
1238 	return FALSE;
1239 #endif
1240 }
1241 
freerdp_dsp_supports_format(const AUDIO_FORMAT * format,BOOL encode)1242 BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* format, BOOL encode)
1243 {
1244 #if defined(WITH_DSP_FFMPEG)
1245 	return freerdp_dsp_ffmpeg_supports_format(format, encode);
1246 #else
1247 
1248 #if !defined(WITH_DSP_EXPERIMENTAL)
1249 	WINPR_UNUSED(encode);
1250 #endif
1251 	switch (format->wFormatTag)
1252 	{
1253 		case WAVE_FORMAT_PCM:
1254 			return TRUE;
1255 #if defined(WITH_DSP_EXPERIMENTAL)
1256 
1257 		case WAVE_FORMAT_ADPCM:
1258 		case WAVE_FORMAT_DVI_ADPCM:
1259 			return TRUE;
1260 #endif
1261 #if defined(WITH_GSM)
1262 
1263 		case WAVE_FORMAT_GSM610:
1264 #if defined(WITH_DSP_EXPERIMENTAL)
1265 			return TRUE;
1266 #else
1267 			return !encode;
1268 #endif
1269 #endif
1270 #if defined(WITH_LAME)
1271 
1272 		case WAVE_FORMAT_MPEGLAYER3:
1273 #if defined(WITH_DSP_EXPERIMENTAL)
1274 			return TRUE;
1275 #else
1276 			return !encode;
1277 #endif
1278 #endif
1279 
1280 		case WAVE_FORMAT_AAC_MS:
1281 #if defined(WITH_FAAD2)
1282 			if (!encode)
1283 				return TRUE;
1284 
1285 #endif
1286 #if defined(WITH_FAAC) && defined(WITH_DSP_EXPERIMENTAL)
1287 
1288 			if (encode)
1289 				return TRUE;
1290 
1291 #endif
1292 
1293 		default:
1294 			return FALSE;
1295 	}
1296 
1297 	return FALSE;
1298 #endif
1299 }
1300 
freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT * context,const AUDIO_FORMAT * targetFormat)1301 BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT* targetFormat)
1302 {
1303 #if defined(WITH_DSP_FFMPEG)
1304 	return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1305 #else
1306 
1307 	if (!context || !targetFormat)
1308 		return FALSE;
1309 
1310 	context->format = *targetFormat;
1311 #if defined(WITH_FAAD2)
1312 	context->faadSetup = FALSE;
1313 #endif
1314 #if defined(WITH_FAAC)
1315 
1316 	if (context->encoder)
1317 	{
1318 		faacEncConfigurationPtr cfg;
1319 
1320 		if (context->faac)
1321 			faacEncClose(context->faac);
1322 
1323 		context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1324 		                            &context->faacInputSamples, &context->faacMaxOutputBytes);
1325 
1326 		if (!context->faac)
1327 			return FALSE;
1328 
1329 		cfg = faacEncGetCurrentConfiguration(context->faac);
1330 		cfg->bitRate = 10000;
1331 		faacEncSetConfiguration(context->faac, cfg);
1332 	}
1333 
1334 #endif
1335 #if defined(WITH_SOXR)
1336 	{
1337 		soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1338 		soxr_error_t error;
1339 		soxr_delete(context->sox);
1340 		context->sox = soxr_create(context->format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1341 		                           targetFormat->nChannels, &error, &iospec, NULL, NULL);
1342 
1343 		if (!context->sox || (error != 0))
1344 			return FALSE;
1345 	}
1346 #endif
1347 	return TRUE;
1348 #endif
1349 }
1350