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