Coverage Report

Created: 2026-10-28 06:54

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