Coverage Report

Created: 2026-04-12 07:03

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