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 5760
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) ? TRUE : FALSE;
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] += 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 int 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 << 1)] = (decoded & 0xFF);
402 dst[((i & 3) << 3) + (channel << 1) + 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 << 1) + 4] = (decoded & 0xFF);
409 dst[((i & 3) << 3) + (channel << 1) + 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] = { 0 };
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 size_t max_size = 5760;
617 int frames;
618
619 if (!context || !src || !out)
620 return FALSE;
621
622 /* Max packet duration is 120ms (5760 at 48KHz) */
623 max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
624 if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
625 return FALSE;
626
627 frames = 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, 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 int 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, frames * context->common.format.nChannels * sizeof(int16_t));
657}
658#endif
659
660#if defined(WITH_FAAD2)
661static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
662 const BYTE* WINPR_RESTRICT src, size_t size,
663 wStream* WINPR_RESTRICT out)
664{
665 NeAACDecFrameInfo info;
666 size_t offset = 0;
667
668 if (!context || !src || !out)
669 return FALSE;
670
671 if (!context->faadSetup)
672 {
673 union
674 {
675 const void* cpv;
676 void* pv;
677 } cnv;
678 unsigned long samplerate;
679 unsigned char channels;
680 long err;
681 cnv.cpv = src;
682 err = NeAACDecInit(context->faad, /* API is not modifying content */ cnv.pv, size,
683 &samplerate, &channels);
684
685 if (err != 0)
686 return FALSE;
687
688 if (channels != context->common.format.nChannels)
689 return FALSE;
690
691 if (samplerate != context->common.format.nSamplesPerSec)
692 return FALSE;
693
694 context->faadSetup = TRUE;
695 }
696
697 while (offset < size)
698 {
699 union
700 {
701 const void* cpv;
702 void* pv;
703 } cnv;
704 size_t outSize;
705 void* sample_buffer;
706 outSize = context->common.format.nSamplesPerSec * context->common.format.nChannels *
707 context->common.format.wBitsPerSample / 8;
708
709 if (!Stream_EnsureRemainingCapacity(out, outSize))
710 return FALSE;
711
712 sample_buffer = Stream_Pointer(out);
713
714 cnv.cpv = &src[offset];
715 NeAACDecDecode2(context->faad, &info, cnv.pv, size - offset, &sample_buffer,
716 Stream_GetRemainingCapacity(out));
717
718 if (info.error != 0)
719 return FALSE;
720
721 offset += info.bytesconsumed;
722
723 if (info.samples == 0)
724 continue;
725
726 Stream_Seek(out, info.samples * context->common.format.wBitsPerSample / 8);
727 }
728
729 return TRUE;
730}
731
732#endif
733
741static const struct
742{
743 BYTE byte_num;
744 BYTE byte_shift;
745} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
746 { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
747 { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
748
749static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, int channel, INT16 sample)
750{
751 INT32 ss = ima_step_size_table[adpcm->ima.last_step[channel]];
752 INT32 e = sample - adpcm->ima.last_sample[channel];
753 INT32 d = e;
754 INT32 diff = ss >> 3;
755 BYTE enc = 0;
756
757 if (e < 0)
758 {
759 enc = 8;
760 e = -e;
761 }
762
763 if (e >= ss)
764 {
765 enc |= 4;
766 e -= ss;
767 }
768
769 ss >>= 1;
770
771 if (e >= ss)
772 {
773 enc |= 2;
774 e -= ss;
775 }
776
777 ss >>= 1;
778
779 if (e >= ss)
780 {
781 enc |= 1;
782 e -= ss;
783 }
784
785 if (d < 0)
786 diff = d + e - diff;
787 else
788 diff = d - e + diff;
789
790 diff += adpcm->ima.last_sample[channel];
791
792 if (diff < -32768)
793 diff = -32768;
794 else if (diff > 32767)
795 diff = 32767;
796
797 adpcm->ima.last_sample[channel] = (INT16)diff;
798 adpcm->ima.last_step[channel] += ima_step_index_table[enc];
799
800 if (adpcm->ima.last_step[channel] < 0)
801 adpcm->ima.last_step[channel] = 0;
802 else if (adpcm->ima.last_step[channel] > 88)
803 adpcm->ima.last_step[channel] = 88;
804
805 return enc;
806}
807
808static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
809 const BYTE* WINPR_RESTRICT src, size_t size,
810 wStream* WINPR_RESTRICT out)
811{
812 if (!Stream_EnsureRemainingCapacity(out, size))
813 return FALSE;
814 if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
815 return FALSE;
816
817 const size_t align = (context->common.format.nChannels > 1) ? 32 : 4;
818
819 while (size >= align)
820 {
821 if (Stream_GetPosition(context->common.buffer) % context->common.format.nBlockAlign == 0)
822 {
823 Stream_Write_UINT8(context->common.buffer, context->adpcm.ima.last_sample[0] & 0xFF);
824 Stream_Write_UINT8(context->common.buffer,
825 (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
826 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[0]);
827 Stream_Write_UINT8(context->common.buffer, 0);
828
829 if (context->common.format.nChannels > 1)
830 {
831 Stream_Write_UINT8(context->common.buffer,
832 context->adpcm.ima.last_sample[1] & 0xFF);
833 Stream_Write_UINT8(context->common.buffer,
834 (context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
835 Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[1]);
836 Stream_Write_UINT8(context->common.buffer, 0);
837 }
838 }
839
840 if (context->common.format.nChannels > 1)
841 {
842 BYTE* dst = Stream_Pointer(context->common.buffer);
843 ZeroMemory(dst, 8);
844
845 for (size_t i = 0; i < 16; i++)
846 {
847 const INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
848 src += 2;
849 const BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
850 dst[ima_stereo_encode_map[i].byte_num] |= encoded
851 << ima_stereo_encode_map[i].byte_shift;
852 }
853
854 if (!Stream_SafeSeek(context->common.buffer, 8))
855 return FALSE;
856 size -= 32;
857 }
858 else
859 {
860 INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
861 src += 2;
862 BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
863 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
864 src += 2;
865 encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
866 Stream_Write_UINT8(context->common.buffer, encoded);
867 size -= 4;
868 }
869
870 if (Stream_GetPosition(context->common.buffer) >= context->adpcm.ima.packet_size)
871 {
872 BYTE* bsrc = Stream_Buffer(context->common.buffer);
873 Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
874 Stream_SetPosition(context->common.buffer, 0);
875 }
876 }
877
878 return TRUE;
879}
880
887static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
888 768, 614, 512, 409, 307, 230, 230, 230 };
889
890static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
891
892static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
893
894static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
895 int channel)
896{
897 const INT8 nibble = (sample & 0x08 ? (INT8)sample - 16 : (INT8)sample);
898 INT32 presample =
899 ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
900 (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
901 256;
902 presample += nibble * adpcm->ms.delta[channel];
903
904 if (presample > 32767)
905 presample = 32767;
906 else if (presample < -32768)
907 presample = -32768;
908
909 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
910 adpcm->ms.sample1[channel] = presample;
911 adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[sample] / 256;
912
913 if (adpcm->ms.delta[channel] < 16)
914 adpcm->ms.delta[channel] = 16;
915
916 return (INT16)presample;
917}
918
919static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
920 const BYTE* WINPR_RESTRICT src, size_t size,
921 wStream* WINPR_RESTRICT out)
922{
923 const size_t out_size = size * 4;
924 const UINT32 channels = context->common.format.nChannels;
925 const UINT32 block_size = context->common.format.nBlockAlign;
926
927 if (!Stream_EnsureCapacity(out, out_size))
928 return FALSE;
929
930 while (size > 0)
931 {
932 if (size % block_size == 0)
933 {
934 if (channels > 1)
935 {
936 context->adpcm.ms.predictor[0] = *src++;
937 context->adpcm.ms.predictor[1] = *src++;
938 context->adpcm.ms.delta[0] = read_int16(src);
939 src += 2;
940 context->adpcm.ms.delta[1] = read_int16(src);
941 src += 2;
942 context->adpcm.ms.sample1[0] = read_int16(src);
943 src += 2;
944 context->adpcm.ms.sample1[1] = read_int16(src);
945 src += 2;
946 context->adpcm.ms.sample2[0] = read_int16(src);
947 src += 2;
948 context->adpcm.ms.sample2[1] = read_int16(src);
949 src += 2;
950 size -= 14;
951 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
952 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
953 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
954 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
955 }
956 else
957 {
958 context->adpcm.ms.predictor[0] = *src++;
959 context->adpcm.ms.delta[0] = read_int16(src);
960 src += 2;
961 context->adpcm.ms.sample1[0] = read_int16(src);
962 src += 2;
963 context->adpcm.ms.sample2[0] = read_int16(src);
964 src += 2;
965 size -= 7;
966 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
967 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
968 }
969 }
970
971 if (channels > 1)
972 {
973 {
974 const BYTE sample = *src++;
975 size--;
976 Stream_Write_INT16(
977 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
978 Stream_Write_INT16(
979 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
980 }
981 {
982 const BYTE sample = *src++;
983 size--;
984 Stream_Write_INT16(
985 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
986 Stream_Write_INT16(
987 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
988 }
989 }
990 else
991 {
992 const BYTE sample = *src++;
993 size--;
994 Stream_Write_INT16(out,
995 freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
996 Stream_Write_INT16(
997 out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
998 }
999 }
1000
1001 return TRUE;
1002}
1003
1004static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
1005 int channel)
1006{
1007 INT32 presample =
1008 ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
1009 (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
1010 256;
1011 INT32 errordelta = (sample - presample) / adpcm->ms.delta[channel];
1012
1013 if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
1014 errordelta++;
1015
1016 if (errordelta > 7)
1017 errordelta = 7;
1018 else if (errordelta < -8)
1019 errordelta = -8;
1020
1021 presample += adpcm->ms.delta[channel] * errordelta;
1022
1023 if (presample > 32767)
1024 presample = 32767;
1025 else if (presample < -32768)
1026 presample = -32768;
1027
1028 adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
1029 adpcm->ms.sample1[channel] = presample;
1030 adpcm->ms.delta[channel] =
1031 adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((BYTE)errordelta) & 0x0F)] / 256;
1032
1033 if (adpcm->ms.delta[channel] < 16)
1034 adpcm->ms.delta[channel] = 16;
1035
1036 return ((BYTE)errordelta) & 0x0F;
1037}
1038
1039static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1040 const BYTE* WINPR_RESTRICT src, size_t size,
1041 wStream* WINPR_RESTRICT out)
1042{
1043 const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
1044
1045 if (!Stream_EnsureRemainingCapacity(out, size))
1046 return FALSE;
1047
1048 const size_t start = Stream_GetPosition(out);
1049
1050 if (context->adpcm.ms.delta[0] < 16)
1051 context->adpcm.ms.delta[0] = 16;
1052
1053 if (context->adpcm.ms.delta[1] < 16)
1054 context->adpcm.ms.delta[1] = 16;
1055
1056 while (size >= step)
1057 {
1058 if ((Stream_GetPosition(out) - start) % context->common.format.nBlockAlign == 0)
1059 {
1060 if (context->common.format.nChannels > 1)
1061 {
1062 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1063 Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
1064 Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
1065 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1066 Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
1067 Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
1068
1069 context->adpcm.ms.sample1[0] = read_int16(src + 4);
1070 context->adpcm.ms.sample1[1] = read_int16(src + 6);
1071 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1072 context->adpcm.ms.sample2[1] = read_int16(src + 2);
1073
1074 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1075 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1076 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1077 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1078
1079 src += 8;
1080 size -= 8;
1081 }
1082 else
1083 {
1084 Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1085 Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
1086 Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1087
1088 context->adpcm.ms.sample1[0] = read_int16(src + 2);
1089 context->adpcm.ms.sample2[0] = read_int16(src + 0);
1090
1091 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1092 Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1093 src += 4;
1094 size -= 4;
1095 }
1096 }
1097
1098 {
1099 const INT16 sample = read_int16(src);
1100 src += 2;
1101 Stream_Write_UINT8(
1102 out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
1103 }
1104 {
1105 const INT16 sample = read_int16(src);
1106 src += 2;
1107
1108 BYTE val = 0;
1109 Stream_Read_UINT8(out, val);
1110 val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1111 context->common.format.nChannels > 1 ? 1 : 0);
1112 Stream_Write_UINT8(out, val);
1113 }
1114 size -= 4;
1115 }
1116
1117 return TRUE;
1118}
1119
1120#endif
1121
1122FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1123{
1124#if defined(WITH_DSP_FFMPEG)
1125 return freerdp_dsp_ffmpeg_context_new(encoder);
1126#else
1127 FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1128
1129 if (!context)
1130 return NULL;
1131
1132 if (!freerdp_dsp_common_context_init(&context->common, encoder))
1133 goto fail;
1134
1135#if defined(WITH_GSM)
1136 context->gsm = gsm_create();
1137
1138 if (!context->gsm)
1139 goto fail;
1140
1141 {
1142 int rc;
1143 int val = 1;
1144 rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1145
1146 if (rc < 0)
1147 goto fail;
1148 }
1149#endif
1150#if defined(WITH_LAME)
1151
1152 if (encoder)
1153 {
1154 context->lame = lame_init();
1155
1156 if (!context->lame)
1157 goto fail;
1158 }
1159 else
1160 {
1161 context->hip = hip_decode_init();
1162
1163 if (!context->hip)
1164 goto fail;
1165 }
1166
1167#endif
1168#if defined(WITH_FAAD2)
1169
1170 if (!encoder)
1171 {
1172 context->faad = NeAACDecOpen();
1173
1174 if (!context->faad)
1175 goto fail;
1176 }
1177
1178#endif
1179 return context;
1180fail:
1181 freerdp_dsp_context_free(context);
1182 return NULL;
1183#endif
1184}
1185
1186void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1187{
1188 if (!context)
1189 return;
1190
1191#if defined(WITH_FDK_AAC)
1193 WINPR_ASSERT(ctx);
1194 fdk_aac_dsp_uninit(ctx);
1195#endif
1196
1197#if defined(WITH_DSP_FFMPEG)
1198 freerdp_dsp_ffmpeg_context_free(context);
1199#else
1200
1201 freerdp_dsp_common_context_uninit(&context->common);
1202
1203#if defined(WITH_GSM)
1204 gsm_destroy(context->gsm);
1205#endif
1206#if defined(WITH_LAME)
1207
1208 if (context->common.encoder)
1209 lame_close(context->lame);
1210 else
1211 hip_decode_exit(context->hip);
1212
1213#endif
1214#if defined(WITH_OPUS)
1215
1216 if (context->opus_decoder)
1217 opus_decoder_destroy(context->opus_decoder);
1218 if (context->opus_encoder)
1219 opus_encoder_destroy(context->opus_encoder);
1220
1221#endif
1222#if defined(WITH_FAAD2)
1223
1224 if (!context->common.encoder)
1225 NeAACDecClose(context->faad);
1226
1227#endif
1228#if defined(WITH_FAAC)
1229
1230 if (context->faac)
1231 faacEncClose(context->faac);
1232
1233#endif
1234#if defined(WITH_SOXR)
1235 soxr_delete(context->sox);
1236#endif
1237 free(context);
1238
1239#endif
1240}
1241
1242BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1243 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1244 const BYTE* WINPR_RESTRICT pdata, size_t length,
1245 wStream* WINPR_RESTRICT out)
1246{
1247#if defined(WITH_FDK_AAC)
1249 WINPR_ASSERT(ctx);
1250 switch (ctx->format.wFormatTag)
1251 {
1252 case WAVE_FORMAT_AAC_MS:
1253 return fdk_aac_dsp_encode(ctx, srcFormat, pdata, length, out);
1254 default:
1255 break;
1256 }
1257#endif
1258
1259#if defined(WITH_DSP_FFMPEG)
1260 return freerdp_dsp_ffmpeg_encode(context, srcFormat, pdata, length, out);
1261#else
1262 if (!context || !context->common.encoder || !srcFormat || !pdata || !out)
1263 return FALSE;
1264
1265 AUDIO_FORMAT format = *srcFormat;
1266 const BYTE* resampleData = NULL;
1267 size_t resampleLength = 0;
1268
1269 if (!freerdp_dsp_channel_mix(context, pdata, length, srcFormat, &resampleData, &resampleLength))
1270 return FALSE;
1271
1272 format.nChannels = context->common.format.nChannels;
1273
1274 const BYTE* data = NULL;
1275 if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1276 return FALSE;
1277
1278 switch (context->common.format.wFormatTag)
1279 {
1280 case WAVE_FORMAT_PCM:
1281 if (!Stream_EnsureRemainingCapacity(out, length))
1282 return FALSE;
1283
1284 Stream_Write(out, data, length);
1285 return TRUE;
1286
1287 case WAVE_FORMAT_ADPCM:
1288 return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1289
1290 case WAVE_FORMAT_DVI_ADPCM:
1291 return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1292#if defined(WITH_GSM)
1293
1294 case WAVE_FORMAT_GSM610:
1295 return freerdp_dsp_encode_gsm610(context, data, length, out);
1296#endif
1297#if defined(WITH_LAME)
1298
1299 case WAVE_FORMAT_MPEGLAYER3:
1300 return freerdp_dsp_encode_mp3(context, data, length, out);
1301#endif
1302#if defined(WITH_FAAC)
1303
1304 case WAVE_FORMAT_AAC_MS:
1305 return freerdp_dsp_encode_faac(context, data, length, out);
1306#endif
1307#if defined(WITH_OPUS)
1308
1309 case WAVE_FORMAT_OPUS:
1310 return freerdp_dsp_encode_opus(context, data, length, out);
1311#endif
1312 default:
1313 return FALSE;
1314 }
1315
1316 return FALSE;
1317#endif
1318}
1319
1320BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1321 const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1322 const BYTE* WINPR_RESTRICT data, size_t length, wStream* WINPR_RESTRICT out)
1323{
1324#if defined(WITH_FDK_AAC)
1326 WINPR_ASSERT(ctx);
1327 switch (ctx->format.wFormatTag)
1328 {
1329 case WAVE_FORMAT_AAC_MS:
1330 return fdk_aac_dsp_decode(ctx, srcFormat, data, length, out);
1331 default:
1332 break;
1333 }
1334#endif
1335
1336#if defined(WITH_DSP_FFMPEG)
1337 return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1338#else
1339
1340 if (!context || context->common.encoder || !srcFormat || !data || !out)
1341 return FALSE;
1342
1343 switch (context->common.format.wFormatTag)
1344 {
1345 case WAVE_FORMAT_PCM:
1346 if (!Stream_EnsureRemainingCapacity(out, length))
1347 return FALSE;
1348
1349 Stream_Write(out, data, length);
1350 return TRUE;
1351
1352 case WAVE_FORMAT_ADPCM:
1353 return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1354
1355 case WAVE_FORMAT_DVI_ADPCM:
1356 return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1357#if defined(WITH_GSM)
1358
1359 case WAVE_FORMAT_GSM610:
1360 return freerdp_dsp_decode_gsm610(context, data, length, out);
1361#endif
1362#if defined(WITH_LAME)
1363
1364 case WAVE_FORMAT_MPEGLAYER3:
1365 return freerdp_dsp_decode_mp3(context, data, length, out);
1366#endif
1367#if defined(WITH_FAAD2)
1368
1369 case WAVE_FORMAT_AAC_MS:
1370 return freerdp_dsp_decode_faad(context, data, length, out);
1371#endif
1372
1373#if defined(WITH_OPUS)
1374 case WAVE_FORMAT_OPUS:
1375 return freerdp_dsp_decode_opus(context, data, length, out);
1376#endif
1377 default:
1378 return FALSE;
1379 }
1380
1381 return FALSE;
1382#endif
1383}
1384
1385BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* WINPR_RESTRICT format, BOOL encode)
1386{
1387#if defined(WITH_FDK_AAC)
1388 switch (format->wFormatTag)
1389 {
1390 case WAVE_FORMAT_AAC_MS:
1391 return TRUE;
1392 default:
1393 break;
1394 }
1395
1396#endif
1397
1398#if defined(WITH_DSP_FFMPEG)
1399 return freerdp_dsp_ffmpeg_supports_format(format, encode);
1400#else
1401
1402#if !defined(WITH_DSP_EXPERIMENTAL)
1403 WINPR_UNUSED(encode);
1404#endif
1405 switch (format->wFormatTag)
1406 {
1407 case WAVE_FORMAT_PCM:
1408 return TRUE;
1409#if defined(WITH_DSP_EXPERIMENTAL)
1410
1411 case WAVE_FORMAT_ADPCM:
1412 return FALSE;
1413 case WAVE_FORMAT_DVI_ADPCM:
1414 return TRUE;
1415#endif
1416#if defined(WITH_GSM)
1417
1418 case WAVE_FORMAT_GSM610:
1419#if defined(WITH_DSP_EXPERIMENTAL)
1420 return TRUE;
1421#else
1422 return !encode;
1423#endif
1424#endif
1425#if defined(WITH_LAME)
1426
1427 case WAVE_FORMAT_MPEGLAYER3:
1428#if defined(WITH_DSP_EXPERIMENTAL)
1429 return TRUE;
1430#else
1431 return !encode;
1432#endif
1433#endif
1434
1435 case WAVE_FORMAT_AAC_MS:
1436#if defined(WITH_FAAD2)
1437 if (!encode)
1438 return TRUE;
1439
1440#endif
1441#if defined(WITH_FAAC)
1442
1443 if (encode)
1444 return TRUE;
1445
1446#endif
1447#if defined(WITH_OPUS)
1448 /* fallthrough */
1449 WINPR_FALLTHROUGH
1450 case WAVE_FORMAT_OPUS:
1451 return opus_is_valid_samplerate(format);
1452#endif
1453 /* fallthrough */
1454 WINPR_FALLTHROUGH
1455 default:
1456 return FALSE;
1457 }
1458
1459 return FALSE;
1460#endif
1461}
1462
1463BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1464 const AUDIO_FORMAT* WINPR_RESTRICT targetFormat,
1465 WINPR_ATTR_UNUSED UINT32 FramesPerPacket)
1466{
1467#if defined(WITH_FDK_AAC)
1468 WINPR_ASSERT(targetFormat);
1469 if (targetFormat->wFormatTag == WAVE_FORMAT_AAC_MS)
1470 {
1472 fdk_aac_dsp_uninit(ctx);
1473 ctx->format = *targetFormat;
1474 return fdk_aac_dsp_init(ctx, FramesPerPacket);
1475 }
1476#endif
1477
1478#if defined(WITH_DSP_FFMPEG)
1479 return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1480#else
1481
1482 if (!context || !targetFormat)
1483 return FALSE;
1484
1485 context->common.format = *targetFormat;
1486
1487 if (context->common.format.wFormatTag == WAVE_FORMAT_DVI_ADPCM)
1488 {
1489 size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
1490 context->common.format.nChannels * FramesPerPacket;
1491 size_t data_per_block =
1492 (1ULL * context->common.format.nBlockAlign - 4ULL * context->common.format.nChannels) *
1493 8ULL;
1494 size_t nb_block_per_packet = min_frame_data / data_per_block;
1495
1496 if (min_frame_data % data_per_block)
1497 nb_block_per_packet++;
1498
1499 context->adpcm.ima.packet_size = nb_block_per_packet * context->common.format.nBlockAlign;
1500 Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size);
1501 Stream_SetPosition(context->common.buffer, 0);
1502 }
1503
1504#if defined(WITH_OPUS)
1505
1506 if (opus_is_valid_samplerate(&context->common.format))
1507 {
1508 if (!context->common.encoder)
1509 {
1510 int opus_error = OPUS_OK;
1511
1512 context->opus_decoder =
1513 opus_decoder_create(context->common.format.nSamplesPerSec,
1514 context->common.format.nChannels, &opus_error);
1515 if (opus_error != OPUS_OK)
1516 return FALSE;
1517 }
1518 else
1519 {
1520 int opus_error = OPUS_OK;
1521
1522 context->opus_encoder = opus_encoder_create(context->common.format.nSamplesPerSec,
1523 context->common.format.nChannels,
1524 OPUS_APPLICATION_VOIP, &opus_error);
1525 if (opus_error != OPUS_OK)
1526 return FALSE;
1527
1528 opus_error =
1529 opus_encoder_ctl(context->opus_encoder,
1530 OPUS_SET_BITRATE(context->common.format.nAvgBytesPerSec * 8));
1531 if (opus_error != OPUS_OK)
1532 return FALSE;
1533 }
1534 }
1535
1536#endif
1537#if defined(WITH_FAAD2)
1538 context->faadSetup = FALSE;
1539#endif
1540#if defined(WITH_FAAC)
1541
1542 if (context->common.encoder)
1543 {
1544 faacEncConfigurationPtr cfg;
1545
1546 if (context->faac)
1547 faacEncClose(context->faac);
1548
1549 context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1550 &context->faacInputSamples, &context->faacMaxOutputBytes);
1551
1552 if (!context->faac)
1553 return FALSE;
1554
1555 cfg = faacEncGetCurrentConfiguration(context->faac);
1556 cfg->inputFormat = FAAC_INPUT_16BIT;
1557 cfg->outputFormat = 0;
1558 cfg->mpegVersion = MPEG4;
1559 cfg->useTns = 1;
1560 cfg->bandWidth = targetFormat->nAvgBytesPerSec;
1561 faacEncSetConfiguration(context->faac, cfg);
1562 }
1563
1564#endif
1565#if defined(WITH_SOXR)
1566 {
1567 soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1568 soxr_error_t error;
1569 soxr_delete(context->sox);
1570 context->sox =
1571 soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1572 targetFormat->nChannels, &error, &iospec, NULL, NULL);
1573
1574 if (!context->sox || (error != 0))
1575 return FALSE;
1576 }
1577#endif
1578 return TRUE;
1579#endif
1580}
1581
1582BOOL freerdp_dsp_common_context_init(FREERDP_DSP_COMMON_CONTEXT* context, BOOL encode)
1583{
1584 WINPR_ASSERT(context);
1585 context->encoder = encode;
1586 context->buffer = Stream_New(NULL, 1024);
1587 if (!context->buffer)
1588 goto fail;
1589
1590 context->channelmix = Stream_New(NULL, 1024);
1591 if (!context->channelmix)
1592 goto fail;
1593
1594 context->resample = Stream_New(NULL, 1024);
1595 if (!context->resample)
1596 goto fail;
1597
1598 return TRUE;
1599
1600fail:
1601 freerdp_dsp_common_context_uninit(context);
1602 return FALSE;
1603}
1604
1605void freerdp_dsp_common_context_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
1606{
1607 WINPR_ASSERT(context);
1608
1609 Stream_Free(context->buffer, TRUE);
1610 Stream_Free(context->channelmix, TRUE);
1611 Stream_Free(context->resample, TRUE);
1612
1613 context->buffer = NULL;
1614 context->channelmix = NULL;
1615 context->resample = NULL;
1616}