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