Coverage Report

Created: 2026-05-11 07:01

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