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 ((size_t)adpcm->ima.last_step[channel] >= size)
331 adpcm->ima.last_step[channel] = (INT16)(size - 1);
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 const int32_t last = adpcm->ima.last_step[channel] + ima_step_index_table[sample];
370 adpcm->ima.last_step[channel] = WINPR_ASSERTING_INT_CAST(int16_t, last);
371
372 dsp_ima_clamp_step(adpcm, channel);
373
374 return (UINT16)d;
375}
376
377static BOOL valid_ima_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
378{
379 WINPR_ASSERT(context);
380 if (context->common.format.wFormatTag != WAVE_FORMAT_DVI_ADPCM)
381 return FALSE;
382 if (context->common.format.nBlockAlign <= 4ULL)
383 return FALSE;
384 if (context->common.format.nChannels < 1)
385 return FALSE;
386 if (context->common.format.wBitsPerSample == 0)
387 return FALSE;
388 return TRUE;
389}
390
391static BOOL freerdp_dsp_decode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
392 const BYTE* WINPR_RESTRICT src, size_t size,
393 wStream* WINPR_RESTRICT out)
394{
395 if (!valid_ima_adpcm_format(context))
396 return FALSE;
397
398 size_t out_size = size * 4ull;
399 const UINT32 block_size = context->common.format.nBlockAlign;
400 const UINT32 channels = context->common.format.nChannels;
401
402 if (!Stream_EnsureCapacity(out, out_size))
403 return FALSE;
404
405 while (size > 0)
406 {
407 if (size % block_size == 0)
408 {
409 if (size < 4)
410 return FALSE;
411
412 context->adpcm.ima.last_sample[0] =
413 (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
414 context->adpcm.ima.last_step[0] = (INT16)(*(src + 2));
415
416 dsp_ima_clamp_step(&context->adpcm, 0);
417
418 src += 4;
419 size -= 4;
420 out_size -= 16;
421
422 if (channels > 1)
423 {
424 if (size < 4)
425 return FALSE;
426 context->adpcm.ima.last_sample[1] =
427 (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
428 context->adpcm.ima.last_step[1] = (INT16)(*(src + 2));
429
430 dsp_ima_clamp_step(&context->adpcm, 1);
431 src += 4;
432 size -= 4;
433 out_size -= 16;
434 }
435 }
436
437 if (channels > 1)
438 {
439 if (size < 8)
440 return FALSE;
441 for (size_t i = 0; i < 8; i++)
442 {
443 BYTE* dst = Stream_Pointer(out);
444
445 const unsigned channel = (i < 4 ? 0 : 1);
446 {
447 const BYTE sample = ((*src) & 0x0f);
448 const UINT16 decoded =
449 dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
450 dst[((i & 3) << 3) + (channel << 1u)] = (decoded & 0xFF);
451 dst[((i & 3) << 3) + (channel << 1u) + 1] = (decoded >> 8);
452 }
453 {
454 const BYTE sample = ((*src) >> 4);
455 const UINT16 decoded =
456 dsp_decode_ima_adpcm_sample(&context->adpcm, channel, sample);
457 dst[((i & 3) << 3) + (channel << 1u) + 4] = (decoded & 0xFF);
458 dst[((i & 3) << 3) + (channel << 1u) + 5] = (decoded >> 8);
459 }
460 src++;
461 }
462
463 if (!Stream_SafeSeek(out, 32))
464 return FALSE;
465 size -= 8;
466 }
467 else
468 {
469 if (size < 1)
470 return FALSE;
471 BYTE* dst = Stream_Pointer(out);
472 if (!Stream_SafeSeek(out, 4))
473 return FALSE;
474
475 {
476 const BYTE sample = ((*src) & 0x0f);
477 const UINT16 decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
478 *dst++ = (decoded & 0xFF);
479 *dst++ = (decoded >> 8);
480 }
481 {
482 const BYTE sample = ((*src) >> 4);
483 const UINT16 decoded = dsp_decode_ima_adpcm_sample(&context->adpcm, 0, sample);
484 *dst++ = (decoded & 0xFF);
485 *dst++ = (decoded >> 8);
486 }
487 src++;
488 size--;
489 }
490 }
491
492 return TRUE;
493}
494
495#if defined(WITH_GSM)
496static BOOL freerdp_dsp_decode_gsm610(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
497 const BYTE* WINPR_RESTRICT src, size_t size,
498 wStream* WINPR_RESTRICT out)
499{
500 size_t offset = 0;
501
502 while (offset < size)
503 {
504 int rc;
505 gsm_signal gsmBlockBuffer[160] = WINPR_C_ARRAY_INIT;
506 rc = gsm_decode(context->gsm, (gsm_byte*)/* API does not modify */ &src[offset],
507 gsmBlockBuffer);
508
509 if (rc < 0)
510 return FALSE;
511
512 if ((offset % 65) == 0)
513 offset += 33;
514 else
515 offset += 32;
516
517 if (!Stream_EnsureRemainingCapacity(out, sizeof(gsmBlockBuffer)))
518 return FALSE;
519
520 Stream_Write(out, (void*)gsmBlockBuffer, sizeof(gsmBlockBuffer));
521 }
522
523 return TRUE;
524}
525
526static BOOL freerdp_dsp_encode_gsm610(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
527 const BYTE* WINPR_RESTRICT src, size_t size,
528 wStream* WINPR_RESTRICT out)
529{
530 size_t offset = 0;
531
532 while (offset < size)
533 {
534 const gsm_signal* signal = (const gsm_signal*)&src[offset];
535
536 if (!Stream_EnsureRemainingCapacity(out, sizeof(gsm_frame)))
537 return FALSE;
538
539 gsm_encode(context->gsm, (gsm_signal*)/* API does not modify */ signal,
540 Stream_Pointer(out));
541
542 if ((offset % 65) == 0)
543 Stream_Seek(out, 33);
544 else
545 Stream_Seek(out, 32);
546
547 offset += 160;
548 }
549
550 return TRUE;
551}
552#endif
553
554#if defined(WITH_LAME)
555static BOOL valid_mp3_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
556{
557 WINPR_ASSERT(context);
558 if (context->common.format.wFormatTag != WAVE_FORMAT_MPEGLAYER3)
559 return FALSE;
560 if (context->common.format.nChannels < 1)
561 return FALSE;
562 if (context->common.format.wBitsPerSample == 0)
563 return FALSE;
564 if (context->common.format.nSamplesPerSec == 0)
565 return FALSE;
566 return TRUE;
567}
568
569static BOOL freerdp_dsp_decode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
570 const BYTE* WINPR_RESTRICT src, size_t size,
571 wStream* WINPR_RESTRICT out)
572{
573 if (!context || !src || !out)
574 return FALSE;
575 if (!valid_mp3_format(context))
576 return FALSE;
577 const size_t buffer_size =
578 2 * context->common.format.nChannels * context->common.format.nSamplesPerSec;
579
580 if (!Stream_EnsureCapacity(context->common.buffer, 2 * buffer_size))
581 return FALSE;
582
583 short* pcm_l = Stream_BufferAs(context->common.buffer, short);
584 short* pcm_r = Stream_BufferAs(context->common.buffer, short) + buffer_size;
585 const int rc = hip_decode(context->hip, (unsigned char*)/* API is not modifying content */ src,
586 size, pcm_l, pcm_r);
587
588 if (rc <= 0)
589 return FALSE;
590
591 if (!Stream_EnsureRemainingCapacity(out, (size_t)rc * context->common.format.nChannels * 2))
592 return FALSE;
593
594 for (size_t x = 0; x < rc; x++)
595 {
596 Stream_Write_UINT16(out, (UINT16)pcm_l[x]);
597 Stream_Write_UINT16(out, (UINT16)pcm_r[x]);
598 }
599
600 return TRUE;
601}
602
603static BOOL freerdp_dsp_encode_mp3(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
604 const BYTE* WINPR_RESTRICT src, size_t size,
605 wStream* WINPR_RESTRICT out)
606{
607 if (!context || !src || !out)
608 return FALSE;
609
610 if (!valid_mp3_format(context))
611 return FALSE;
612
613 size_t samples_per_channel =
614 size / context->common.format.nChannels / context->common.format.wBitsPerSample / 8;
615
616 /* Ensure worst case buffer size for mp3 stream taken from LAME header */
617 if (!Stream_EnsureRemainingCapacity(out, 5 / 4 * samples_per_channel + 7200))
618 return FALSE;
619
620 samples_per_channel = size / 2 /* size of a sample */ / context->common.format.nChannels;
621 const int rc =
622 lame_encode_buffer_interleaved(context->lame, (short*)src, samples_per_channel,
623 Stream_Pointer(out), Stream_GetRemainingCapacity(out));
624
625 if (rc < 0)
626 return FALSE;
627
628 Stream_Seek(out, (size_t)rc);
629 return TRUE;
630}
631#endif
632
633#if defined(WITH_FAAC)
634static BOOL freerdp_dsp_encode_faac(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
635 const BYTE* WINPR_RESTRICT src, size_t size,
636 wStream* WINPR_RESTRICT out)
637{
638 const int16_t* inSamples = (const int16_t*)src;
639 unsigned int bpp;
640 size_t nrSamples;
641 int rc;
642
643 if (!context || !src || !out)
644 return FALSE;
645
646 bpp = context->common.format.wBitsPerSample / 8;
647 nrSamples = size / bpp;
648
649 if (!Stream_EnsureRemainingCapacity(context->common.buffer, nrSamples * sizeof(int16_t)))
650 return FALSE;
651
652 for (size_t x = 0; x < nrSamples; x++)
653 {
654 Stream_Write_INT16(context->common.buffer, inSamples[x]);
655 if (Stream_GetPosition(context->common.buffer) / bpp >= context->faacInputSamples)
656 {
657 if (!Stream_EnsureRemainingCapacity(out, context->faacMaxOutputBytes))
658 return FALSE;
659 rc = faacEncEncode(context->faac, Stream_BufferAs(context->common.buffer, int32_t),
660 context->faacInputSamples, Stream_Pointer(out),
661 Stream_GetRemainingCapacity(out));
662 if (rc < 0)
663 return FALSE;
664 if (rc > 0)
665 Stream_Seek(out, (size_t)rc);
666 Stream_ResetPosition(context->common.buffer);
667 }
668 }
669
670 return TRUE;
671}
672#endif
673
674#if defined(WITH_OPUS)
675static BOOL freerdp_dsp_decode_opus(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
676 const BYTE* WINPR_RESTRICT src, size_t size,
677 wStream* WINPR_RESTRICT out)
678{
679 if (!context || !src || !out)
680 return FALSE;
681
682 /* Max packet duration is 120ms (5760 at 48KHz) */
683 const size_t max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
684 if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
685 return FALSE;
686
687 const opus_int32 frames =
688 opus_decode(context->opus_decoder, src, WINPR_ASSERTING_INT_CAST(opus_int32, size),
689 Stream_Pointer(out), OPUS_MAX_FRAMES, 0);
690 if (frames < 0)
691 return FALSE;
692
693 Stream_Seek(out, (size_t)frames * context->common.format.nChannels * sizeof(int16_t));
694
695 return TRUE;
696}
697
698static BOOL freerdp_dsp_encode_opus(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
699 const BYTE* WINPR_RESTRICT src, size_t size,
700 wStream* WINPR_RESTRICT out)
701{
702 if (!context || !src || !out)
703 return FALSE;
704
705 /* Max packet duration is 120ms (5760 at 48KHz) */
706 const size_t max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
707 if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
708 return FALSE;
709
710 const size_t src_frames = size / sizeof(opus_int16) / context->common.format.nChannels;
711 const opus_int16* src_data = (const opus_int16*)src;
712 const opus_int32 frames = opus_encode(
713 context->opus_encoder, src_data, WINPR_ASSERTING_INT_CAST(opus_int32, src_frames),
714 Stream_Pointer(out), WINPR_ASSERTING_INT_CAST(opus_int32, max_size));
715 if (frames < 0)
716 return FALSE;
717 return Stream_SafeSeek(out,
718 (size_t)frames * context->common.format.nChannels * sizeof(int16_t));
719}
720#endif
721
722#if defined(WITH_FAAD2)
723static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
724 const BYTE* WINPR_RESTRICT src, size_t size,
725 wStream* WINPR_RESTRICT out)
726{
727 NeAACDecFrameInfo info;
728 size_t offset = 0;
729
730 if (!context || !src || !out)
731 return FALSE;
732
733 if (!context->faadSetup)
734 {
735 union
736 {
737 const void* cpv;
738 void* pv;
739 } cnv;
740 unsigned long samplerate;
741 unsigned char channels;
742 long err;
743 cnv.cpv = src;
744 err = NeAACDecInit(context->faad, /* API is not modifying content */ cnv.pv, size,
745 &samplerate, &channels);
746
747 if (err != 0)
748 return FALSE;
749
750 if (channels != context->common.format.nChannels)
751 return FALSE;
752
753 if (samplerate != context->common.format.nSamplesPerSec)
754 return FALSE;
755
756 context->faadSetup = TRUE;
757 }
758
759 while (offset < size)
760 {
761 union
762 {
763 const void* cpv;
764 void* pv;
765 } cnv;
766 size_t outSize;
767 void* sample_buffer;
768 outSize = context->common.format.nSamplesPerSec * context->common.format.nChannels *
769 context->common.format.wBitsPerSample / 8;
770
771 if (!Stream_EnsureRemainingCapacity(out, outSize))
772 return FALSE;
773
774 sample_buffer = Stream_Pointer(out);
775
776 cnv.cpv = &src[offset];
777 NeAACDecDecode2(context->faad, &info, cnv.pv, size - offset, &sample_buffer,
778 Stream_GetRemainingCapacity(out));
779
780 if (info.error != 0)
781 return FALSE;
782
783 offset += info.bytesconsumed;
784
785 if (info.samples == 0)
786 continue;
787
788 Stream_Seek(out, info.samples * context->common.format.wBitsPerSample / 8);
789 }
790
791 return TRUE;
792}
793
794#endif
795
803static const struct
804{
805 BYTE byte_num;
806 BYTE byte_shift;
807} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
808 { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
809 { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
810
811static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, size_t channel, INT16 sample)
812{
813 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
814 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
815
816 const INT16 offset = adpcm->ima.last_step[channel];
817 WINPR_ASSERT(offset >= 0);
818 WINPR_ASSERT(WINPR_CXX_COMPAT_CAST(size_t, offset) < ARRAYSIZE(ima_step_size_table));
819
820 INT32 ss = ima_step_size_table[offset];
821 INT32 e = sample - adpcm->ima.last_sample[channel];
822 INT32 d = e;
823 INT32 diff = ss >> 3;
824 BYTE enc = 0;
825
826 if (e < 0)
827 {
828 enc = 8;
829 e = -e;
830 }
831
832 if (e >= ss)
833 {
834 enc |= 4;
835 e -= ss;
836 }
837
838 ss >>= 1;
839
840 if (e >= ss)
841 {
842 enc |= 2;
843 e -= ss;
844 }
845
846 ss >>= 1;
847
848 if (e >= ss)
849 {
850 enc |= 1;
851 e -= ss;
852 }
853
854 if (d < 0)
855 diff = d + e - diff;
856 else
857 diff = d - e + diff;
858
859 diff += adpcm->ima.last_sample[channel];
860
861 if (diff < -32768)
862 diff = -32768;
863 else if (diff > 32767)
864 diff = 32767;
865
866 adpcm->ima.last_sample[channel] = (INT16)diff;
867
868 WINPR_ASSERT(enc < ARRAYSIZE(ima_step_index_table));
869 const int32_t last = adpcm->ima.last_step[channel] + ima_step_index_table[enc];
870 adpcm->ima.last_step[channel] = WINPR_ASSERTING_INT_CAST(int16_t, last);
871
872 dsp_ima_clamp_step(adpcm, channel);
873
874 return enc;
875}
876
877static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
878 const BYTE* WINPR_RESTRICT src, size_t size,
879 wStream* WINPR_RESTRICT out)
880{
881 if (!valid_ima_adpcm_format(context))
882 return FALSE;
883 if (!Stream_EnsureRemainingCapacity(out, size))
884 return FALSE;
885 if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
886 return FALSE;
887
888 const size_t align = (context->common.format.nChannels > 1) ? 32 : 4;
889
890 while (size >= align)
891 {
892 if (Stream_GetPosition(context->common.buffer) % context->common.format.nBlockAlign == 0)
893 {
894 Stream_Write_UINT8(context->common.buffer, context->adpcm.ima.last_sample[0] & 0xFF);
895 Stream_Write_UINT8(context->common.buffer,
896 (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
897 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[0]);
898 Stream_Write_UINT8(context->common.buffer, 0);
899
900 if (context->common.format.nChannels > 1)
901 {
902 Stream_Write_UINT8(context->common.buffer,
903 context->adpcm.ima.last_sample[1] & 0xFF);
904 Stream_Write_UINT8(context->common.buffer,
905 (context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
906 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[1]);
907 Stream_Write_UINT8(context->common.buffer, 0);
908 }
909 }
910
911 if (context->common.format.nChannels > 1)
912 {
913 BYTE* dst = Stream_Pointer(context->common.buffer);
914 ZeroMemory(dst, 8);
915
916 for (size_t i = 0; i < 16; i++)
917 {
918 const INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
919 src += 2;
920 const BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
921 dst[ima_stereo_encode_map[i].byte_num] |= encoded
922 << ima_stereo_encode_map[i].byte_shift;
923 }
924
925 if (!Stream_SafeSeek(context->common.buffer, 8))
926 return FALSE;
927 size -= 32;
928 }
929 else
930 {
931 INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
932 src += 2;
933 BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
934 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
935 src += 2;
936 encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
937 Stream_Write_UINT8(context->common.buffer, encoded);
938 size -= 4;
939 }
940
941 if (Stream_GetPosition(context->common.buffer) >= context->adpcm.ima.packet_size)
942 {
943 BYTE* bsrc = Stream_Buffer(context->common.buffer);
944 Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
945 Stream_ResetPosition(context->common.buffer);
946 }
947 }
948
949 return TRUE;
950}
951
958static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
959 768, 614, 512, 409, 307, 230, 230, 230 };
960
961static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
962
963static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
964
965static inline INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
966 size_t channel)
967{
968 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
969 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
970 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
971 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
972
973 const INT8 nibble = (INT8)((sample & 0x08) ? (sample - 16) : sample);
974 const BYTE predictor = adpcm->ms.predictor[channel];
975 INT32 coeff1 = 0;
976 if (predictor < ARRAYSIZE(ms_adpcm_coeffs1))
977 coeff1 = ms_adpcm_coeffs1[predictor];
978
979 INT32 coeff2 = 0;
980 if (predictor < ARRAYSIZE(ms_adpcm_coeffs2))
981 coeff2 = ms_adpcm_coeffs2[predictor];
982 INT32 presample =
983 ((adpcm->ms.sample1[channel] * coeff1) + (adpcm->ms.sample2[channel] * coeff2)) / 256;
984 presample += nibble * adpcm->ms.delta[channel];
985
986 if (presample > 32767)
987 presample = 32767;
988 else if (presample < -32768)
989 presample = -32768;
990
991 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
992 adpcm->ms.sample1[channel] = presample;
993
994 INT32 tableval = 0;
995 if (sample < ARRAYSIZE(ms_adpcm_adaptation_table))
996 tableval = ms_adpcm_adaptation_table[sample];
997
998 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * tableval / 256;
999
1000 if (adpcm->ms.delta[channel] < 16)
1001 adpcm->ms.delta[channel] = 16;
1002
1003 return (INT16)presample;
1004}
1005
1006static BOOL valid_ms_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
1007{
1008 WINPR_ASSERT(context);
1009 if (context->common.format.wFormatTag != WAVE_FORMAT_ADPCM)
1010 return FALSE;
1011 if (context->common.format.nBlockAlign <= 4ULL)
1012 return FALSE;
1013 if (context->common.format.nChannels < 1)
1014 return FALSE;
1015 if (context->common.format.wBitsPerSample == 0)
1016 return FALSE;
1017 return TRUE;
1018}
1019
1020static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1021 const BYTE* WINPR_RESTRICT src, size_t size,
1022 wStream* WINPR_RESTRICT out)
1023{
1024 if (!valid_ms_adpcm_format(context))
1025 return FALSE;
1026 const size_t out_size = size * 4;
1027 const UINT32 channels = context->common.format.nChannels;
1028 const UINT32 block_size = context->common.format.nBlockAlign;
1029
1030 if (!Stream_EnsureCapacity(out, out_size))
1031 return FALSE;
1032
1033 while (size > 0)
1034 {
1035 if (size % block_size == 0)
1036 {
1037 if (channels > 1)
1038 {
1039 if (size < 14)
1040 return FALSE;
1041
1042 context->adpcm.ms.predictor[0] = *src++;
1043 context->adpcm.ms.predictor[1] = *src++;
1044 context->adpcm.ms.delta[0] = read_int16(src);
1045 src += 2;
1046 context->adpcm.ms.delta[1] = read_int16(src);
1047 src += 2;
1048 context->adpcm.ms.sample1[0] = read_int16(src);
1049 src += 2;
1050 context->adpcm.ms.sample1[1] = read_int16(src);
1051 src += 2;
1052 context->adpcm.ms.sample2[0] = read_int16(src);
1053 src += 2;
1054 context->adpcm.ms.sample2[1] = read_int16(src);
1055 src += 2;
1056 size -= 14;
1057 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1058 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1059 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1060 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1061 }
1062 else
1063 {
1064 if (size < 7)
1065 return FALSE;
1066
1067 context->adpcm.ms.predictor[0] = *src++;
1068 context->adpcm.ms.delta[0] = read_int16(src);
1069 src += 2;
1070 context->adpcm.ms.sample1[0] = read_int16(src);
1071 src += 2;
1072 context->adpcm.ms.sample2[0] = read_int16(src);
1073 src += 2;
1074 size -= 7;
1075 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1076 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1077 }
1078 }
1079
1080 if (channels > 1)
1081 {
1082 {
1083 if (size < 1)
1084 return FALSE;
1085 const BYTE sample = *src++;
1086 size--;
1087 Stream_Write_INT16(
1088 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1089 Stream_Write_INT16(
1090 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1091 }
1092 {
1093 if (size < 1)
1094 return FALSE;
1095 const BYTE sample = *src++;
1096 size--;
1097 Stream_Write_INT16(
1098 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1099 Stream_Write_INT16(
1100 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1101 }
1102 }
1103 else
1104 {
1105 if (size < 1)
1106 return FALSE;
1107 const BYTE sample = *src++;
1108 size--;
1109 Stream_Write_INT16(out,
1110 freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1111 Stream_Write_INT16(
1112 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
1113 }
1114 }
1115
1116 return TRUE;
1117}
1118
1119static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
1120 size_t channel)
1121{
1122 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
1123 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
1124 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
1125 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
1126
1127 INT32 presample =
1128 ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
1129 (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
1130 256;
1131 INT32 errordelta = (sample - presample) / adpcm->ms.delta[channel];
1132
1133 if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
1134 errordelta++;
1135
1136 if (errordelta > 7)
1137 errordelta = 7;
1138 else if (errordelta < -8)
1139 errordelta = -8;
1140
1141 presample += adpcm->ms.delta[channel] * errordelta;
1142
1143 if (presample > 32767)
1144 presample = 32767;
1145 else if (presample < -32768)
1146 presample = -32768;
1147
1148 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
1149 adpcm->ms.sample1[channel] = presample;
1150 const size_t offset = (((BYTE)errordelta) & 0x0F);
1151 WINPR_ASSERT(offset < ARRAYSIZE(ms_adpcm_adaptation_table));
1152 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[offset] / 256;
1153
1154 if (adpcm->ms.delta[channel] < 16)
1155 adpcm->ms.delta[channel] = 16;
1156
1157 return ((BYTE)errordelta) & 0x0F;
1158}
1159
1160static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1161 const BYTE* WINPR_RESTRICT src, size_t size,
1162 wStream* WINPR_RESTRICT out)
1163{
1164 if (!valid_ms_adpcm_format(context))
1165 return FALSE;
1166
1167 const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
1168
1169 if (!Stream_EnsureRemainingCapacity(out, size))
1170 return FALSE;
1171
1172 const size_t start = Stream_GetPosition(out);
1173
1174 if (context->adpcm.ms.delta[0] < 16)
1175 context->adpcm.ms.delta[0] = 16;
1176
1177 if (context->adpcm.ms.delta[1] < 16)
1178 context->adpcm.ms.delta[1] = 16;
1179
1180 while (size >= step)
1181 {
1182 if ((Stream_GetPosition(out) - start) % context->common.format.nBlockAlign == 0)
1183 {
1184 if (context->common.format.nChannels > 1)
1185 {
1186 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1187 Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
1188 Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
1189 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1190 Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
1191 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
1192
1193 context->adpcm.ms.sample1[0] = read_int16(src + 4);
1194 context->adpcm.ms.sample1[1] = read_int16(src + 6);
1195 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1196 context->adpcm.ms.sample2[1] = read_int16(src + 2);
1197
1198 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1199 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1200 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1201 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1202
1203 src += 8;
1204 size -= 8;
1205 }
1206 else
1207 {
1208 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1209 Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
1210 Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1211
1212 context->adpcm.ms.sample1[0] = read_int16(src + 2);
1213 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1214
1215 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1216 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1217 src += 4;
1218 size -= 4;
1219 }
1220 }
1221
1222 {
1223 const INT16 sample = read_int16(src);
1224 src += 2;
1225 Stream_Write_UINT8(
1226 out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
1227 }
1228 {
1229 const INT16 sample = read_int16(src);
1230 src += 2;
1231
1232 BYTE val = 0;
1233 Stream_Read_UINT8(out, val);
1234 val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1235 context->common.format.nChannels > 1 ? 1 : 0);
1236 Stream_Write_UINT8(out, val);
1237 }
1238 size -= 4;
1239 }
1240
1241 return TRUE;
1242}
1243
1244#endif
1245
1246FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1247{
1248#if defined(WITH_DSP_FFMPEG)
1249 return freerdp_dsp_ffmpeg_context_new(encoder);
1250#else
1251 FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1252
1253 if (!context)
1254 return nullptr;
1255
1256 if (!freerdp_dsp_common_context_init(&context->common, encoder))
1257 goto fail;
1258
1259#if defined(WITH_GSM)
1260 context->gsm = gsm_create();
1261
1262 if (!context->gsm)
1263 goto fail;
1264
1265 {
1266 int rc;
1267 int val = 1;
1268 rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1269
1270 if (rc < 0)
1271 goto fail;
1272 }
1273#endif
1274#if defined(WITH_LAME)
1275
1276 if (encoder)
1277 {
1278 context->lame = lame_init();
1279
1280 if (!context->lame)
1281 goto fail;
1282 }
1283 else
1284 {
1285 context->hip = hip_decode_init();
1286
1287 if (!context->hip)
1288 goto fail;
1289 }
1290
1291#endif
1292#if defined(WITH_FAAD2)
1293
1294 if (!encoder)
1295 {
1296 context->faad = NeAACDecOpen();
1297
1298 if (!context->faad)
1299 goto fail;
1300 }
1301
1302#endif
1303 return context;
1304fail:
1305 freerdp_dsp_context_free(context);
1306 return nullptr;
1307#endif
1308}
1309
1310void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1311{
1312 if (!context)
1313 return;
1314
1315#if defined(WITH_FDK_AAC)
1317 WINPR_ASSERT(ctx);
1318 fdk_aac_dsp_uninit(ctx);
1319#endif
1320
1321#if defined(WITH_DSP_FFMPEG)
1322 freerdp_dsp_ffmpeg_context_free(context);
1323#else
1324
1325 freerdp_dsp_common_context_uninit(&context->common);
1326
1327#if defined(WITH_GSM)
1328 gsm_destroy(context->gsm);
1329#endif
1330#if defined(WITH_LAME)
1331
1332 if (context->common.encoder)
1333 lame_close(context->lame);
1334 else
1335 hip_decode_exit(context->hip);
1336
1337#endif
1338#if defined(WITH_OPUS)
1339
1340 if (context->opus_decoder)
1341 opus_decoder_destroy(context->opus_decoder);
1342 if (context->opus_encoder)
1343 opus_encoder_destroy(context->opus_encoder);
1344
1345#endif
1346#if defined(WITH_FAAD2)
1347
1348 if (!context->common.encoder)
1349 NeAACDecClose(context->faad);
1350
1351#endif
1352#if defined(WITH_FAAC)
1353
1354 if (context->faac)
1355 faacEncClose(context->faac);
1356
1357#endif
1358#if defined(WITH_SOXR)
1359 soxr_delete(context->sox);
1360#endif
1361 free(context);
1362
1363#endif
1364}
1365
1366BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1367 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1368 const BYTE* WINPR_RESTRICT pdata, size_t length,
1369 wStream* WINPR_RESTRICT out)
1370{
1371#if defined(WITH_FDK_AAC)
1373 WINPR_ASSERT(ctx);
1374 switch (ctx->format.wFormatTag)
1375 {
1376 case WAVE_FORMAT_AAC_MS:
1377 return fdk_aac_dsp_encode(ctx, srcFormat, pdata, length, out);
1378 default:
1379 break;
1380 }
1381#endif
1382
1383#if defined(WITH_DSP_FFMPEG)
1384 return freerdp_dsp_ffmpeg_encode(context, srcFormat, pdata, length, out);
1385#else
1386 if (!context || !context->common.encoder || !srcFormat || !pdata || !out)
1387 return FALSE;
1388
1389 AUDIO_FORMAT format = *srcFormat;
1390 const BYTE* resampleData = nullptr;
1391 size_t resampleLength = 0;
1392
1393 if (!freerdp_dsp_channel_mix(context, pdata, length, srcFormat, &resampleData, &resampleLength))
1394 return FALSE;
1395
1396 format.nChannels = context->common.format.nChannels;
1397
1398 const BYTE* data = nullptr;
1399 if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1400 return FALSE;
1401
1402 switch (context->common.format.wFormatTag)
1403 {
1404 case WAVE_FORMAT_PCM:
1405 if (!Stream_EnsureRemainingCapacity(out, length))
1406 return FALSE;
1407
1408 Stream_Write(out, data, length);
1409 return TRUE;
1410
1411 case WAVE_FORMAT_ADPCM:
1412 return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1413
1414 case WAVE_FORMAT_DVI_ADPCM:
1415 return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1416#if defined(WITH_GSM)
1417
1418 case WAVE_FORMAT_GSM610:
1419 return freerdp_dsp_encode_gsm610(context, data, length, out);
1420#endif
1421#if defined(WITH_LAME)
1422
1423 case WAVE_FORMAT_MPEGLAYER3:
1424 return freerdp_dsp_encode_mp3(context, data, length, out);
1425#endif
1426#if defined(WITH_FAAC)
1427
1428 case WAVE_FORMAT_AAC_MS:
1429 return freerdp_dsp_encode_faac(context, data, length, out);
1430#endif
1431#if defined(WITH_OPUS)
1432
1433 case WAVE_FORMAT_OPUS:
1434 return freerdp_dsp_encode_opus(context, data, length, out);
1435#endif
1436 default:
1437 return FALSE;
1438 }
1439
1440 return FALSE;
1441#endif
1442}
1443
1444BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1445 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1446 const BYTE* WINPR_RESTRICT data, size_t length, wStream* WINPR_RESTRICT out)
1447{
1448#if defined(WITH_FDK_AAC)
1450 WINPR_ASSERT(ctx);
1451 switch (ctx->format.wFormatTag)
1452 {
1453 case WAVE_FORMAT_AAC_MS:
1454 return fdk_aac_dsp_decode(ctx, srcFormat, data, length, out);
1455 default:
1456 break;
1457 }
1458#endif
1459
1460#if defined(WITH_DSP_FFMPEG)
1461 return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1462#else
1463
1464 if (!context || context->common.encoder || !srcFormat || !data || !out)
1465 return FALSE;
1466
1467 switch (context->common.format.wFormatTag)
1468 {
1469 case WAVE_FORMAT_PCM:
1470 if (!Stream_EnsureRemainingCapacity(out, length))
1471 return FALSE;
1472
1473 Stream_Write(out, data, length);
1474 return TRUE;
1475
1476 case WAVE_FORMAT_ADPCM:
1477 return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1478
1479 case WAVE_FORMAT_DVI_ADPCM:
1480 return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1481#if defined(WITH_GSM)
1482
1483 case WAVE_FORMAT_GSM610:
1484 return freerdp_dsp_decode_gsm610(context, data, length, out);
1485#endif
1486#if defined(WITH_LAME)
1487
1488 case WAVE_FORMAT_MPEGLAYER3:
1489 return freerdp_dsp_decode_mp3(context, data, length, out);
1490#endif
1491#if defined(WITH_FAAD2)
1492
1493 case WAVE_FORMAT_AAC_MS:
1494 return freerdp_dsp_decode_faad(context, data, length, out);
1495#endif
1496
1497#if defined(WITH_OPUS)
1498 case WAVE_FORMAT_OPUS:
1499 return freerdp_dsp_decode_opus(context, data, length, out);
1500#endif
1501 default:
1502 return FALSE;
1503 }
1504
1505 return FALSE;
1506#endif
1507}
1508
1509BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* WINPR_RESTRICT format, BOOL encode)
1510{
1511#if defined(WITH_FDK_AAC)
1512 switch (format->wFormatTag)
1513 {
1514 case WAVE_FORMAT_AAC_MS:
1515 return TRUE;
1516 default:
1517 break;
1518 }
1519
1520#endif
1521
1522#if defined(WITH_DSP_FFMPEG)
1523 return freerdp_dsp_ffmpeg_supports_format(format, encode);
1524#else
1525
1526#if !defined(WITH_DSP_EXPERIMENTAL)
1527 WINPR_UNUSED(encode);
1528#endif
1529 switch (format->wFormatTag)
1530 {
1531 case WAVE_FORMAT_PCM:
1532 return TRUE;
1533#if defined(WITH_DSP_EXPERIMENTAL)
1534
1535 case WAVE_FORMAT_ADPCM:
1536 return FALSE;
1537 case WAVE_FORMAT_DVI_ADPCM:
1538 return TRUE;
1539#endif
1540#if defined(WITH_GSM)
1541
1542 case WAVE_FORMAT_GSM610:
1543#if defined(WITH_DSP_EXPERIMENTAL)
1544 return TRUE;
1545#else
1546 return !encode;
1547#endif
1548#endif
1549#if defined(WITH_LAME)
1550
1551 case WAVE_FORMAT_MPEGLAYER3:
1552#if defined(WITH_DSP_EXPERIMENTAL)
1553 return TRUE;
1554#else
1555 return !encode;
1556#endif
1557#endif
1558
1559 case WAVE_FORMAT_AAC_MS:
1560#if defined(WITH_FAAD2)
1561 if (!encode)
1562 return TRUE;
1563
1564#endif
1565#if defined(WITH_FAAC)
1566
1567 if (encode)
1568 return TRUE;
1569
1570#endif
1571#if defined(WITH_FDK_AAC)
1572 return TRUE;
1573#else
1574 return FALSE;
1575#endif
1576
1577#if defined(WITH_OPUS)
1578 case WAVE_FORMAT_OPUS:
1579 return opus_is_valid_samplerate(format);
1580#endif
1581 default:
1582 return FALSE;
1583 }
1584
1585 return FALSE;
1586#endif
1587}
1588
1589BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1590 const AUDIO_FORMAT* WINPR_RESTRICT targetFormat,
1591 WINPR_ATTR_UNUSED UINT32 FramesPerPacket)
1592{
1593#if defined(WITH_FDK_AAC)
1594 WINPR_ASSERT(targetFormat);
1595 if (targetFormat->wFormatTag == WAVE_FORMAT_AAC_MS)
1596 {
1598 fdk_aac_dsp_uninit(ctx);
1599 ctx->format = *targetFormat;
1600 return fdk_aac_dsp_init(ctx, FramesPerPacket);
1601 }
1602#endif
1603
1604#if defined(WITH_DSP_FFMPEG)
1605 return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1606#else
1607
1608 if (!context || !targetFormat)
1609 return FALSE;
1610
1611 context->common.format = *targetFormat;
1612
1613 switch (context->common.format.wFormatTag)
1614 {
1615#if defined(WITH_LAME)
1616 case WAVE_FORMAT_MPEGLAYER3:
1617 if (!valid_mp3_format(context))
1618 return FALSE;
1619 break;
1620#endif
1621 case WAVE_FORMAT_ADPCM:
1622 if (!valid_ms_adpcm_format(context))
1623 return FALSE;
1624 break;
1625 case WAVE_FORMAT_DVI_ADPCM:
1626 {
1627 if (!valid_ima_adpcm_format(context))
1628 return FALSE;
1629 if (FramesPerPacket == 0)
1630 return FALSE;
1631
1632 const size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
1633 context->common.format.nChannels * FramesPerPacket;
1634 const size_t data_per_block = (1ULL * context->common.format.nBlockAlign -
1635 4ULL * context->common.format.nChannels) *
1636 8ULL;
1637 size_t nb_block_per_packet = min_frame_data / data_per_block;
1638
1639 if (min_frame_data % data_per_block)
1640 nb_block_per_packet++;
1641
1642 context->adpcm.ima.packet_size =
1643 nb_block_per_packet * context->common.format.nBlockAlign;
1644 if (!Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size))
1645 return FALSE;
1646 Stream_ResetPosition(context->common.buffer);
1647 }
1648 break;
1649 default:
1650 break;
1651 }
1652
1653#if defined(WITH_OPUS)
1654
1655 if (opus_is_valid_samplerate(&context->common.format))
1656 {
1657 if (!context->common.encoder)
1658 {
1659 int opus_error = OPUS_OK;
1660
1661 context->opus_decoder = opus_decoder_create(
1662 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1663 context->common.format.nChannels, &opus_error);
1664 if (opus_error != OPUS_OK)
1665 return FALSE;
1666 }
1667 else
1668 {
1669 int opus_error = OPUS_OK;
1670
1671 context->opus_encoder = opus_encoder_create(
1672 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1673 context->common.format.nChannels, OPUS_APPLICATION_VOIP, &opus_error);
1674 if (opus_error != OPUS_OK)
1675 return FALSE;
1676
1677 opus_error =
1678 opus_encoder_ctl(context->opus_encoder,
1679 OPUS_SET_BITRATE(context->common.format.nAvgBytesPerSec * 8));
1680 if (opus_error != OPUS_OK)
1681 return FALSE;
1682 }
1683 }
1684
1685#endif
1686#if defined(WITH_FAAD2)
1687 context->faadSetup = FALSE;
1688#endif
1689#if defined(WITH_FAAC)
1690
1691 if (context->common.encoder)
1692 {
1693 faacEncConfigurationPtr cfg = nullptr;
1694
1695 if (context->faac)
1696 faacEncClose(context->faac);
1697
1698 context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1699 &context->faacInputSamples, &context->faacMaxOutputBytes);
1700
1701 if (!context->faac)
1702 return FALSE;
1703
1704 cfg = faacEncGetCurrentConfiguration(context->faac);
1705 cfg->inputFormat = FAAC_INPUT_16BIT;
1706 cfg->outputFormat = 0;
1707 cfg->mpegVersion = MPEG4;
1708 cfg->useTns = 1;
1709 cfg->bandWidth = targetFormat->nAvgBytesPerSec;
1710 const int rc = faacEncSetConfiguration(context->faac, cfg);
1711 if (rc <= 0)
1712 return FALSE;
1713 }
1714
1715#endif
1716#if defined(WITH_SOXR)
1717 {
1718 soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1719 soxr_error_t error = nullptr;
1720
1721 soxr_delete(context->sox);
1722 context->sox =
1723 soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1724 targetFormat->nChannels, &error, &iospec, nullptr, nullptr);
1725
1726 if (!context->sox || (error != nullptr))
1727 return FALSE;
1728 }
1729#endif
1730 return TRUE;
1731#endif
1732}
1733
1734BOOL freerdp_dsp_common_context_init(FREERDP_DSP_COMMON_CONTEXT* context, BOOL encode)
1735{
1736 WINPR_ASSERT(context);
1737 context->encoder = encode;
1738 context->buffer = Stream_New(nullptr, 1024);
1739 if (!context->buffer)
1740 goto fail;
1741
1742 context->channelmix = Stream_New(nullptr, 1024);
1743 if (!context->channelmix)
1744 goto fail;
1745
1746 context->resample = Stream_New(nullptr, 1024);
1747 if (!context->resample)
1748 goto fail;
1749
1750 return TRUE;
1751
1752fail:
1753 freerdp_dsp_common_context_uninit(context);
1754 return FALSE;
1755}
1756
1757void freerdp_dsp_common_context_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
1758{
1759 WINPR_ASSERT(context);
1760
1761 Stream_Free(context->buffer, TRUE);
1762 Stream_Free(context->channelmix, TRUE);
1763 Stream_Free(context->resample, TRUE);
1764
1765 context->buffer = nullptr;
1766 context->channelmix = nullptr;
1767 context->resample = nullptr;
1768}