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