Coverage Report

Created: 2026-09-14 06:32

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