Coverage Report

Created: 2025-07-01 06:46

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