FreeRDP
Loading...
Searching...
No Matches
dsp.c
1
20#include <freerdp/config.h>
21
22#include <winpr/assert.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <winpr/crt.h>
28
29#include <freerdp/types.h>
30#include <freerdp/log.h>
31#include <freerdp/codec/dsp.h>
32
33#include "dsp.h"
34
35#if defined(WITH_FDK_AAC)
36#include "dsp_fdk_aac.h"
37#endif
38
39#if !defined(WITH_DSP_FFMPEG)
40#if defined(WITH_GSM)
41#include <gsm/gsm.h>
42#endif
43
44#if defined(WITH_LAME)
45#include <lame/lame.h>
46#endif
47
48#if defined(WITH_OPUS)
49#include <opus/opus.h>
50
51#define OPUS_MAX_FRAMES 5760ull
52#endif
53
54#if defined(WITH_FAAD2)
55#include <neaacdec.h>
56#endif
57
58#if defined(WITH_FAAC)
59#include <faac.h>
60#endif
61
62#if defined(WITH_SOXR)
63#include <soxr.h>
64#endif
65
66#else
67#include "dsp_ffmpeg.h"
68#endif
69
70#if !defined(WITH_DSP_FFMPEG)
71
72#define TAG FREERDP_TAG("dsp")
73
74typedef union
75{
76 struct
77 {
78 size_t packet_size;
79 INT16 last_sample[2];
80 INT16 last_step[2];
81 } ima;
82 struct
83 {
84 BYTE predictor[2];
85 INT32 delta[2];
86 INT32 sample1[2];
87 INT32 sample2[2];
88 } ms;
89} ADPCM;
90
91struct S_FREERDP_DSP_CONTEXT
92{
94
95 ADPCM adpcm;
96
97#if defined(WITH_GSM)
98 gsm gsm;
99#endif
100#if defined(WITH_LAME)
101 lame_t lame;
102 hip_t hip;
103#endif
104#if defined(WITH_OPUS)
105 OpusDecoder* opus_decoder;
106 OpusEncoder* opus_encoder;
107#endif
108#if defined(WITH_FAAD2)
109 NeAACDecHandle faad;
110 BOOL faadSetup;
111#endif
112
113#if defined(WITH_FAAC)
114 faacEncHandle faac;
115 unsigned long faacInputSamples;
116 unsigned long faacMaxOutputBytes;
117#endif
118
119#if defined(WITH_SOXR)
120 soxr_t sox;
121#endif
122};
123
124#if defined(WITH_OPUS)
125static BOOL opus_is_valid_samplerate(const AUDIO_FORMAT* WINPR_RESTRICT format)
126{
127 WINPR_ASSERT(format);
128
129 switch (format->nSamplesPerSec)
130 {
131 case 8000:
132 case 12000:
133 case 16000:
134 case 24000:
135 case 48000:
136 return TRUE;
137 default:
138 return FALSE;
139 }
140}
141#endif
142
143static INT16 read_int16(const BYTE* WINPR_RESTRICT src)
144{
145 return (INT16)(src[0] | (src[1] << 8));
146}
147
148static BOOL freerdp_dsp_channel_mix(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
149 const BYTE* WINPR_RESTRICT src, size_t size,
150 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
151 const BYTE** WINPR_RESTRICT data, size_t* WINPR_RESTRICT length)
152{
153 if (!context || !data || !length)
154 return FALSE;
155
156 if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
157 return FALSE;
158
159 const UINT32 bpp = srcFormat->wBitsPerSample > 8 ? 2 : 1;
160 const size_t samples = size / bpp / srcFormat->nChannels;
161
162 if (context->common.format.nChannels == srcFormat->nChannels)
163 {
164 *data = src;
165 *length = size;
166 return TRUE;
167 }
168
169 Stream_ResetPosition(context->common.channelmix);
170
171 /* Destination has more channels than source */
172 if (context->common.format.nChannels > srcFormat->nChannels)
173 {
174 switch (srcFormat->nChannels)
175 {
176 case 1:
177 if (!Stream_EnsureCapacity(context->common.channelmix, size * 2))
178 return FALSE;
179
180 for (size_t x = 0; x < samples; x++)
181 {
182 for (size_t y = 0; y < bpp; y++)
183 Stream_Write_UINT8(context->common.channelmix, src[x * bpp + y]);
184
185 for (size_t y = 0; y < bpp; y++)
186 Stream_Write_UINT8(context->common.channelmix, src[x * bpp + y]);
187 }
188
189 Stream_SealLength(context->common.channelmix);
190 *data = Stream_Buffer(context->common.channelmix);
191 *length = Stream_Length(context->common.channelmix);
192 return TRUE;
193
194 case 2: /* We only support stereo, so we can not handle this case. */
195 default: /* Unsupported number of channels */
196 return FALSE;
197 }
198 }
199
200 /* Destination has less channels than source */
201 switch (srcFormat->nChannels)
202 {
203 case 2:
204 if (!Stream_EnsureCapacity(context->common.channelmix, size / 2))
205 return FALSE;
206
207 /* Simply drop second channel.
208 * TODO: Calculate average */
209 for (size_t x = 0; x < samples; x++)
210 {
211 for (size_t y = 0; y < bpp; y++)
212 Stream_Write_UINT8(context->common.channelmix, src[2 * x * bpp + y]);
213 }
214
215 Stream_SealLength(context->common.channelmix);
216 *data = Stream_Buffer(context->common.channelmix);
217 *length = Stream_Length(context->common.channelmix);
218 return TRUE;
219
220 case 1: /* Invalid, do we want to use a 0 channel sound? */
221 default: /* Unsupported number of channels */
222 return FALSE;
223 }
224
225 return FALSE;
226}
227
233static BOOL freerdp_dsp_resample(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
234 const BYTE* WINPR_RESTRICT src, size_t size,
235 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
236 const BYTE** WINPR_RESTRICT data, size_t* WINPR_RESTRICT length)
237{
238#if defined(WITH_SOXR)
239 soxr_error_t error;
240 size_t idone, odone;
241 size_t sframes, rframes;
242 size_t rsize;
243 size_t sbytes, rbytes;
244 size_t dstChannels;
245 size_t srcChannels;
246 size_t srcBytesPerFrame, dstBytesPerFrame;
247#endif
248 AUDIO_FORMAT format;
249
250 if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
251 {
252 WLog_ERR(TAG, "requires %s for sample input, got %s",
253 audio_format_get_tag_string(WAVE_FORMAT_PCM),
254 audio_format_get_tag_string(srcFormat->wFormatTag));
255 return FALSE;
256 }
257
258 /* We want to ignore differences of source and destination format. */
259 format = *srcFormat;
260 format.wFormatTag = WAVE_FORMAT_UNKNOWN;
261 format.wBitsPerSample = 0;
262
263 if (audio_format_compatible(&format, &context->common.format))
264 {
265 *data = src;
266 *length = size;
267 return TRUE;
268 }
269
270#if defined(WITH_SOXR)
271 srcBytesPerFrame = (srcFormat->wBitsPerSample > 8) ? 2 : 1;
272 dstBytesPerFrame = (context->common.format.wBitsPerSample > 8) ? 2 : 1;
273 srcChannels = srcFormat->nChannels;
274 dstChannels = context->common.format.nChannels;
275 sbytes = srcChannels * srcBytesPerFrame;
276 sframes = size / sbytes;
277 rbytes = dstBytesPerFrame * dstChannels;
278 /* Integer rounding correct division */
279 rframes =
280 (sframes * context->common.format.nSamplesPerSec + (srcFormat->nSamplesPerSec + 1) / 2) /
281 srcFormat->nSamplesPerSec;
282 rsize = rframes * rbytes;
283
284 if (!Stream_EnsureCapacity(context->common.resample, rsize))
285 return FALSE;
286
287 error =
288 soxr_process(context->sox, src, sframes, &idone, Stream_Buffer(context->common.resample),
289 Stream_Capacity(context->common.resample) / rbytes, &odone);
290 if (!Stream_SetLength(context->common.resample, odone * rbytes))
291 return FALSE;
292
293 *data = Stream_Buffer(context->common.resample);
294 *length = Stream_Length(context->common.resample);
295 return (error == 0) != 0;
296#else
297 WLog_ERR(TAG, "Missing resample support, recompile -DWITH_SOXR=ON or -DWITH_DSP_FFMPEG=ON");
298 return FALSE;
299#endif
300}
301
309static const INT16 ima_step_index_table[] = {
310 -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8
311};
312
313static const INT16 ima_step_size_table[] = {
314 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23,
315 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80,
316 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
317 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
318 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
319 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487,
320 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
321};
322
323static inline void dsp_ima_clamp_step(ADPCM* WINPR_RESTRICT adpcm, unsigned int channel)
324{
325 WINPR_ASSERT(adpcm);
326 if (adpcm->ima.last_step[channel] < 0)
327 adpcm->ima.last_step[channel] = 0;
328
329 const size_t size = ARRAYSIZE(ima_step_size_table);
330 if (adpcm->ima.last_step[channel] > size)
331 adpcm->ima.last_step[channel] = size;
332}
333
334static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, unsigned int channel,
335 BYTE sample)
336{
337 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
338 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
339
340 const INT16 offset = adpcm->ima.last_step[channel];
341 WINPR_ASSERT(offset >= 0);
342 WINPR_ASSERT(WINPR_CXX_COMPAT_CAST(size_t, offset) < ARRAYSIZE(ima_step_size_table));
343
344 const INT32 ss = ima_step_size_table[offset];
345 INT32 d = (ss >> 3);
346
347 if (sample & 1)
348 d += (ss >> 2);
349
350 if (sample & 2)
351 d += (ss >> 1);
352
353 if (sample & 4)
354 d += ss;
355
356 if (sample & 8)
357 d = -d;
358
359 d += adpcm->ima.last_sample[channel];
360
361 if (d < -32768)
362 d = -32768;
363 else if (d > 32767)
364 d = 32767;
365
366 adpcm->ima.last_sample[channel] = (INT16)d;
367
368 WINPR_ASSERT(sample < ARRAYSIZE(ima_step_index_table));
369 adpcm->ima.last_step[channel] = adpcm->ima.last_step[channel] + ima_step_index_table[sample];
370
371 dsp_ima_clamp_step(adpcm, channel);
372
373 return (UINT16)d;
374}
375
376static BOOL valid_ima_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
377{
378 WINPR_ASSERT(context);
379 if (context->common.format.wFormatTag != WAVE_FORMAT_DVI_ADPCM)
380 return FALSE;
381 if (context->common.format.nBlockAlign <= 4ULL)
382 return FALSE;
383 if (context->common.format.nChannels < 1)
384 return FALSE;
385 if (context->common.format.wBitsPerSample == 0)
386 return FALSE;
387 return TRUE;
388}
389
390static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
391 const BYTE* WINPR_RESTRICT src, size_t size,
392 wStream* WINPR_RESTRICT out)
393{
394 if (!valid_ima_adpcm_format(context))
395 return FALSE;
396
397 size_t out_size = size * 4ull;
398 const UINT32 block_size = context->common.format.nBlockAlign;
399 const UINT32 channels = context->common.format.nChannels;
400
401 if (!Stream_EnsureCapacity(out, out_size))
402 return FALSE;
403
404 while (size > 0)
405 {
406 if (size % block_size == 0)
407 {
408 if (size < 4)
409 return FALSE;
410
411 context->adpcm.ima.last_sample[0] =
412 (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
413 context->adpcm.ima.last_step[0] = (INT16)(*(src + 2));
414
415 dsp_ima_clamp_step(&context->adpcm, 0);
416
417 src += 4;
418 size -= 4;
419 out_size -= 16;
420
421 if (channels > 1)
422 {
423 if (size < 4)
424 return FALSE;
425 context->adpcm.ima.last_sample[1] =
426 (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
427 context->adpcm.ima.last_step[1] = (INT16)(*(src + 2));
428
429 dsp_ima_clamp_step(&context->adpcm, 1);
430 src += 4;
431 size -= 4;
432 out_size -= 16;
433 }
434 }
435
436 if (channels > 1)
437 {
438 if (size < 8)
439 return FALSE;
440 for (size_t i = 0; i < 8; i++)
441 {
442 BYTE* dst = Stream_Pointer(out);
443
444 const unsigned channel = (i < 4 ? 0 : 1);
445 {
446 const BYTE sample = ((*src) & 0x0f);
447 const UINT16 decoded =
448 dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
449 dst[((i & 3) << 3) + (channel << 1u)] = (decoded & 0xFF);
450 dst[((i & 3) << 3) + (channel << 1u) + 1] = (decoded >> 8);
451 }
452 {
453 const BYTE sample = ((*src) >> 4);
454 const UINT16 decoded =
455 dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
456 dst[((i & 3) << 3) + (channel << 1u) + 4] = (decoded & 0xFF);
457 dst[((i & 3) << 3) + (channel << 1u) + 5] = (decoded >> 8);
458 }
459 src++;
460 }
461
462 if (!Stream_SafeSeek(out, 32))
463 return FALSE;
464 size -= 8;
465 }
466 else
467 {
468 if (size < 1)
469 return FALSE;
470 BYTE* dst = Stream_Pointer(out);
471 if (!Stream_SafeSeek(out, 4))
472 return FALSE;
473
474 {
475 const BYTE sample = ((*src) & 0x0f);
476 const UINT16 decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
477 *dst++ = (decoded & 0xFF);
478 *dst++ = (decoded >> 8);
479 }
480 {
481 const BYTE sample = ((*src) >> 4);
482 const UINT16 decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
483 *dst++ = (decoded & 0xFF);
484 *dst++ = (decoded >> 8);
485 }
486 src++;
487 size--;
488 }
489 }
490
491 return TRUE;
492}
493
494#if defined(WITH_GSM)
495static BOOL freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
496 const BYTE* WINPR_RESTRICT src, size_t size,
497 wStream* WINPR_RESTRICT out)
498{
499 size_t offset = 0;
500
501 while (offset < size)
502 {
503 int rc;
504 gsm_signal gsmBlockBuffer[160] = WINPR_C_ARRAY_INIT;
505 rc = gsm_decode(context->gsm, (gsm_byte*)/* API does not modify */ &src[offset],
506 gsmBlockBuffer);
507
508 if (rc < 0)
509 return FALSE;
510
511 if ((offset % 65) == 0)
512 offset += 33;
513 else
514 offset += 32;
515
516 if (!Stream_EnsureRemainingCapacity(out, sizeof(gsmBlockBuffer)))
517 return FALSE;
518
519 Stream_Write(out, (void*)gsmBlockBuffer, sizeof(gsmBlockBuffer));
520 }
521
522 return TRUE;
523}
524
525static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
526 const BYTE* WINPR_RESTRICT src, size_t size,
527 wStream* WINPR_RESTRICT out)
528{
529 size_t offset = 0;
530
531 while (offset < size)
532 {
533 const gsm_signal* signal = (const gsm_signal*)&src[offset];
534
535 if (!Stream_EnsureRemainingCapacity(out, sizeof(gsm_frame)))
536 return FALSE;
537
538 gsm_encode(context->gsm, (gsm_signal*)/* API does not modify */ signal,
539 Stream_Pointer(out));
540
541 if ((offset % 65) == 0)
542 Stream_Seek(out, 33);
543 else
544 Stream_Seek(out, 32);
545
546 offset += 160;
547 }
548
549 return TRUE;
550}
551#endif
552
553#if defined(WITH_LAME)
554static BOOL valid_mp3_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
555{
556 WINPR_ASSERT(context);
557 if (context->common.format.wFormatTag != WAVE_FORMAT_MPEGLAYER3)
558 return FALSE;
559 if (context->common.format.nChannels < 1)
560 return FALSE;
561 if (context->common.format.wBitsPerSample == 0)
562 return FALSE;
563 if (context->common.format.nSamplesPerSec == 0)
564 return FALSE;
565 return TRUE;
566}
567
568static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
569 const BYTE* WINPR_RESTRICT src, size_t size,
570 wStream* WINPR_RESTRICT out)
571{
572 if (!context || !src || !out)
573 return FALSE;
574 if (!valid_mp3_format(context))
575 return FALSE;
576 const size_t buffer_size =
577 2 * context->common.format.nChannels * context->common.format.nSamplesPerSec;
578
579 if (!Stream_EnsureCapacity(context->common.buffer, 2 * buffer_size))
580 return FALSE;
581
582 short* pcm_l = Stream_BufferAs(context->common.buffer, short);
583 short* pcm_r = Stream_BufferAs(context->common.buffer, short) + buffer_size;
584 const int rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src,
585 size, pcm_l, pcm_r);
586
587 if (rc <= 0)
588 return FALSE;
589
590 if (!Stream_EnsureRemainingCapacity(out, (size_t)rc * context->common.format.nChannels * 2))
591 return FALSE;
592
593 for (size_t x = 0; x < rc; x++)
594 {
595 Stream_Write_UINT16(out, (UINT16)pcm_l[x]);
596 Stream_Write_UINT16(out, (UINT16)pcm_r[x]);
597 }
598
599 return TRUE;
600}
601
602static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
603 const BYTE* WINPR_RESTRICT src, size_t size,
604 wStream* WINPR_RESTRICT out)
605{
606 if (!context || !src || !out)
607 return FALSE;
608
609 if (!valid_mp3_format(context))
610 return FALSE;
611
612 size_t samples_per_channel =
613 size / context->common.format.nChannels / context->common.format.wBitsPerSample / 8;
614
615 /* Ensure worst case buffer size for mp3 stream taken from LAME header */
616 if (!Stream_EnsureRemainingCapacity(out, 5 / 4 * samples_per_channel + 7200))
617 return FALSE;
618
619 samples_per_channel = size / 2 /* size of a sample */ / context->common.format.nChannels;
620 const int rc =
621 lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
622 Stream_Pointer(out), Stream_GetRemainingCapacity(out));
623
624 if (rc < 0)
625 return FALSE;
626
627 Stream_Seek(out, (size_t)rc);
628 return TRUE;
629}
630#endif
631
632#if defined(WITH_FAAC)
633static BOOL freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
634 const BYTE* WINPR_RESTRICT src, size_t size,
635 wStream* WINPR_RESTRICT out)
636{
637 const int16_t* inSamples = (const int16_t*)src;
638 unsigned int bpp;
639 size_t nrSamples;
640 int rc;
641
642 if (!context || !src || !out)
643 return FALSE;
644
645 bpp = context->common.format.wBitsPerSample / 8;
646 nrSamples = size / bpp;
647
648 if (!Stream_EnsureRemainingCapacity(context->common.buffer, nrSamples * sizeof(int16_t)))
649 return FALSE;
650
651 for (size_t x = 0; x < nrSamples; x++)
652 {
653 Stream_Write_INT16(context->common.buffer, inSamples[x]);
654 if (Stream_GetPosition(context->common.buffer) / bpp >= context->faacInputSamples)
655 {
656 if (!Stream_EnsureRemainingCapacity(out, context->faacMaxOutputBytes))
657 return FALSE;
658 rc = faacEncEncode(context->faac, Stream_BufferAs(context->common.buffer, int32_t),
659 context->faacInputSamples, Stream_Pointer(out),
660 Stream_GetRemainingCapacity(out));
661 if (rc < 0)
662 return FALSE;
663 if (rc > 0)
664 Stream_Seek(out, (size_t)rc);
665 Stream_ResetPosition(context->common.buffer);
666 }
667 }
668
669 return TRUE;
670}
671#endif
672
673#if defined(WITH_OPUS)
674static BOOL freerdp_dsp_decode_opus(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
675 const BYTE* WINPR_RESTRICT src, size_t size,
676 wStream* WINPR_RESTRICT out)
677{
678 if (!context || !src || !out)
679 return FALSE;
680
681 /* Max packet duration is 120ms (5760 at 48KHz) */
682 const size_t max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
683 if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
684 return FALSE;
685
686 const opus_int32 frames =
687 opus_decode(context->opus_decoder, src, WINPR_ASSERTING_INT_CAST(opus_int32, size),
688 Stream_Pointer(out), OPUS_MAX_FRAMES, 0);
689 if (frames < 0)
690 return FALSE;
691
692 Stream_Seek(out, (size_t)frames * context->common.format.nChannels * sizeof(int16_t));
693
694 return TRUE;
695}
696
697static BOOL freerdp_dsp_encode_opus(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
698 const BYTE* WINPR_RESTRICT src, size_t size,
699 wStream* WINPR_RESTRICT out)
700{
701 if (!context || !src || !out)
702 return FALSE;
703
704 /* Max packet duration is 120ms (5760 at 48KHz) */
705 const size_t max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
706 if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
707 return FALSE;
708
709 const size_t src_frames = size / sizeof(opus_int16) / context->common.format.nChannels;
710 const opus_int16* src_data = (const opus_int16*)src;
711 const opus_int32 frames = opus_encode(
712 context->opus_encoder, src_data, WINPR_ASSERTING_INT_CAST(opus_int32, src_frames),
713 Stream_Pointer(out), WINPR_ASSERTING_INT_CAST(opus_int32, max_size));
714 if (frames < 0)
715 return FALSE;
716 return Stream_SafeSeek(out,
717 (size_t)frames * context->common.format.nChannels * sizeof(int16_t));
718}
719#endif
720
721#if defined(WITH_FAAD2)
722static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
723 const BYTE* WINPR_RESTRICT src, size_t size,
724 wStream* WINPR_RESTRICT out)
725{
726 NeAACDecFrameInfo info;
727 size_t offset = 0;
728
729 if (!context || !src || !out)
730 return FALSE;
731
732 if (!context->faadSetup)
733 {
734 union
735 {
736 const void* cpv;
737 void* pv;
738 } cnv;
739 unsigned long samplerate;
740 unsigned char channels;
741 long err;
742 cnv.cpv = src;
743 err = NeAACDecInit(context->faad, /* API is not modifying content */ cnv.pv, size,
744 &samplerate, &channels);
745
746 if (err != 0)
747 return FALSE;
748
749 if (channels != context->common.format.nChannels)
750 return FALSE;
751
752 if (samplerate != context->common.format.nSamplesPerSec)
753 return FALSE;
754
755 context->faadSetup = TRUE;
756 }
757
758 while (offset < size)
759 {
760 union
761 {
762 const void* cpv;
763 void* pv;
764 } cnv;
765 size_t outSize;
766 void* sample_buffer;
767 outSize = context->common.format.nSamplesPerSec * context->common.format.nChannels *
768 context->common.format.wBitsPerSample / 8;
769
770 if (!Stream_EnsureRemainingCapacity(out, outSize))
771 return FALSE;
772
773 sample_buffer = Stream_Pointer(out);
774
775 cnv.cpv = &src[offset];
776 NeAACDecDecode2(context->faad, &info, cnv.pv, size - offset, &sample_buffer,
777 Stream_GetRemainingCapacity(out));
778
779 if (info.error != 0)
780 return FALSE;
781
782 offset += info.bytesconsumed;
783
784 if (info.samples == 0)
785 continue;
786
787 Stream_Seek(out, info.samples * context->common.format.wBitsPerSample / 8);
788 }
789
790 return TRUE;
791}
792
793#endif
794
802static const struct
803{
804 BYTE byte_num;
805 BYTE byte_shift;
806} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
807 { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
808 { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
809
810static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, size_t channel, INT16 sample)
811{
812 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
813 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
814
815 const INT16 offset = adpcm->ima.last_step[channel];
816 WINPR_ASSERT(offset >= 0);
817 WINPR_ASSERT(WINPR_CXX_COMPAT_CAST(size_t, offset) < ARRAYSIZE(ima_step_size_table));
818
819 INT32 ss = ima_step_size_table[offset];
820 INT32 e = sample - adpcm->ima.last_sample[channel];
821 INT32 d = e;
822 INT32 diff = ss >> 3;
823 BYTE enc = 0;
824
825 if (e < 0)
826 {
827 enc = 8;
828 e = -e;
829 }
830
831 if (e >= ss)
832 {
833 enc |= 4;
834 e -= ss;
835 }
836
837 ss >>= 1;
838
839 if (e >= ss)
840 {
841 enc |= 2;
842 e -= ss;
843 }
844
845 ss >>= 1;
846
847 if (e >= ss)
848 {
849 enc |= 1;
850 e -= ss;
851 }
852
853 if (d < 0)
854 diff = d + e - diff;
855 else
856 diff = d - e + diff;
857
858 diff += adpcm->ima.last_sample[channel];
859
860 if (diff < -32768)
861 diff = -32768;
862 else if (diff > 32767)
863 diff = 32767;
864
865 adpcm->ima.last_sample[channel] = (INT16)diff;
866
867 WINPR_ASSERT(enc < ARRAYSIZE(ima_step_index_table));
868 adpcm->ima.last_step[channel] = adpcm->ima.last_step[channel] + ima_step_index_table[enc];
869
870 dsp_ima_clamp_step(adpcm, channel);
871
872 return enc;
873}
874
875static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
876 const BYTE* WINPR_RESTRICT src, size_t size,
877 wStream* WINPR_RESTRICT out)
878{
879 if (!valid_ima_adpcm_format(context))
880 return FALSE;
881 if (!Stream_EnsureRemainingCapacity(out, size))
882 return FALSE;
883 if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
884 return FALSE;
885
886 const size_t align = (context->common.format.nChannels > 1) ? 32 : 4;
887
888 while (size >= align)
889 {
890 if (Stream_GetPosition(context->common.buffer) % context->common.format.nBlockAlign == 0)
891 {
892 Stream_Write_UINT8(context->common.buffer, context->adpcm.ima.last_sample[0] & 0xFF);
893 Stream_Write_UINT8(context->common.buffer,
894 (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
895 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[0]);
896 Stream_Write_UINT8(context->common.buffer, 0);
897
898 if (context->common.format.nChannels > 1)
899 {
900 Stream_Write_UINT8(context->common.buffer,
901 context->adpcm.ima.last_sample[1] & 0xFF);
902 Stream_Write_UINT8(context->common.buffer,
903 (context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
904 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[1]);
905 Stream_Write_UINT8(context->common.buffer, 0);
906 }
907 }
908
909 if (context->common.format.nChannels > 1)
910 {
911 BYTE* dst = Stream_Pointer(context->common.buffer);
912 ZeroMemory(dst, 8);
913
914 for (size_t i = 0; i < 16; i++)
915 {
916 const INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
917 src += 2;
918 const BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
919 dst[ima_stereo_encode_map[i].byte_num] |= encoded
920 << ima_stereo_encode_map[i].byte_shift;
921 }
922
923 if (!Stream_SafeSeek(context->common.buffer, 8))
924 return FALSE;
925 size -= 32;
926 }
927 else
928 {
929 INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
930 src += 2;
931 BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
932 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
933 src += 2;
934 encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
935 Stream_Write_UINT8(context->common.buffer, encoded);
936 size -= 4;
937 }
938
939 if (Stream_GetPosition(context->common.buffer) >= context->adpcm.ima.packet_size)
940 {
941 BYTE* bsrc = Stream_Buffer(context->common.buffer);
942 Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
943 Stream_ResetPosition(context->common.buffer);
944 }
945 }
946
947 return TRUE;
948}
949
956static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
957 768, 614, 512, 409, 307, 230, 230, 230 };
958
959static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
960
961static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
962
963static inline INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
964 size_t channel)
965{
966 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
967 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
968 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
969 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
970
971 const INT8 nibble = (INT8)((sample & 0x08) ? (sample - 16) : sample);
972 const BYTE predictor = adpcm->ms.predictor[channel];
973 INT32 coeff1 = 0;
974 if (predictor < ARRAYSIZE(ms_adpcm_coeffs1))
975 coeff1 = ms_adpcm_coeffs1[predictor];
976
977 INT32 coeff2 = 0;
978 if (predictor < ARRAYSIZE(ms_adpcm_coeffs2))
979 coeff2 = ms_adpcm_coeffs2[predictor];
980 INT32 presample =
981 ((adpcm->ms.sample1[channel] * coeff1) + (adpcm->ms.sample2[channel] * coeff2)) / 256;
982 presample += nibble * adpcm->ms.delta[channel];
983
984 if (presample > 32767)
985 presample = 32767;
986 else if (presample < -32768)
987 presample = -32768;
988
989 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
990 adpcm->ms.sample1[channel] = presample;
991
992 INT32 tableval = 0;
993 if (sample < ARRAYSIZE(ms_adpcm_adaptation_table))
994 tableval = ms_adpcm_adaptation_table[sample];
995
996 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * tableval / 256;
997
998 if (adpcm->ms.delta[channel] < 16)
999 adpcm->ms.delta[channel] = 16;
1000
1001 return (INT16)presample;
1002}
1003
1004static BOOL valid_ms_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
1005{
1006 WINPR_ASSERT(context);
1007 if (context->common.format.wFormatTag != WAVE_FORMAT_ADPCM)
1008 return FALSE;
1009 if (context->common.format.nBlockAlign <= 4ULL)
1010 return FALSE;
1011 if (context->common.format.nChannels < 1)
1012 return FALSE;
1013 if (context->common.format.wBitsPerSample == 0)
1014 return FALSE;
1015 return TRUE;
1016}
1017
1018static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1019 const BYTE* WINPR_RESTRICT src, size_t size,
1020 wStream* WINPR_RESTRICT out)
1021{
1022 if (!valid_ms_adpcm_format(context))
1023 return FALSE;
1024 const size_t out_size = size * 4;
1025 const UINT32 channels = context->common.format.nChannels;
1026 const UINT32 block_size = context->common.format.nBlockAlign;
1027
1028 if (!Stream_EnsureCapacity(out, out_size))
1029 return FALSE;
1030
1031 while (size > 0)
1032 {
1033 if (size % block_size == 0)
1034 {
1035 if (channels > 1)
1036 {
1037 if (size < 14)
1038 return FALSE;
1039
1040 context->adpcm.ms.predictor[0] = *src++;
1041 context->adpcm.ms.predictor[1] = *src++;
1042 context->adpcm.ms.delta[0] = read_int16(src);
1043 src += 2;
1044 context->adpcm.ms.delta[1] = read_int16(src);
1045 src += 2;
1046 context->adpcm.ms.sample1[0] = read_int16(src);
1047 src += 2;
1048 context->adpcm.ms.sample1[1] = read_int16(src);
1049 src += 2;
1050 context->adpcm.ms.sample2[0] = read_int16(src);
1051 src += 2;
1052 context->adpcm.ms.sample2[1] = read_int16(src);
1053 src += 2;
1054 size -= 14;
1055 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1056 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1057 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1058 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1059 }
1060 else
1061 {
1062 if (size < 7)
1063 return FALSE;
1064
1065 context->adpcm.ms.predictor[0] = *src++;
1066 context->adpcm.ms.delta[0] = read_int16(src);
1067 src += 2;
1068 context->adpcm.ms.sample1[0] = read_int16(src);
1069 src += 2;
1070 context->adpcm.ms.sample2[0] = read_int16(src);
1071 src += 2;
1072 size -= 7;
1073 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1074 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1075 }
1076 }
1077
1078 if (channels > 1)
1079 {
1080 {
1081 if (size < 1)
1082 return FALSE;
1083 const BYTE sample = *src++;
1084 size--;
1085 Stream_Write_INT16(
1086 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1087 Stream_Write_INT16(
1088 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1089 }
1090 {
1091 if (size < 1)
1092 return FALSE;
1093 const BYTE sample = *src++;
1094 size--;
1095 Stream_Write_INT16(
1096 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1097 Stream_Write_INT16(
1098 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1099 }
1100 }
1101 else
1102 {
1103 if (size < 1)
1104 return FALSE;
1105 const BYTE sample = *src++;
1106 size--;
1107 Stream_Write_INT16(out,
1108 freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1109 Stream_Write_INT16(
1110 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
1111 }
1112 }
1113
1114 return TRUE;
1115}
1116
1117static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
1118 size_t channel)
1119{
1120 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
1121 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
1122 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
1123 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
1124
1125 INT32 presample =
1126 ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
1127 (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
1128 256;
1129 INT32 errordelta = (sample - presample) / adpcm->ms.delta[channel];
1130
1131 if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
1132 errordelta++;
1133
1134 if (errordelta > 7)
1135 errordelta = 7;
1136 else if (errordelta < -8)
1137 errordelta = -8;
1138
1139 presample += adpcm->ms.delta[channel] * errordelta;
1140
1141 if (presample > 32767)
1142 presample = 32767;
1143 else if (presample < -32768)
1144 presample = -32768;
1145
1146 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
1147 adpcm->ms.sample1[channel] = presample;
1148 const size_t offset = (((BYTE)errordelta) & 0x0F);
1149 WINPR_ASSERT(offset < ARRAYSIZE(ms_adpcm_adaptation_table));
1150 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[offset] / 256;
1151
1152 if (adpcm->ms.delta[channel] < 16)
1153 adpcm->ms.delta[channel] = 16;
1154
1155 return ((BYTE)errordelta) & 0x0F;
1156}
1157
1158static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1159 const BYTE* WINPR_RESTRICT src, size_t size,
1160 wStream* WINPR_RESTRICT out)
1161{
1162 if (!valid_ms_adpcm_format(context))
1163 return FALSE;
1164
1165 const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
1166
1167 if (!Stream_EnsureRemainingCapacity(out, size))
1168 return FALSE;
1169
1170 const size_t start = Stream_GetPosition(out);
1171
1172 if (context->adpcm.ms.delta[0] < 16)
1173 context->adpcm.ms.delta[0] = 16;
1174
1175 if (context->adpcm.ms.delta[1] < 16)
1176 context->adpcm.ms.delta[1] = 16;
1177
1178 while (size >= step)
1179 {
1180 if ((Stream_GetPosition(out) - start) % context->common.format.nBlockAlign == 0)
1181 {
1182 if (context->common.format.nChannels > 1)
1183 {
1184 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1185 Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
1186 Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
1187 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1188 Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
1189 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
1190
1191 context->adpcm.ms.sample1[0] = read_int16(src + 4);
1192 context->adpcm.ms.sample1[1] = read_int16(src + 6);
1193 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1194 context->adpcm.ms.sample2[1] = read_int16(src + 2);
1195
1196 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1197 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1198 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1199 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1200
1201 src += 8;
1202 size -= 8;
1203 }
1204 else
1205 {
1206 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1207 Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
1208 Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1209
1210 context->adpcm.ms.sample1[0] = read_int16(src + 2);
1211 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1212
1213 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1214 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1215 src += 4;
1216 size -= 4;
1217 }
1218 }
1219
1220 {
1221 const INT16 sample = read_int16(src);
1222 src += 2;
1223 Stream_Write_UINT8(
1224 out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
1225 }
1226 {
1227 const INT16 sample = read_int16(src);
1228 src += 2;
1229
1230 BYTE val = 0;
1231 Stream_Read_UINT8(out, val);
1232 val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1233 context->common.format.nChannels > 1 ? 1 : 0);
1234 Stream_Write_UINT8(out, val);
1235 }
1236 size -= 4;
1237 }
1238
1239 return TRUE;
1240}
1241
1242#endif
1243
1244FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1245{
1246#if defined(WITH_DSP_FFMPEG)
1247 return freerdp_dsp_ffmpeg_context_new(encoder);
1248#else
1249 FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1250
1251 if (!context)
1252 return nullptr;
1253
1254 if (!freerdp_dsp_common_context_init(&context->common, encoder))
1255 goto fail;
1256
1257#if defined(WITH_GSM)
1258 context->gsm = gsm_create();
1259
1260 if (!context->gsm)
1261 goto fail;
1262
1263 {
1264 int rc;
1265 int val = 1;
1266 rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1267
1268 if (rc < 0)
1269 goto fail;
1270 }
1271#endif
1272#if defined(WITH_LAME)
1273
1274 if (encoder)
1275 {
1276 context->lame = lame_init();
1277
1278 if (!context->lame)
1279 goto fail;
1280 }
1281 else
1282 {
1283 context->hip = hip_decode_init();
1284
1285 if (!context->hip)
1286 goto fail;
1287 }
1288
1289#endif
1290#if defined(WITH_FAAD2)
1291
1292 if (!encoder)
1293 {
1294 context->faad = NeAACDecOpen();
1295
1296 if (!context->faad)
1297 goto fail;
1298 }
1299
1300#endif
1301 return context;
1302fail:
1303 freerdp_dsp_context_free(context);
1304 return nullptr;
1305#endif
1306}
1307
1308void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1309{
1310 if (!context)
1311 return;
1312
1313#if defined(WITH_FDK_AAC)
1315 WINPR_ASSERT(ctx);
1316 fdk_aac_dsp_uninit(ctx);
1317#endif
1318
1319#if defined(WITH_DSP_FFMPEG)
1320 freerdp_dsp_ffmpeg_context_free(context);
1321#else
1322
1323 freerdp_dsp_common_context_uninit(&context->common);
1324
1325#if defined(WITH_GSM)
1326 gsm_destroy(context->gsm);
1327#endif
1328#if defined(WITH_LAME)
1329
1330 if (context->common.encoder)
1331 lame_close(context->lame);
1332 else
1333 hip_decode_exit(context->hip);
1334
1335#endif
1336#if defined(WITH_OPUS)
1337
1338 if (context->opus_decoder)
1339 opus_decoder_destroy(context->opus_decoder);
1340 if (context->opus_encoder)
1341 opus_encoder_destroy(context->opus_encoder);
1342
1343#endif
1344#if defined(WITH_FAAD2)
1345
1346 if (!context->common.encoder)
1347 NeAACDecClose(context->faad);
1348
1349#endif
1350#if defined(WITH_FAAC)
1351
1352 if (context->faac)
1353 faacEncClose(context->faac);
1354
1355#endif
1356#if defined(WITH_SOXR)
1357 soxr_delete(context->sox);
1358#endif
1359 free(context);
1360
1361#endif
1362}
1363
1364BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1365 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1366 const BYTE* WINPR_RESTRICT pdata, size_t length,
1367 wStream* WINPR_RESTRICT out)
1368{
1369#if defined(WITH_FDK_AAC)
1371 WINPR_ASSERT(ctx);
1372 switch (ctx->format.wFormatTag)
1373 {
1374 case WAVE_FORMAT_AAC_MS:
1375 return fdk_aac_dsp_encode(ctx, srcFormat, pdata, length, out);
1376 default:
1377 break;
1378 }
1379#endif
1380
1381#if defined(WITH_DSP_FFMPEG)
1382 return freerdp_dsp_ffmpeg_encode(context, srcFormat, pdata, length, out);
1383#else
1384 if (!context || !context->common.encoder || !srcFormat || !pdata || !out)
1385 return FALSE;
1386
1387 AUDIO_FORMAT format = *srcFormat;
1388 const BYTE* resampleData = nullptr;
1389 size_t resampleLength = 0;
1390
1391 if (!freerdp_dsp_channel_mix(context, pdata, length, srcFormat, &resampleData, &resampleLength))
1392 return FALSE;
1393
1394 format.nChannels = context->common.format.nChannels;
1395
1396 const BYTE* data = nullptr;
1397 if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1398 return FALSE;
1399
1400 switch (context->common.format.wFormatTag)
1401 {
1402 case WAVE_FORMAT_PCM:
1403 if (!Stream_EnsureRemainingCapacity(out, length))
1404 return FALSE;
1405
1406 Stream_Write(out, data, length);
1407 return TRUE;
1408
1409 case WAVE_FORMAT_ADPCM:
1410 return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1411
1412 case WAVE_FORMAT_DVI_ADPCM:
1413 return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1414#if defined(WITH_GSM)
1415
1416 case WAVE_FORMAT_GSM610:
1417 return freerdp_dsp_encode_gsm610(context, data, length, out);
1418#endif
1419#if defined(WITH_LAME)
1420
1421 case WAVE_FORMAT_MPEGLAYER3:
1422 return freerdp_dsp_encode_mp3(context, data, length, out);
1423#endif
1424#if defined(WITH_FAAC)
1425
1426 case WAVE_FORMAT_AAC_MS:
1427 return freerdp_dsp_encode_faac(context, data, length, out);
1428#endif
1429#if defined(WITH_OPUS)
1430
1431 case WAVE_FORMAT_OPUS:
1432 return freerdp_dsp_encode_opus(context, data, length, out);
1433#endif
1434 default:
1435 return FALSE;
1436 }
1437
1438 return FALSE;
1439#endif
1440}
1441
1442BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1443 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1444 const BYTE* WINPR_RESTRICT data, size_t length, wStream* WINPR_RESTRICT out)
1445{
1446#if defined(WITH_FDK_AAC)
1448 WINPR_ASSERT(ctx);
1449 switch (ctx->format.wFormatTag)
1450 {
1451 case WAVE_FORMAT_AAC_MS:
1452 return fdk_aac_dsp_decode(ctx, srcFormat, data, length, out);
1453 default:
1454 break;
1455 }
1456#endif
1457
1458#if defined(WITH_DSP_FFMPEG)
1459 return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1460#else
1461
1462 if (!context || context->common.encoder || !srcFormat || !data || !out)
1463 return FALSE;
1464
1465 switch (context->common.format.wFormatTag)
1466 {
1467 case WAVE_FORMAT_PCM:
1468 if (!Stream_EnsureRemainingCapacity(out, length))
1469 return FALSE;
1470
1471 Stream_Write(out, data, length);
1472 return TRUE;
1473
1474 case WAVE_FORMAT_ADPCM:
1475 return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1476
1477 case WAVE_FORMAT_DVI_ADPCM:
1478 return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1479#if defined(WITH_GSM)
1480
1481 case WAVE_FORMAT_GSM610:
1482 return freerdp_dsp_decode_gsm610(context, data, length, out);
1483#endif
1484#if defined(WITH_LAME)
1485
1486 case WAVE_FORMAT_MPEGLAYER3:
1487 return freerdp_dsp_decode_mp3(context, data, length, out);
1488#endif
1489#if defined(WITH_FAAD2)
1490
1491 case WAVE_FORMAT_AAC_MS:
1492 return freerdp_dsp_decode_faad(context, data, length, out);
1493#endif
1494
1495#if defined(WITH_OPUS)
1496 case WAVE_FORMAT_OPUS:
1497 return freerdp_dsp_decode_opus(context, data, length, out);
1498#endif
1499 default:
1500 return FALSE;
1501 }
1502
1503 return FALSE;
1504#endif
1505}
1506
1507BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* WINPR_RESTRICT format, BOOL encode)
1508{
1509#if defined(WITH_FDK_AAC)
1510 switch (format->wFormatTag)
1511 {
1512 case WAVE_FORMAT_AAC_MS:
1513 return TRUE;
1514 default:
1515 break;
1516 }
1517
1518#endif
1519
1520#if defined(WITH_DSP_FFMPEG)
1521 return freerdp_dsp_ffmpeg_supports_format(format, encode);
1522#else
1523
1524#if !defined(WITH_DSP_EXPERIMENTAL)
1525 WINPR_UNUSED(encode);
1526#endif
1527 switch (format->wFormatTag)
1528 {
1529 case WAVE_FORMAT_PCM:
1530 return TRUE;
1531#if defined(WITH_DSP_EXPERIMENTAL)
1532
1533 case WAVE_FORMAT_ADPCM:
1534 return FALSE;
1535 case WAVE_FORMAT_DVI_ADPCM:
1536 return TRUE;
1537#endif
1538#if defined(WITH_GSM)
1539
1540 case WAVE_FORMAT_GSM610:
1541#if defined(WITH_DSP_EXPERIMENTAL)
1542 return TRUE;
1543#else
1544 return !encode;
1545#endif
1546#endif
1547#if defined(WITH_LAME)
1548
1549 case WAVE_FORMAT_MPEGLAYER3:
1550#if defined(WITH_DSP_EXPERIMENTAL)
1551 return TRUE;
1552#else
1553 return !encode;
1554#endif
1555#endif
1556
1557 case WAVE_FORMAT_AAC_MS:
1558#if defined(WITH_FAAD2)
1559 if (!encode)
1560 return TRUE;
1561
1562#endif
1563#if defined(WITH_FAAC)
1564
1565 if (encode)
1566 return TRUE;
1567
1568#endif
1569#if defined(WITH_FDK_AAC)
1570 return TRUE;
1571#else
1572 return FALSE;
1573#endif
1574
1575#if defined(WITH_OPUS)
1576 case WAVE_FORMAT_OPUS:
1577 return opus_is_valid_samplerate(format);
1578#endif
1579 default:
1580 return FALSE;
1581 }
1582
1583 return FALSE;
1584#endif
1585}
1586
1587BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1588 const AUDIO_FORMAT* WINPR_RESTRICT targetFormat,
1589 WINPR_ATTR_UNUSED UINT32 FramesPerPacket)
1590{
1591#if defined(WITH_FDK_AAC)
1592 WINPR_ASSERT(targetFormat);
1593 if (targetFormat->wFormatTag == WAVE_FORMAT_AAC_MS)
1594 {
1596 fdk_aac_dsp_uninit(ctx);
1597 ctx->format = *targetFormat;
1598 return fdk_aac_dsp_init(ctx, FramesPerPacket);
1599 }
1600#endif
1601
1602#if defined(WITH_DSP_FFMPEG)
1603 return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1604#else
1605
1606 if (!context || !targetFormat)
1607 return FALSE;
1608
1609 context->common.format = *targetFormat;
1610
1611 switch (context->common.format.wFormatTag)
1612 {
1613#if defined(WITH_LAME)
1614 case WAVE_FORMAT_MPEGLAYER3:
1615 if (!valid_mp3_format(context))
1616 return FALSE;
1617 break;
1618#endif
1619 case WAVE_FORMAT_ADPCM:
1620 if (!valid_ms_adpcm_format(context))
1621 return FALSE;
1622 break;
1623 case WAVE_FORMAT_DVI_ADPCM:
1624 {
1625 if (!valid_ima_adpcm_format(context))
1626 return FALSE;
1627 if (FramesPerPacket == 0)
1628 return FALSE;
1629
1630 const size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
1631 context->common.format.nChannels * FramesPerPacket;
1632 const size_t data_per_block = (1ULL * context->common.format.nBlockAlign -
1633 4ULL * context->common.format.nChannels) *
1634 8ULL;
1635 size_t nb_block_per_packet = min_frame_data / data_per_block;
1636
1637 if (min_frame_data % data_per_block)
1638 nb_block_per_packet++;
1639
1640 context->adpcm.ima.packet_size =
1641 nb_block_per_packet * context->common.format.nBlockAlign;
1642 if (!Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size))
1643 return FALSE;
1644 Stream_ResetPosition(context->common.buffer);
1645 }
1646 break;
1647 default:
1648 break;
1649 }
1650
1651#if defined(WITH_OPUS)
1652
1653 if (opus_is_valid_samplerate(&context->common.format))
1654 {
1655 if (!context->common.encoder)
1656 {
1657 int opus_error = OPUS_OK;
1658
1659 context->opus_decoder = opus_decoder_create(
1660 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1661 context->common.format.nChannels, &opus_error);
1662 if (opus_error != OPUS_OK)
1663 return FALSE;
1664 }
1665 else
1666 {
1667 int opus_error = OPUS_OK;
1668
1669 context->opus_encoder = opus_encoder_create(
1670 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1671 context->common.format.nChannels, OPUS_APPLICATION_VOIP, &opus_error);
1672 if (opus_error != OPUS_OK)
1673 return FALSE;
1674
1675 opus_error =
1676 opus_encoder_ctl(context->opus_encoder,
1677 OPUS_SET_BITRATE(context->common.format.nAvgBytesPerSec * 8));
1678 if (opus_error != OPUS_OK)
1679 return FALSE;
1680 }
1681 }
1682
1683#endif
1684#if defined(WITH_FAAD2)
1685 context->faadSetup = FALSE;
1686#endif
1687#if defined(WITH_FAAC)
1688
1689 if (context->common.encoder)
1690 {
1691 faacEncConfigurationPtr cfg = nullptr;
1692
1693 if (context->faac)
1694 faacEncClose(context->faac);
1695
1696 context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1697 &context->faacInputSamples, &context->faacMaxOutputBytes);
1698
1699 if (!context->faac)
1700 return FALSE;
1701
1702 cfg = faacEncGetCurrentConfiguration(context->faac);
1703 cfg->inputFormat = FAAC_INPUT_16BIT;
1704 cfg->outputFormat = 0;
1705 cfg->mpegVersion = MPEG4;
1706 cfg->useTns = 1;
1707 cfg->bandWidth = targetFormat->nAvgBytesPerSec;
1708 const int rc = faacEncSetConfiguration(context->faac, cfg);
1709 if (rc <= 0)
1710 return FALSE;
1711 }
1712
1713#endif
1714#if defined(WITH_SOXR)
1715 {
1716 soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1717 soxr_error_t error = nullptr;
1718
1719 soxr_delete(context->sox);
1720 context->sox =
1721 soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1722 targetFormat->nChannels, &error, &iospec, nullptr, nullptr);
1723
1724 if (!context->sox || (error != nullptr))
1725 return FALSE;
1726 }
1727#endif
1728 return TRUE;
1729#endif
1730}
1731
1732BOOL freerdp_dsp_common_context_init(FREERDP_DSP_COMMON_CONTEXT* context, BOOL encode)
1733{
1734 WINPR_ASSERT(context);
1735 context->encoder = encode;
1736 context->buffer = Stream_New(nullptr, 1024);
1737 if (!context->buffer)
1738 goto fail;
1739
1740 context->channelmix = Stream_New(nullptr, 1024);
1741 if (!context->channelmix)
1742 goto fail;
1743
1744 context->resample = Stream_New(nullptr, 1024);
1745 if (!context->resample)
1746 goto fail;
1747
1748 return TRUE;
1749
1750fail:
1751 freerdp_dsp_common_context_uninit(context);
1752 return FALSE;
1753}
1754
1755void freerdp_dsp_common_context_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
1756{
1757 WINPR_ASSERT(context);
1758
1759 Stream_Free(context->buffer, TRUE);
1760 Stream_Free(context->channelmix, TRUE);
1761 Stream_Free(context->resample, TRUE);
1762
1763 context->buffer = nullptr;
1764 context->channelmix = nullptr;
1765 context->resample = nullptr;
1766}