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 sox_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 == 0) != 0;
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 2 * context->common.format.nChannels * context->common.format.nSamplesPerSec;
573
574 if (!Stream_EnsureCapacity(context->common.buffer, 2 * 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;
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 * 2))
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, 5 / 4 * samples_per_channel + 7200))
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 frames = 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 (frames < 0)
720 return FALSE;
721 return Stream_SafeSeek(out,
722 (size_t)frames * context->common.format.nChannels * sizeof(int16_t));
723}
724#endif
725
726#if defined(WITH_FAAD2)
727static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
728 const BYTE* WINPR_RESTRICT src, size_t size,
729 wStream* WINPR_RESTRICT out)
730{
731 NeAACDecFrameInfo info;
732 size_t offset = 0;
733
734 if (!context || !src || !out)
735 return FALSE;
736
737 if (!context->faadSetup)
738 {
739 union
740 {
741 const void* cpv;
742 void* pv;
743 } cnv;
744 unsigned long samplerate = 0;
745 unsigned char channels = 0;
746
747 cnv.cpv = src;
748 const long err = NeAACDecInit(context->faad, /* API is not modifying content */ cnv.pv,
749 size, &samplerate, &channels);
750
751 if (err != 0)
752 return FALSE;
753
754 if (channels != context->common.format.nChannels)
755 return FALSE;
756
757 if (samplerate != context->common.format.nSamplesPerSec)
758 return FALSE;
759
760 context->faadSetup = TRUE;
761 }
762
763 while (offset < size)
764 {
765 union
766 {
767 const void* cpv;
768 void* pv;
769 } cnv;
770
771 const size_t outSize = context->common.format.nSamplesPerSec *
772 context->common.format.nChannels *
773 context->common.format.wBitsPerSample / 8;
774
775 if (!Stream_EnsureRemainingCapacity(out, outSize))
776 return FALSE;
777
778 void* sample_buffer = Stream_Pointer(out);
779
780 cnv.cpv = &src[offset];
781 NeAACDecDecode2(context->faad, &info, cnv.pv, size - offset, &sample_buffer,
782 Stream_GetRemainingCapacity(out));
783
784 if (info.error != 0)
785 return FALSE;
786
787 offset += info.bytesconsumed;
788
789 if (info.samples == 0)
790 continue;
791
792 Stream_Seek(out, info.samples * context->common.format.wBitsPerSample / 8);
793 }
794
795 return TRUE;
796}
797
798#endif
799
807static const struct
808{
809 BYTE byte_num;
810 BYTE byte_shift;
811} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
812 { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
813 { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
814
815static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, size_t channel, INT16 sample)
816{
817 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_step));
818 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ima.last_sample));
819
820 const INT16 offset = adpcm->ima.last_step[channel];
821 WINPR_ASSERT(offset >= 0);
822 WINPR_ASSERT(WINPR_CXX_COMPAT_CAST(size_t, offset) < ARRAYSIZE(ima_step_size_table));
823
824 INT32 ss = ima_step_size_table[offset];
825 INT32 e = sample - adpcm->ima.last_sample[channel];
826 INT32 d = e;
827 INT32 diff = ss >> 3;
828 BYTE enc = 0;
829
830 if (e < 0)
831 {
832 enc = 8;
833 e = -e;
834 }
835
836 if (e >= ss)
837 {
838 enc |= 4;
839 e -= ss;
840 }
841
842 ss >>= 1;
843
844 if (e >= ss)
845 {
846 enc |= 2;
847 e -= ss;
848 }
849
850 ss >>= 1;
851
852 if (e >= ss)
853 {
854 enc |= 1;
855 e -= ss;
856 }
857
858 if (d < 0)
859 diff = d + e - diff;
860 else
861 diff = d - e + diff;
862
863 diff += adpcm->ima.last_sample[channel];
864
865 if (diff < -32768)
866 diff = -32768;
867 else if (diff > 32767)
868 diff = 32767;
869
870 adpcm->ima.last_sample[channel] = (INT16)diff;
871
872 WINPR_ASSERT(enc < ARRAYSIZE(ima_step_index_table));
873 const int32_t last = adpcm->ima.last_step[channel] + ima_step_index_table[enc];
874 adpcm->ima.last_step[channel] = WINPR_ASSERTING_INT_CAST(int16_t, last);
875
876 dsp_ima_clamp_step(adpcm, channel);
877
878 return enc;
879}
880
881static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
882 const BYTE* WINPR_RESTRICT src, size_t size,
883 wStream* WINPR_RESTRICT out)
884{
885 if (!valid_ima_adpcm_format(context))
886 return FALSE;
887 if (!Stream_EnsureRemainingCapacity(out, size))
888 return FALSE;
889 if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
890 return FALSE;
891
892 const size_t align = (context->common.format.nChannels > 1) ? 32 : 4;
893
894 while (size >= align)
895 {
896 if (Stream_GetPosition(context->common.buffer) % context->common.format.nBlockAlign == 0)
897 {
898 Stream_Write_UINT8(context->common.buffer, context->adpcm.ima.last_sample[0] & 0xFF);
899 Stream_Write_UINT8(context->common.buffer,
900 (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
901 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[0]);
902 Stream_Write_UINT8(context->common.buffer, 0);
903
904 if (context->common.format.nChannels > 1)
905 {
906 Stream_Write_UINT8(context->common.buffer,
907 context->adpcm.ima.last_sample[1] & 0xFF);
908 Stream_Write_UINT8(context->common.buffer,
909 (context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
910 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[1]);
911 Stream_Write_UINT8(context->common.buffer, 0);
912 }
913 }
914
915 if (context->common.format.nChannels > 1)
916 {
917 BYTE* dst = Stream_Pointer(context->common.buffer);
918 ZeroMemory(dst, 8);
919
920 for (size_t i = 0; i < 16; i++)
921 {
922 const INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
923 src += 2;
924 const BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
925 dst[ima_stereo_encode_map[i].byte_num] |= encoded
926 << ima_stereo_encode_map[i].byte_shift;
927 }
928
929 if (!Stream_SafeSeek(context->common.buffer, 8))
930 return FALSE;
931 size -= 32;
932 }
933 else
934 {
935 INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
936 src += 2;
937 BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
938 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
939 src += 2;
940 encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
941 Stream_Write_UINT8(context->common.buffer, encoded);
942 size -= 4;
943 }
944
945 if (Stream_GetPosition(context->common.buffer) >= context->adpcm.ima.packet_size)
946 {
947 BYTE* bsrc = Stream_Buffer(context->common.buffer);
948 Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
949 Stream_ResetPosition(context->common.buffer);
950 }
951 }
952
953 return TRUE;
954}
955
962static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
963 768, 614, 512, 409, 307, 230, 230, 230 };
964
965static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
966
967static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
968
969static inline INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
970 size_t channel)
971{
972 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
973 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
974 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
975 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
976
977 const INT8 nibble = (INT8)((sample & 0x08) ? (sample - 16) : sample);
978 const BYTE predictor = adpcm->ms.predictor[channel];
979 INT32 coeff1 = 0;
980 if (predictor < ARRAYSIZE(ms_adpcm_coeffs1))
981 coeff1 = ms_adpcm_coeffs1[predictor];
982
983 INT32 coeff2 = 0;
984 if (predictor < ARRAYSIZE(ms_adpcm_coeffs2))
985 coeff2 = ms_adpcm_coeffs2[predictor];
986 INT32 presample =
987 ((adpcm->ms.sample1[channel] * coeff1) + (adpcm->ms.sample2[channel] * coeff2)) / 256;
988 presample += nibble * adpcm->ms.delta[channel];
989
990 if (presample > 32767)
991 presample = 32767;
992 else if (presample < -32768)
993 presample = -32768;
994
995 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
996 adpcm->ms.sample1[channel] = presample;
997
998 INT32 tableval = 0;
999 if (sample < ARRAYSIZE(ms_adpcm_adaptation_table))
1000 tableval = ms_adpcm_adaptation_table[sample];
1001
1002 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * tableval / 256;
1003
1004 if (adpcm->ms.delta[channel] < 16)
1005 adpcm->ms.delta[channel] = 16;
1006
1007 return (INT16)presample;
1008}
1009
1010static BOOL valid_ms_adpcm_format(const FREERDP_DSP_CONTEXT* WINPR_RESTRICT context)
1011{
1012 WINPR_ASSERT(context);
1013 if (context->common.format.wFormatTag != WAVE_FORMAT_ADPCM)
1014 return FALSE;
1015 if (context->common.format.nBlockAlign <= 4ULL)
1016 return FALSE;
1017 if (context->common.format.nChannels < 1)
1018 return FALSE;
1019 if (context->common.format.wBitsPerSample == 0)
1020 return FALSE;
1021 return TRUE;
1022}
1023
1024static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1025 const BYTE* WINPR_RESTRICT src, size_t size,
1026 wStream* WINPR_RESTRICT out)
1027{
1028 if (!valid_ms_adpcm_format(context))
1029 return FALSE;
1030 const size_t out_size = size * 4;
1031 const UINT32 channels = context->common.format.nChannels;
1032 const UINT32 block_size = context->common.format.nBlockAlign;
1033
1034 if (!Stream_EnsureCapacity(out, out_size))
1035 return FALSE;
1036
1037 while (size > 0)
1038 {
1039 if (size % block_size == 0)
1040 {
1041 if (channels > 1)
1042 {
1043 if (size < 14)
1044 return FALSE;
1045
1046 context->adpcm.ms.predictor[0] = *src++;
1047 context->adpcm.ms.predictor[1] = *src++;
1048 context->adpcm.ms.delta[0] = read_int16(src);
1049 src += 2;
1050 context->adpcm.ms.delta[1] = read_int16(src);
1051 src += 2;
1052 context->adpcm.ms.sample1[0] = read_int16(src);
1053 src += 2;
1054 context->adpcm.ms.sample1[1] = read_int16(src);
1055 src += 2;
1056 context->adpcm.ms.sample2[0] = read_int16(src);
1057 src += 2;
1058 context->adpcm.ms.sample2[1] = read_int16(src);
1059 src += 2;
1060 size -= 14;
1061 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1062 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1063 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1064 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1065 }
1066 else
1067 {
1068 if (size < 7)
1069 return FALSE;
1070
1071 context->adpcm.ms.predictor[0] = *src++;
1072 context->adpcm.ms.delta[0] = read_int16(src);
1073 src += 2;
1074 context->adpcm.ms.sample1[0] = read_int16(src);
1075 src += 2;
1076 context->adpcm.ms.sample2[0] = read_int16(src);
1077 src += 2;
1078 size -= 7;
1079 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1080 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1081 }
1082 }
1083
1084 if (channels > 1)
1085 {
1086 {
1087 if (size < 1)
1088 return FALSE;
1089 const BYTE sample = *src++;
1090 size--;
1091 Stream_Write_INT16(
1092 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1093 Stream_Write_INT16(
1094 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1095 }
1096 {
1097 if (size < 1)
1098 return FALSE;
1099 const BYTE sample = *src++;
1100 size--;
1101 Stream_Write_INT16(
1102 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1103 Stream_Write_INT16(
1104 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
1105 }
1106 }
1107 else
1108 {
1109 if (size < 1)
1110 return FALSE;
1111 const BYTE sample = *src++;
1112 size--;
1113 Stream_Write_INT16(out,
1114 freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
1115 Stream_Write_INT16(
1116 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
1117 }
1118 }
1119
1120 return TRUE;
1121}
1122
1123static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
1124 size_t channel)
1125{
1126 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample1));
1127 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.sample2));
1128 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.delta));
1129 WINPR_ASSERT(channel < ARRAYSIZE(adpcm->ms.predictor));
1130
1131 INT32 presample =
1132 ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
1133 (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
1134 256;
1135 INT32 errordelta = (sample - presample) / adpcm->ms.delta[channel];
1136
1137 if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
1138 errordelta++;
1139
1140 if (errordelta > 7)
1141 errordelta = 7;
1142 else if (errordelta < -8)
1143 errordelta = -8;
1144
1145 presample += adpcm->ms.delta[channel] * errordelta;
1146
1147 if (presample > 32767)
1148 presample = 32767;
1149 else if (presample < -32768)
1150 presample = -32768;
1151
1152 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
1153 adpcm->ms.sample1[channel] = presample;
1154 const size_t offset = (((BYTE)errordelta) & 0x0F);
1155 WINPR_ASSERT(offset < ARRAYSIZE(ms_adpcm_adaptation_table));
1156 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[offset] / 256;
1157
1158 if (adpcm->ms.delta[channel] < 16)
1159 adpcm->ms.delta[channel] = 16;
1160
1161 return ((BYTE)errordelta) & 0x0F;
1162}
1163
1164static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1165 const BYTE* WINPR_RESTRICT src, size_t size,
1166 wStream* WINPR_RESTRICT out)
1167{
1168 if (!valid_ms_adpcm_format(context))
1169 return FALSE;
1170
1171 const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
1172
1173 if (!Stream_EnsureRemainingCapacity(out, size))
1174 return FALSE;
1175
1176 const size_t start = Stream_GetPosition(out);
1177
1178 if (context->adpcm.ms.delta[0] < 16)
1179 context->adpcm.ms.delta[0] = 16;
1180
1181 if (context->adpcm.ms.delta[1] < 16)
1182 context->adpcm.ms.delta[1] = 16;
1183
1184 while (size >= step)
1185 {
1186 if ((Stream_GetPosition(out) - start) % context->common.format.nBlockAlign == 0)
1187 {
1188 if (context->common.format.nChannels > 1)
1189 {
1190 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1191 Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
1192 Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
1193 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1194 Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
1195 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
1196
1197 context->adpcm.ms.sample1[0] = read_int16(src + 4);
1198 context->adpcm.ms.sample1[1] = read_int16(src + 6);
1199 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1200 context->adpcm.ms.sample2[1] = read_int16(src + 2);
1201
1202 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1203 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1204 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1205 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1206
1207 src += 8;
1208 size -= 8;
1209 }
1210 else
1211 {
1212 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1213 Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
1214 Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1215
1216 context->adpcm.ms.sample1[0] = read_int16(src + 2);
1217 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1218
1219 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1220 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1221 src += 4;
1222 size -= 4;
1223 }
1224 }
1225
1226 {
1227 const INT16 sample = read_int16(src);
1228 src += 2;
1229 Stream_Write_UINT8(
1230 out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
1231 }
1232 {
1233 const INT16 sample = read_int16(src);
1234 src += 2;
1235
1236 BYTE val = 0;
1237 Stream_Read_UINT8(out, val);
1238 val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1239 context->common.format.nChannels > 1 ? 1 : 0);
1240 Stream_Write_UINT8(out, val);
1241 }
1242 size -= 4;
1243 }
1244
1245 return TRUE;
1246}
1247
1248#endif
1249
1250FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1251{
1252#if defined(WITH_DSP_FFMPEG)
1253 return freerdp_dsp_ffmpeg_context_new(encoder);
1254#else
1255 FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1256
1257 if (!context)
1258 return nullptr;
1259
1260 if (!freerdp_dsp_common_context_init(&context->common, encoder))
1261 goto fail;
1262
1263#if defined(WITH_GSM)
1264 context->gsm = gsm_create();
1265
1266 if (!context->gsm)
1267 goto fail;
1268
1269 {
1270 int rc;
1271 int val = 1;
1272 rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1273
1274 if (rc < 0)
1275 goto fail;
1276 }
1277#endif
1278#if defined(WITH_LAME)
1279
1280 if (encoder)
1281 {
1282 context->lame = lame_init();
1283
1284 if (!context->lame)
1285 goto fail;
1286 }
1287 else
1288 {
1289 context->hip = hip_decode_init();
1290
1291 if (!context->hip)
1292 goto fail;
1293 }
1294
1295#endif
1296#if defined(WITH_FAAD2)
1297
1298 if (!encoder)
1299 {
1300 context->faad = NeAACDecOpen();
1301
1302 if (!context->faad)
1303 goto fail;
1304 }
1305
1306#endif
1307 return context;
1308fail:
1309 freerdp_dsp_context_free(context);
1310 return nullptr;
1311#endif
1312}
1313
1314void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1315{
1316 if (!context)
1317 return;
1318
1319#if defined(WITH_FDK_AAC)
1321 WINPR_ASSERT(ctx);
1322 fdk_aac_dsp_uninit(ctx);
1323#endif
1324
1325#if defined(WITH_DSP_FFMPEG)
1326 freerdp_dsp_ffmpeg_context_free(context);
1327#else
1328
1329 freerdp_dsp_common_context_uninit(&context->common);
1330
1331#if defined(WITH_GSM)
1332 gsm_destroy(context->gsm);
1333#endif
1334#if defined(WITH_LAME)
1335
1336 if (context->common.encoder)
1337 lame_close(context->lame);
1338 else
1339 hip_decode_exit(context->hip);
1340
1341#endif
1342#if defined(WITH_OPUS)
1343
1344 if (context->opus_decoder)
1345 opus_decoder_destroy(context->opus_decoder);
1346 if (context->opus_encoder)
1347 opus_encoder_destroy(context->opus_encoder);
1348
1349#endif
1350#if defined(WITH_FAAD2)
1351
1352 if (!context->common.encoder)
1353 NeAACDecClose(context->faad);
1354
1355#endif
1356#if defined(WITH_FAAC)
1357
1358 if (context->faac)
1359 faacEncClose(context->faac);
1360
1361#endif
1362#if defined(WITH_SOXR)
1363 soxr_delete(context->sox);
1364#endif
1365 free(context);
1366
1367#endif
1368}
1369
1370BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1371 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1372 const BYTE* WINPR_RESTRICT pdata, size_t length,
1373 wStream* WINPR_RESTRICT out)
1374{
1375#if defined(WITH_FDK_AAC)
1377 WINPR_ASSERT(ctx);
1378 switch (ctx->format.wFormatTag)
1379 {
1380 case WAVE_FORMAT_AAC_MS:
1381 return fdk_aac_dsp_encode(ctx, srcFormat, pdata, length, out);
1382 default:
1383 break;
1384 }
1385#endif
1386
1387#if defined(WITH_DSP_FFMPEG)
1388 return freerdp_dsp_ffmpeg_encode(context, srcFormat, pdata, length, out);
1389#else
1390 if (!context || !context->common.encoder || !srcFormat || !pdata || !out)
1391 return FALSE;
1392
1393 AUDIO_FORMAT format = *srcFormat;
1394 const BYTE* resampleData = nullptr;
1395 size_t resampleLength = 0;
1396
1397 if (!freerdp_dsp_channel_mix(context, pdata, length, srcFormat, &resampleData, &resampleLength))
1398 return FALSE;
1399
1400 format.nChannels = context->common.format.nChannels;
1401
1402 const BYTE* data = nullptr;
1403 if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1404 return FALSE;
1405
1406 switch (context->common.format.wFormatTag)
1407 {
1408 case WAVE_FORMAT_PCM:
1409 if (!Stream_EnsureRemainingCapacity(out, length))
1410 return FALSE;
1411
1412 Stream_Write(out, data, length);
1413 return TRUE;
1414
1415 case WAVE_FORMAT_ADPCM:
1416 return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1417
1418 case WAVE_FORMAT_DVI_ADPCM:
1419 return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1420#if defined(WITH_GSM)
1421
1422 case WAVE_FORMAT_GSM610:
1423 return freerdp_dsp_encode_gsm610(context, data, length, out);
1424#endif
1425#if defined(WITH_LAME)
1426
1427 case WAVE_FORMAT_MPEGLAYER3:
1428 return freerdp_dsp_encode_mp3(context, data, length, out);
1429#endif
1430#if defined(WITH_FAAC)
1431
1432 case WAVE_FORMAT_AAC_MS:
1433 return freerdp_dsp_encode_faac(context, data, length, out);
1434#endif
1435#if defined(WITH_OPUS)
1436
1437 case WAVE_FORMAT_OPUS:
1438 return freerdp_dsp_encode_opus(context, data, length, out);
1439#endif
1440 default:
1441 return FALSE;
1442 }
1443
1444 return FALSE;
1445#endif
1446}
1447
1448BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1449 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1450 const BYTE* WINPR_RESTRICT data, size_t length, wStream* WINPR_RESTRICT out)
1451{
1452#if defined(WITH_FDK_AAC)
1454 WINPR_ASSERT(ctx);
1455 switch (ctx->format.wFormatTag)
1456 {
1457 case WAVE_FORMAT_AAC_MS:
1458 return fdk_aac_dsp_decode(ctx, srcFormat, data, length, out);
1459 default:
1460 break;
1461 }
1462#endif
1463
1464#if defined(WITH_DSP_FFMPEG)
1465 return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1466#else
1467
1468 if (!context || context->common.encoder || !srcFormat || !data || !out)
1469 return FALSE;
1470
1471 switch (context->common.format.wFormatTag)
1472 {
1473 case WAVE_FORMAT_PCM:
1474 if (!Stream_EnsureRemainingCapacity(out, length))
1475 return FALSE;
1476
1477 Stream_Write(out, data, length);
1478 return TRUE;
1479
1480 case WAVE_FORMAT_ADPCM:
1481 return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1482
1483 case WAVE_FORMAT_DVI_ADPCM:
1484 return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1485#if defined(WITH_GSM)
1486
1487 case WAVE_FORMAT_GSM610:
1488 return freerdp_dsp_decode_gsm610(context, data, length, out);
1489#endif
1490#if defined(WITH_LAME)
1491
1492 case WAVE_FORMAT_MPEGLAYER3:
1493 return freerdp_dsp_decode_mp3(context, data, length, out);
1494#endif
1495#if defined(WITH_FAAD2)
1496
1497 case WAVE_FORMAT_AAC_MS:
1498 return freerdp_dsp_decode_faad(context, data, length, out);
1499#endif
1500
1501#if defined(WITH_OPUS)
1502 case WAVE_FORMAT_OPUS:
1503 return freerdp_dsp_decode_opus(context, data, length, out);
1504#endif
1505 default:
1506 return FALSE;
1507 }
1508
1509 return FALSE;
1510#endif
1511}
1512
1513BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* WINPR_RESTRICT format, BOOL encode)
1514{
1515#if defined(WITH_FDK_AAC)
1516 switch (format->wFormatTag)
1517 {
1518 case WAVE_FORMAT_AAC_MS:
1519 return TRUE;
1520 default:
1521 break;
1522 }
1523
1524#endif
1525
1526#if defined(WITH_DSP_FFMPEG)
1527 return freerdp_dsp_ffmpeg_supports_format(format, encode);
1528#else
1529
1530#if !defined(WITH_DSP_EXPERIMENTAL)
1531 WINPR_UNUSED(encode);
1532#endif
1533 switch (format->wFormatTag)
1534 {
1535 case WAVE_FORMAT_PCM:
1536 return TRUE;
1537#if defined(WITH_DSP_EXPERIMENTAL)
1538
1539 case WAVE_FORMAT_ADPCM:
1540 return FALSE;
1541 case WAVE_FORMAT_DVI_ADPCM:
1542 return TRUE;
1543#endif
1544#if defined(WITH_GSM)
1545
1546 case WAVE_FORMAT_GSM610:
1547#if defined(WITH_DSP_EXPERIMENTAL)
1548 return TRUE;
1549#else
1550 return !encode;
1551#endif
1552#endif
1553#if defined(WITH_LAME)
1554
1555 case WAVE_FORMAT_MPEGLAYER3:
1556#if defined(WITH_DSP_EXPERIMENTAL)
1557 return TRUE;
1558#else
1559 return !encode;
1560#endif
1561#endif
1562
1563 case WAVE_FORMAT_AAC_MS:
1564#if defined(WITH_FAAD2)
1565 if (!encode)
1566 return TRUE;
1567
1568#endif
1569#if defined(WITH_FAAC)
1570
1571 if (encode)
1572 return TRUE;
1573
1574#endif
1575#if defined(WITH_FDK_AAC)
1576 return TRUE;
1577#else
1578 return FALSE;
1579#endif
1580
1581#if defined(WITH_OPUS)
1582 case WAVE_FORMAT_OPUS:
1583 return opus_is_valid_samplerate(format);
1584#endif
1585 default:
1586 return FALSE;
1587 }
1588
1589 return FALSE;
1590#endif
1591}
1592
1593BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1594 const AUDIO_FORMAT* WINPR_RESTRICT targetFormat,
1595 WINPR_ATTR_UNUSED UINT32 FramesPerPacket)
1596{
1597#if defined(WITH_FDK_AAC)
1598 WINPR_ASSERT(targetFormat);
1599 if (targetFormat->wFormatTag == WAVE_FORMAT_AAC_MS)
1600 {
1602 fdk_aac_dsp_uninit(ctx);
1603 ctx->format = *targetFormat;
1604 return fdk_aac_dsp_init(ctx, FramesPerPacket);
1605 }
1606#endif
1607
1608#if defined(WITH_DSP_FFMPEG)
1609 return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1610#else
1611
1612 if (!context || !targetFormat)
1613 return FALSE;
1614
1615 context->common.format = *targetFormat;
1616
1617 switch (context->common.format.wFormatTag)
1618 {
1619#if defined(WITH_LAME)
1620 case WAVE_FORMAT_MPEGLAYER3:
1621 if (!valid_mp3_format(context))
1622 return FALSE;
1623 break;
1624#endif
1625 case WAVE_FORMAT_ADPCM:
1626 if (!valid_ms_adpcm_format(context))
1627 return FALSE;
1628 break;
1629 case WAVE_FORMAT_DVI_ADPCM:
1630 {
1631 if (!valid_ima_adpcm_format(context))
1632 return FALSE;
1633 if (FramesPerPacket == 0)
1634 return FALSE;
1635
1636 const size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
1637 context->common.format.nChannels * FramesPerPacket;
1638 const size_t data_per_block = (1ULL * context->common.format.nBlockAlign -
1639 4ULL * context->common.format.nChannels) *
1640 8ULL;
1641 size_t nb_block_per_packet = min_frame_data / data_per_block;
1642
1643 if (min_frame_data % data_per_block)
1644 nb_block_per_packet++;
1645
1646 context->adpcm.ima.packet_size =
1647 nb_block_per_packet * context->common.format.nBlockAlign;
1648 if (!Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size))
1649 return FALSE;
1650 Stream_ResetPosition(context->common.buffer);
1651 }
1652 break;
1653 default:
1654 break;
1655 }
1656
1657#if defined(WITH_OPUS)
1658
1659 if (opus_is_valid_samplerate(&context->common.format))
1660 {
1661 if (!context->common.encoder)
1662 {
1663 int opus_error = OPUS_OK;
1664
1665 context->opus_decoder = opus_decoder_create(
1666 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1667 context->common.format.nChannels, &opus_error);
1668 if (opus_error != OPUS_OK)
1669 return FALSE;
1670 }
1671 else
1672 {
1673 int opus_error = OPUS_OK;
1674
1675 context->opus_encoder = opus_encoder_create(
1676 WINPR_ASSERTING_INT_CAST(opus_int32, context->common.format.nSamplesPerSec),
1677 context->common.format.nChannels, OPUS_APPLICATION_VOIP, &opus_error);
1678 if (opus_error != OPUS_OK)
1679 return FALSE;
1680
1681 opus_error =
1682 opus_encoder_ctl(context->opus_encoder,
1683 OPUS_SET_BITRATE(context->common.format.nAvgBytesPerSec * 8));
1684 if (opus_error != OPUS_OK)
1685 return FALSE;
1686 }
1687 }
1688
1689#endif
1690#if defined(WITH_FAAD2)
1691 context->faadSetup = FALSE;
1692#endif
1693#if defined(WITH_FAAC)
1694
1695 if (context->common.encoder)
1696 {
1697 faacEncConfigurationPtr cfg = nullptr;
1698
1699 if (context->faac)
1700 faacEncClose(context->faac);
1701
1702 context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1703 &context->faacInputSamples, &context->faacMaxOutputBytes);
1704
1705 if (!context->faac)
1706 return FALSE;
1707
1708 cfg = faacEncGetCurrentConfiguration(context->faac);
1709 cfg->inputFormat = FAAC_INPUT_16BIT;
1710 cfg->outputFormat = 0;
1711 cfg->mpegVersion = MPEG4;
1712 cfg->useTns = 1;
1713 cfg->bandWidth = targetFormat->nAvgBytesPerSec;
1714 const int rc = faacEncSetConfiguration(context->faac, cfg);
1715 if (rc <= 0)
1716 return FALSE;
1717 }
1718
1719#endif
1720#if defined(WITH_SOXR)
1721 {
1722 soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1723 soxr_error_t error = nullptr;
1724
1725 soxr_delete(context->sox);
1726 context->sox =
1727 soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1728 targetFormat->nChannels, &error, &iospec, nullptr, nullptr);
1729
1730 if (!context->sox || (error != nullptr))
1731 return FALSE;
1732 }
1733#endif
1734 return TRUE;
1735#endif
1736}
1737
1738BOOL freerdp_dsp_common_context_init(FREERDP_DSP_COMMON_CONTEXT* context, BOOL encode)
1739{
1740 WINPR_ASSERT(context);
1741 context->encoder = encode;
1742 context->buffer = Stream_New(nullptr, 1024);
1743 if (!context->buffer)
1744 goto fail;
1745
1746 context->channelmix = Stream_New(nullptr, 1024);
1747 if (!context->channelmix)
1748 goto fail;
1749
1750 context->resample = Stream_New(nullptr, 1024);
1751 if (!context->resample)
1752 goto fail;
1753
1754 return TRUE;
1755
1756fail:
1757 freerdp_dsp_common_context_uninit(context);
1758 return FALSE;
1759}
1760
1761void freerdp_dsp_common_context_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
1762{
1763 WINPR_ASSERT(context);
1764
1765 Stream_Free(context->buffer, TRUE);
1766 Stream_Free(context->channelmix, TRUE);
1767 Stream_Free(context->resample, TRUE);
1768
1769 context->buffer = nullptr;
1770 context->channelmix = nullptr;
1771 context->resample = nullptr;
1772}