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