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