Coverage Report

Created: 2024-09-08 06:20

/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
#define TAG FREERDP_TAG("dsp")
71
72
#if !defined(WITH_DSP_FFMPEG)
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 = (short*)Stream_Buffer(context->common.buffer);
522
  pcm_r = (short*)Stream_Buffer(context->common.buffer) + 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, (int32_t*)Stream_Buffer(context->common.buffer),
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, size, Stream_Pointer(out), OPUS_MAX_FRAMES, 0);
628
  if (frames < 0)
629
    return FALSE;
630
631
  Stream_Seek(out, frames * context->common.format.nChannels * sizeof(int16_t));
632
633
  return TRUE;
634
}
635
636
static BOOL freerdp_dsp_encode_opus(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
637
                                    const BYTE* WINPR_RESTRICT src, size_t size,
638
                                    wStream* WINPR_RESTRICT out)
639
{
640
  if (!context || !src || !out)
641
    return FALSE;
642
643
  /* Max packet duration is 120ms (5760 at 48KHz) */
644
  const size_t max_size = OPUS_MAX_FRAMES * context->common.format.nChannels * sizeof(int16_t);
645
  if (!Stream_EnsureRemainingCapacity(context->common.buffer, max_size))
646
    return FALSE;
647
648
  const int src_frames = size / sizeof(opus_int16) / context->common.format.nChannels;
649
  const opus_int16* src_data = (const opus_int16*)src;
650
  const int frames =
651
      opus_encode(context->opus_encoder, src_data, src_frames, Stream_Pointer(out), max_size);
652
  if (frames < 0)
653
    return FALSE;
654
  return Stream_SafeSeek(out, frames * context->common.format.nChannels * sizeof(int16_t));
655
}
656
#endif
657
658
#if defined(WITH_FAAD2)
659
static BOOL freerdp_dsp_decode_faad(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
660
                                    const BYTE* WINPR_RESTRICT src, size_t size,
661
                                    wStream* WINPR_RESTRICT out)
662
{
663
  NeAACDecFrameInfo info;
664
  size_t offset = 0;
665
666
  if (!context || !src || !out)
667
    return FALSE;
668
669
  if (!context->faadSetup)
670
  {
671
    union
672
    {
673
      const void* cpv;
674
      void* pv;
675
    } cnv;
676
    unsigned long samplerate;
677
    unsigned char channels;
678
    long err;
679
    cnv.cpv = src;
680
    err = NeAACDecInit(context->faad, /* API is not modifying content */ cnv.pv, size,
681
                       &samplerate, &channels);
682
683
    if (err != 0)
684
      return FALSE;
685
686
    if (channels != context->common.format.nChannels)
687
      return FALSE;
688
689
    if (samplerate != context->common.format.nSamplesPerSec)
690
      return FALSE;
691
692
    context->faadSetup = TRUE;
693
  }
694
695
  while (offset < size)
696
  {
697
    union
698
    {
699
      const void* cpv;
700
      void* pv;
701
    } cnv;
702
    size_t outSize;
703
    void* sample_buffer;
704
    outSize = context->common.format.nSamplesPerSec * context->common.format.nChannels *
705
              context->common.format.wBitsPerSample / 8;
706
707
    if (!Stream_EnsureRemainingCapacity(out, outSize))
708
      return FALSE;
709
710
    sample_buffer = Stream_Pointer(out);
711
712
    cnv.cpv = &src[offset];
713
    NeAACDecDecode2(context->faad, &info, cnv.pv, size - offset, &sample_buffer,
714
                    Stream_GetRemainingCapacity(out));
715
716
    if (info.error != 0)
717
      return FALSE;
718
719
    offset += info.bytesconsumed;
720
721
    if (info.samples == 0)
722
      continue;
723
724
    Stream_Seek(out, info.samples * context->common.format.wBitsPerSample / 8);
725
  }
726
727
  return TRUE;
728
}
729
730
#endif
731
732
/**
733
 * 0     1     2     3
734
 * 2 0   6 4   10 8  14 12   <left>
735
 *
736
 * 4     5     6     7
737
 * 3 1   7 5   11 9  15 13   <right>
738
 */
739
static const struct
740
{
741
  BYTE byte_num;
742
  BYTE byte_shift;
743
} ima_stereo_encode_map[] = { { 0, 0 }, { 4, 0 }, { 0, 4 }, { 4, 4 }, { 1, 0 }, { 5, 0 },
744
                            { 1, 4 }, { 5, 4 }, { 2, 0 }, { 6, 0 }, { 2, 4 }, { 6, 4 },
745
                            { 3, 0 }, { 7, 0 }, { 3, 4 }, { 7, 4 } };
746
747
static BYTE dsp_encode_ima_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, int channel, INT16 sample)
748
0
{
749
0
  INT32 ss = ima_step_size_table[adpcm->ima.last_step[channel]];
750
0
  INT32 e = sample - adpcm->ima.last_sample[channel];
751
0
  INT32 d = e;
752
0
  INT32 diff = ss >> 3;
753
0
  BYTE enc = 0;
754
755
0
  if (e < 0)
756
0
  {
757
0
    enc = 8;
758
0
    e = -e;
759
0
  }
760
761
0
  if (e >= ss)
762
0
  {
763
0
    enc |= 4;
764
0
    e -= ss;
765
0
  }
766
767
0
  ss >>= 1;
768
769
0
  if (e >= ss)
770
0
  {
771
0
    enc |= 2;
772
0
    e -= ss;
773
0
  }
774
775
0
  ss >>= 1;
776
777
0
  if (e >= ss)
778
0
  {
779
0
    enc |= 1;
780
0
    e -= ss;
781
0
  }
782
783
0
  if (d < 0)
784
0
    diff = d + e - diff;
785
0
  else
786
0
    diff = d - e + diff;
787
788
0
  diff += adpcm->ima.last_sample[channel];
789
790
0
  if (diff < -32768)
791
0
    diff = -32768;
792
0
  else if (diff > 32767)
793
0
    diff = 32767;
794
795
0
  adpcm->ima.last_sample[channel] = (INT16)diff;
796
0
  adpcm->ima.last_step[channel] += ima_step_index_table[enc];
797
798
0
  if (adpcm->ima.last_step[channel] < 0)
799
0
    adpcm->ima.last_step[channel] = 0;
800
0
  else if (adpcm->ima.last_step[channel] > 88)
801
0
    adpcm->ima.last_step[channel] = 88;
802
803
0
  return enc;
804
0
}
805
806
static BOOL freerdp_dsp_encode_ima_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
807
                                         const BYTE* WINPR_RESTRICT src, size_t size,
808
                                         wStream* WINPR_RESTRICT out)
809
0
{
810
0
  if (!Stream_EnsureRemainingCapacity(out, size))
811
0
    return FALSE;
812
0
  if (!Stream_EnsureRemainingCapacity(context->common.buffer, size + 64))
813
0
    return FALSE;
814
815
0
  const size_t align = (context->common.format.nChannels > 1) ? 32 : 4;
816
817
0
  while (size >= align)
818
0
  {
819
0
    if (Stream_GetPosition(context->common.buffer) % context->common.format.nBlockAlign == 0)
820
0
    {
821
0
      Stream_Write_UINT8(context->common.buffer, context->adpcm.ima.last_sample[0] & 0xFF);
822
0
      Stream_Write_UINT8(context->common.buffer,
823
0
                         (context->adpcm.ima.last_sample[0] >> 8) & 0xFF);
824
0
      Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[0]);
825
0
      Stream_Write_UINT8(context->common.buffer, 0);
826
827
0
      if (context->common.format.nChannels > 1)
828
0
      {
829
0
        Stream_Write_UINT8(context->common.buffer,
830
0
                           context->adpcm.ima.last_sample[1] & 0xFF);
831
0
        Stream_Write_UINT8(context->common.buffer,
832
0
                           (context->adpcm.ima.last_sample[1] >> 8) & 0xFF);
833
0
        Stream_Write_UINT8(context->common.buffer, (BYTE)context->adpcm.ima.last_step[1]);
834
0
        Stream_Write_UINT8(context->common.buffer, 0);
835
0
      }
836
0
    }
837
838
0
    if (context->common.format.nChannels > 1)
839
0
    {
840
0
      BYTE* dst = Stream_Pointer(context->common.buffer);
841
0
      ZeroMemory(dst, 8);
842
843
0
      for (size_t i = 0; i < 16; i++)
844
0
      {
845
0
        const INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
846
0
        src += 2;
847
0
        const BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, i % 2, sample);
848
0
        dst[ima_stereo_encode_map[i].byte_num] |= encoded
849
0
                                                  << ima_stereo_encode_map[i].byte_shift;
850
0
      }
851
852
0
      if (!Stream_SafeSeek(context->common.buffer, 8))
853
0
        return FALSE;
854
0
      size -= 32;
855
0
    }
856
0
    else
857
0
    {
858
0
      INT16 sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
859
0
      src += 2;
860
0
      BYTE encoded = dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample);
861
0
      sample = (INT16)(((UINT16)(*src)) | (((UINT16)(*(src + 1))) << 8));
862
0
      src += 2;
863
0
      encoded |= dsp_encode_ima_adpcm_sample(&context->adpcm, 0, sample) << 4;
864
0
      Stream_Write_UINT8(context->common.buffer, encoded);
865
0
      size -= 4;
866
0
    }
867
868
0
    if (Stream_GetPosition(context->common.buffer) >= context->adpcm.ima.packet_size)
869
0
    {
870
0
      BYTE* bsrc = Stream_Buffer(context->common.buffer);
871
0
      Stream_Write(out, bsrc, context->adpcm.ima.packet_size);
872
0
      Stream_SetPosition(context->common.buffer, 0);
873
0
    }
874
0
  }
875
876
0
  return TRUE;
877
0
}
878
879
/**
880
 * Microsoft ADPCM Specification:
881
 *
882
 * http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM
883
 */
884
885
static const INT32 ms_adpcm_adaptation_table[] = { 230, 230, 230, 230, 307, 409, 512, 614,
886
                                                 768, 614, 512, 409, 307, 230, 230, 230 };
887
888
static const INT32 ms_adpcm_coeffs1[7] = { 256, 512, 0, 192, 240, 460, 392 };
889
890
static const INT32 ms_adpcm_coeffs2[7] = { 0, -256, 0, 64, 0, -208, -232 };
891
892
static INLINE INT16 freerdp_dsp_decode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, BYTE sample,
893
                                                       int channel)
894
0
{
895
0
  const INT8 nibble = (sample & 0x08 ? (INT8)sample - 16 : (INT8)sample);
896
0
  INT32 presample =
897
0
      ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
898
0
       (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
899
0
      256;
900
0
  presample += nibble * adpcm->ms.delta[channel];
901
902
0
  if (presample > 32767)
903
0
    presample = 32767;
904
0
  else if (presample < -32768)
905
0
    presample = -32768;
906
907
0
  adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
908
0
  adpcm->ms.sample1[channel] = presample;
909
0
  adpcm->ms.delta[channel] = adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[sample] / 256;
910
911
0
  if (adpcm->ms.delta[channel] < 16)
912
0
    adpcm->ms.delta[channel] = 16;
913
914
0
  return (INT16)presample;
915
0
}
916
917
static BOOL freerdp_dsp_decode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
918
                                        const BYTE* WINPR_RESTRICT src, size_t size,
919
                                        wStream* WINPR_RESTRICT out)
920
0
{
921
0
  const size_t out_size = size * 4;
922
0
  const UINT32 channels = context->common.format.nChannels;
923
0
  const UINT32 block_size = context->common.format.nBlockAlign;
924
925
0
  if (!Stream_EnsureCapacity(out, out_size))
926
0
    return FALSE;
927
928
0
  while (size > 0)
929
0
  {
930
0
    if (size % block_size == 0)
931
0
    {
932
0
      if (channels > 1)
933
0
      {
934
0
        context->adpcm.ms.predictor[0] = *src++;
935
0
        context->adpcm.ms.predictor[1] = *src++;
936
0
        context->adpcm.ms.delta[0] = read_int16(src);
937
0
        src += 2;
938
0
        context->adpcm.ms.delta[1] = read_int16(src);
939
0
        src += 2;
940
0
        context->adpcm.ms.sample1[0] = read_int16(src);
941
0
        src += 2;
942
0
        context->adpcm.ms.sample1[1] = read_int16(src);
943
0
        src += 2;
944
0
        context->adpcm.ms.sample2[0] = read_int16(src);
945
0
        src += 2;
946
0
        context->adpcm.ms.sample2[1] = read_int16(src);
947
0
        src += 2;
948
0
        size -= 14;
949
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
950
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
951
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
952
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
953
0
      }
954
0
      else
955
0
      {
956
0
        context->adpcm.ms.predictor[0] = *src++;
957
0
        context->adpcm.ms.delta[0] = read_int16(src);
958
0
        src += 2;
959
0
        context->adpcm.ms.sample1[0] = read_int16(src);
960
0
        src += 2;
961
0
        context->adpcm.ms.sample2[0] = read_int16(src);
962
0
        src += 2;
963
0
        size -= 7;
964
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
965
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
966
0
      }
967
0
    }
968
969
0
    if (channels > 1)
970
0
    {
971
0
      {
972
0
        const BYTE sample = *src++;
973
0
        size--;
974
0
        Stream_Write_INT16(
975
0
            out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
976
0
        Stream_Write_INT16(
977
0
            out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
978
0
      }
979
0
      {
980
0
        const BYTE sample = *src++;
981
0
        size--;
982
0
        Stream_Write_INT16(
983
0
            out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
984
0
        Stream_Write_INT16(
985
0
            out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 1));
986
0
      }
987
0
    }
988
0
    else
989
0
    {
990
0
      const BYTE sample = *src++;
991
0
      size--;
992
0
      Stream_Write_INT16(out,
993
0
                         freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample >> 4, 0));
994
0
      Stream_Write_INT16(
995
0
          out, freerdp_dsp_decode_ms_adpcm_sample(&context->adpcm, sample & 0x0F, 0));
996
0
    }
997
0
  }
998
999
0
  return TRUE;
1000
0
}
1001
1002
static BYTE freerdp_dsp_encode_ms_adpcm_sample(ADPCM* WINPR_RESTRICT adpcm, INT32 sample,
1003
                                               int channel)
1004
0
{
1005
0
  INT32 presample =
1006
0
      ((adpcm->ms.sample1[channel] * ms_adpcm_coeffs1[adpcm->ms.predictor[channel]]) +
1007
0
       (adpcm->ms.sample2[channel] * ms_adpcm_coeffs2[adpcm->ms.predictor[channel]])) /
1008
0
      256;
1009
0
  INT32 errordelta = (sample - presample) / adpcm->ms.delta[channel];
1010
1011
0
  if ((sample - presample) % adpcm->ms.delta[channel] > adpcm->ms.delta[channel] / 2)
1012
0
    errordelta++;
1013
1014
0
  if (errordelta > 7)
1015
0
    errordelta = 7;
1016
0
  else if (errordelta < -8)
1017
0
    errordelta = -8;
1018
1019
0
  presample += adpcm->ms.delta[channel] * errordelta;
1020
1021
0
  if (presample > 32767)
1022
0
    presample = 32767;
1023
0
  else if (presample < -32768)
1024
0
    presample = -32768;
1025
1026
0
  adpcm->ms.sample2[channel] = adpcm->ms.sample1[channel];
1027
0
  adpcm->ms.sample1[channel] = presample;
1028
0
  adpcm->ms.delta[channel] =
1029
0
      adpcm->ms.delta[channel] * ms_adpcm_adaptation_table[(((BYTE)errordelta) & 0x0F)] / 256;
1030
1031
0
  if (adpcm->ms.delta[channel] < 16)
1032
0
    adpcm->ms.delta[channel] = 16;
1033
1034
0
  return ((BYTE)errordelta) & 0x0F;
1035
0
}
1036
1037
static BOOL freerdp_dsp_encode_ms_adpcm(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1038
                                        const BYTE* WINPR_RESTRICT src, size_t size,
1039
                                        wStream* WINPR_RESTRICT out)
1040
0
{
1041
0
  const size_t step = 8 + ((context->common.format.nChannels > 1) ? 4 : 0);
1042
1043
0
  if (!Stream_EnsureRemainingCapacity(out, size))
1044
0
    return FALSE;
1045
1046
0
  const size_t start = Stream_GetPosition(out);
1047
1048
0
  if (context->adpcm.ms.delta[0] < 16)
1049
0
    context->adpcm.ms.delta[0] = 16;
1050
1051
0
  if (context->adpcm.ms.delta[1] < 16)
1052
0
    context->adpcm.ms.delta[1] = 16;
1053
1054
0
  while (size >= step)
1055
0
  {
1056
0
    if ((Stream_GetPosition(out) - start) % context->common.format.nBlockAlign == 0)
1057
0
    {
1058
0
      if (context->common.format.nChannels > 1)
1059
0
      {
1060
0
        Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1061
0
        Stream_Write_UINT8(out, context->adpcm.ms.predictor[1]);
1062
0
        Stream_Write_UINT8(out, (context->adpcm.ms.delta[0] & 0xFF));
1063
0
        Stream_Write_UINT8(out, ((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1064
0
        Stream_Write_UINT8(out, (context->adpcm.ms.delta[1] & 0xFF));
1065
0
        Stream_Write_UINT8(out, ((context->adpcm.ms.delta[1] >> 8) & 0xFF));
1066
1067
0
        context->adpcm.ms.sample1[0] = read_int16(src + 4);
1068
0
        context->adpcm.ms.sample1[1] = read_int16(src + 6);
1069
0
        context->adpcm.ms.sample2[0] = read_int16(src + 0);
1070
0
        context->adpcm.ms.sample2[1] = read_int16(src + 2);
1071
1072
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1073
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[1]);
1074
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1075
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[1]);
1076
1077
0
        src += 8;
1078
0
        size -= 8;
1079
0
      }
1080
0
      else
1081
0
      {
1082
0
        Stream_Write_UINT8(out, context->adpcm.ms.predictor[0]);
1083
0
        Stream_Write_UINT8(out, (BYTE)(context->adpcm.ms.delta[0] & 0xFF));
1084
0
        Stream_Write_UINT8(out, (BYTE)((context->adpcm.ms.delta[0] >> 8) & 0xFF));
1085
1086
0
        context->adpcm.ms.sample1[0] = read_int16(src + 2);
1087
0
        context->adpcm.ms.sample2[0] = read_int16(src + 0);
1088
1089
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample1[0]);
1090
0
        Stream_Write_INT16(out, (INT16)context->adpcm.ms.sample2[0]);
1091
0
        src += 4;
1092
0
        size -= 4;
1093
0
      }
1094
0
    }
1095
1096
0
    {
1097
0
      const INT16 sample = read_int16(src);
1098
0
      src += 2;
1099
0
      Stream_Write_UINT8(
1100
0
          out, (freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample, 0) << 4) & 0xFF);
1101
0
    }
1102
0
    {
1103
0
      const INT16 sample = read_int16(src);
1104
0
      src += 2;
1105
1106
0
      BYTE val = 0;
1107
0
      Stream_Read_UINT8(out, val);
1108
0
      val += freerdp_dsp_encode_ms_adpcm_sample(&context->adpcm, sample,
1109
0
                                                context->common.format.nChannels > 1 ? 1 : 0);
1110
0
      Stream_Write_UINT8(out, val);
1111
0
    }
1112
0
    size -= 4;
1113
0
  }
1114
1115
0
  return TRUE;
1116
0
}
1117
1118
#endif
1119
1120
FREERDP_DSP_CONTEXT* freerdp_dsp_context_new(BOOL encoder)
1121
0
{
1122
#if defined(WITH_DSP_FFMPEG)
1123
  return freerdp_dsp_ffmpeg_context_new(encoder);
1124
#else
1125
0
  FREERDP_DSP_CONTEXT* context = calloc(1, sizeof(FREERDP_DSP_CONTEXT));
1126
1127
0
  if (!context)
1128
0
    return NULL;
1129
1130
0
  if (!freerdp_dsp_common_context_init(&context->common, encoder))
1131
0
    goto fail;
1132
1133
#if defined(WITH_GSM)
1134
  context->gsm = gsm_create();
1135
1136
  if (!context->gsm)
1137
    goto fail;
1138
1139
  {
1140
    int rc;
1141
    int val = 1;
1142
    rc = gsm_option(context->gsm, GSM_OPT_WAV49, &val);
1143
1144
    if (rc < 0)
1145
      goto fail;
1146
  }
1147
#endif
1148
#if defined(WITH_LAME)
1149
1150
  if (encoder)
1151
  {
1152
    context->lame = lame_init();
1153
1154
    if (!context->lame)
1155
      goto fail;
1156
  }
1157
  else
1158
  {
1159
    context->hip = hip_decode_init();
1160
1161
    if (!context->hip)
1162
      goto fail;
1163
  }
1164
1165
#endif
1166
#if defined(WITH_FAAD2)
1167
1168
  if (!encoder)
1169
  {
1170
    context->faad = NeAACDecOpen();
1171
1172
    if (!context->faad)
1173
      goto fail;
1174
  }
1175
1176
#endif
1177
0
  return context;
1178
0
fail:
1179
0
  freerdp_dsp_context_free(context);
1180
0
  return NULL;
1181
0
#endif
1182
0
}
1183
1184
void freerdp_dsp_context_free(FREERDP_DSP_CONTEXT* context)
1185
0
{
1186
#if defined(WITH_DSP_FFMPEG)
1187
  freerdp_dsp_ffmpeg_context_free(context);
1188
#else
1189
1190
0
  if (context)
1191
0
  {
1192
0
    freerdp_dsp_common_context_uninit(&context->common);
1193
1194
#if defined(WITH_GSM)
1195
    gsm_destroy(context->gsm);
1196
#endif
1197
#if defined(WITH_LAME)
1198
1199
    if (context->common.encoder)
1200
      lame_close(context->lame);
1201
    else
1202
      hip_decode_exit(context->hip);
1203
1204
#endif
1205
#if defined(WITH_OPUS)
1206
1207
    if (context->opus_decoder)
1208
      opus_decoder_destroy(context->opus_decoder);
1209
    if (context->opus_encoder)
1210
      opus_encoder_destroy(context->opus_encoder);
1211
1212
#endif
1213
#if defined(WITH_FAAD2)
1214
1215
    if (!context->common.encoder)
1216
      NeAACDecClose(context->faad);
1217
1218
#endif
1219
#if defined(WITH_FAAC)
1220
1221
    if (context->faac)
1222
      faacEncClose(context->faac);
1223
1224
#endif
1225
#if defined(WITH_SOXR)
1226
    soxr_delete(context->sox);
1227
#endif
1228
0
    free(context);
1229
0
  }
1230
1231
0
#endif
1232
0
}
1233
1234
BOOL freerdp_dsp_encode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1235
                        const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1236
                        const BYTE* WINPR_RESTRICT pdata, size_t length,
1237
                        wStream* WINPR_RESTRICT out)
1238
0
{
1239
#if defined(WITH_FDK_AAC)
1240
  FREERDP_DSP_COMMON_CONTEXT* ctx = (FREERDP_DSP_COMMON_CONTEXT*)context;
1241
  WINPR_ASSERT(ctx);
1242
  switch (ctx->format.wFormatTag)
1243
  {
1244
    case WAVE_FORMAT_AAC_MS:
1245
      return fdk_aac_dsp_encode(ctx, srcFormat, pdata, length, out);
1246
    default:
1247
      break;
1248
  }
1249
#endif
1250
1251
#if defined(WITH_DSP_FFMPEG)
1252
  return freerdp_dsp_ffmpeg_encode(context, srcFormat, pdata, length, out);
1253
#else
1254
0
  if (!context || !context->common.encoder || !srcFormat || !pdata || !out)
1255
0
    return FALSE;
1256
1257
0
  AUDIO_FORMAT format = *srcFormat;
1258
0
  const BYTE* resampleData = NULL;
1259
0
  size_t resampleLength = 0;
1260
1261
0
  if (!freerdp_dsp_channel_mix(context, pdata, length, srcFormat, &resampleData, &resampleLength))
1262
0
    return FALSE;
1263
1264
0
  format.nChannels = context->common.format.nChannels;
1265
1266
0
  const BYTE* data = NULL;
1267
0
  if (!freerdp_dsp_resample(context, resampleData, resampleLength, &format, &data, &length))
1268
0
    return FALSE;
1269
1270
0
  switch (context->common.format.wFormatTag)
1271
0
  {
1272
0
    case WAVE_FORMAT_PCM:
1273
0
      if (!Stream_EnsureRemainingCapacity(out, length))
1274
0
        return FALSE;
1275
1276
0
      Stream_Write(out, data, length);
1277
0
      return TRUE;
1278
1279
0
    case WAVE_FORMAT_ADPCM:
1280
0
      return freerdp_dsp_encode_ms_adpcm(context, data, length, out);
1281
1282
0
    case WAVE_FORMAT_DVI_ADPCM:
1283
0
      return freerdp_dsp_encode_ima_adpcm(context, data, length, out);
1284
#if defined(WITH_GSM)
1285
1286
    case WAVE_FORMAT_GSM610:
1287
      return freerdp_dsp_encode_gsm610(context, data, length, out);
1288
#endif
1289
#if defined(WITH_LAME)
1290
1291
    case WAVE_FORMAT_MPEGLAYER3:
1292
      return freerdp_dsp_encode_mp3(context, data, length, out);
1293
#endif
1294
#if defined(WITH_FAAC)
1295
1296
    case WAVE_FORMAT_AAC_MS:
1297
      return freerdp_dsp_encode_faac(context, data, length, out);
1298
#endif
1299
#if defined(WITH_OPUS)
1300
1301
    case WAVE_FORMAT_OPUS:
1302
      return freerdp_dsp_encode_opus(context, data, length, out);
1303
#endif
1304
0
    default:
1305
0
      return FALSE;
1306
0
  }
1307
1308
0
  return FALSE;
1309
0
#endif
1310
0
}
1311
1312
BOOL freerdp_dsp_decode(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1313
                        const AUDIO_FORMAT* WINPR_RESTRICT srcFormat,
1314
                        const BYTE* WINPR_RESTRICT data, size_t length, wStream* WINPR_RESTRICT out)
1315
0
{
1316
#if defined(WITH_FDK_AAC)
1317
  FREERDP_DSP_COMMON_CONTEXT* ctx = (FREERDP_DSP_COMMON_CONTEXT*)context;
1318
  WINPR_ASSERT(ctx);
1319
  switch (ctx->format.wFormatTag)
1320
  {
1321
    case WAVE_FORMAT_AAC_MS:
1322
      return fdk_aac_dsp_decode(ctx, srcFormat, data, length, out);
1323
    default:
1324
      break;
1325
  }
1326
#endif
1327
1328
#if defined(WITH_DSP_FFMPEG)
1329
  return freerdp_dsp_ffmpeg_decode(context, srcFormat, data, length, out);
1330
#else
1331
1332
0
  if (!context || context->common.encoder || !srcFormat || !data || !out)
1333
0
    return FALSE;
1334
1335
0
  switch (context->common.format.wFormatTag)
1336
0
  {
1337
0
    case WAVE_FORMAT_PCM:
1338
0
      if (!Stream_EnsureRemainingCapacity(out, length))
1339
0
        return FALSE;
1340
1341
0
      Stream_Write(out, data, length);
1342
0
      return TRUE;
1343
1344
0
    case WAVE_FORMAT_ADPCM:
1345
0
      return freerdp_dsp_decode_ms_adpcm(context, data, length, out);
1346
1347
0
    case WAVE_FORMAT_DVI_ADPCM:
1348
0
      return freerdp_dsp_decode_ima_adpcm(context, data, length, out);
1349
#if defined(WITH_GSM)
1350
1351
    case WAVE_FORMAT_GSM610:
1352
      return freerdp_dsp_decode_gsm610(context, data, length, out);
1353
#endif
1354
#if defined(WITH_LAME)
1355
1356
    case WAVE_FORMAT_MPEGLAYER3:
1357
      return freerdp_dsp_decode_mp3(context, data, length, out);
1358
#endif
1359
#if defined(WITH_FAAD2)
1360
1361
    case WAVE_FORMAT_AAC_MS:
1362
      return freerdp_dsp_decode_faad(context, data, length, out);
1363
#endif
1364
1365
#if defined(WITH_OPUS)
1366
    case WAVE_FORMAT_OPUS:
1367
      return freerdp_dsp_decode_opus(context, data, length, out);
1368
#endif
1369
0
    default:
1370
0
      return FALSE;
1371
0
  }
1372
1373
0
  return FALSE;
1374
0
#endif
1375
0
}
1376
1377
BOOL freerdp_dsp_supports_format(const AUDIO_FORMAT* WINPR_RESTRICT format, BOOL encode)
1378
0
{
1379
#if defined(WITH_FDK_AAC)
1380
  switch (format->wFormatTag)
1381
  {
1382
    case WAVE_FORMAT_AAC_MS:
1383
      return TRUE;
1384
    default:
1385
      break;
1386
  }
1387
1388
#endif
1389
1390
#if defined(WITH_DSP_FFMPEG)
1391
  return freerdp_dsp_ffmpeg_supports_format(format, encode);
1392
#else
1393
1394
0
#if !defined(WITH_DSP_EXPERIMENTAL)
1395
0
  WINPR_UNUSED(encode);
1396
0
#endif
1397
0
  switch (format->wFormatTag)
1398
0
  {
1399
0
    case WAVE_FORMAT_PCM:
1400
0
      return TRUE;
1401
#if defined(WITH_DSP_EXPERIMENTAL)
1402
1403
    case WAVE_FORMAT_ADPCM:
1404
      return FALSE;
1405
    case WAVE_FORMAT_DVI_ADPCM:
1406
      return TRUE;
1407
#endif
1408
#if defined(WITH_GSM)
1409
1410
    case WAVE_FORMAT_GSM610:
1411
#if defined(WITH_DSP_EXPERIMENTAL)
1412
      return TRUE;
1413
#else
1414
      return !encode;
1415
#endif
1416
#endif
1417
#if defined(WITH_LAME)
1418
1419
    case WAVE_FORMAT_MPEGLAYER3:
1420
#if defined(WITH_DSP_EXPERIMENTAL)
1421
      return TRUE;
1422
#else
1423
      return !encode;
1424
#endif
1425
#endif
1426
1427
0
    case WAVE_FORMAT_AAC_MS:
1428
#if defined(WITH_FAAD2)
1429
      if (!encode)
1430
        return TRUE;
1431
1432
#endif
1433
#if defined(WITH_FAAC)
1434
1435
      if (encode)
1436
        return TRUE;
1437
1438
#endif
1439
#if defined(WITH_OPUS)
1440
      /* fallthrough */
1441
      WINPR_FALLTHROUGH
1442
    case WAVE_FORMAT_OPUS:
1443
      return opus_is_valid_samplerate(format);
1444
#endif
1445
      /* fallthrough */
1446
0
      WINPR_FALLTHROUGH
1447
0
    default:
1448
0
      return FALSE;
1449
0
  }
1450
1451
0
  return FALSE;
1452
0
#endif
1453
0
}
1454
1455
BOOL freerdp_dsp_context_reset(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context,
1456
                               const AUDIO_FORMAT* WINPR_RESTRICT targetFormat,
1457
                               UINT32 FramesPerPacket)
1458
0
{
1459
#if defined(WITH_FDK_AAC)
1460
  WINPR_ASSERT(targetFormat);
1461
  if (targetFormat->wFormatTag == WAVE_FORMAT_AAC_MS)
1462
  {
1463
    FREERDP_DSP_COMMON_CONTEXT* ctx = (FREERDP_DSP_COMMON_CONTEXT*)context;
1464
    fdk_aac_dsp_uninit(ctx);
1465
    ctx->format = *targetFormat;
1466
    return fdk_aac_dsp_init(ctx, FramesPerPacket);
1467
  }
1468
#endif
1469
1470
#if defined(WITH_DSP_FFMPEG)
1471
  return freerdp_dsp_ffmpeg_context_reset(context, targetFormat);
1472
#else
1473
1474
0
  if (!context || !targetFormat)
1475
0
    return FALSE;
1476
1477
0
  context->common.format = *targetFormat;
1478
1479
0
  if (context->common.format.wFormatTag == WAVE_FORMAT_DVI_ADPCM)
1480
0
  {
1481
0
    size_t min_frame_data = 1ull * context->common.format.wBitsPerSample *
1482
0
                            context->common.format.nChannels * FramesPerPacket;
1483
0
    size_t data_per_block =
1484
0
        (1ULL * context->common.format.nBlockAlign - 4ULL * context->common.format.nChannels) *
1485
0
        8ULL;
1486
0
    size_t nb_block_per_packet = min_frame_data / data_per_block;
1487
1488
0
    if (min_frame_data % data_per_block)
1489
0
      nb_block_per_packet++;
1490
1491
0
    context->adpcm.ima.packet_size = nb_block_per_packet * context->common.format.nBlockAlign;
1492
0
    Stream_EnsureCapacity(context->common.buffer, context->adpcm.ima.packet_size);
1493
0
    Stream_SetPosition(context->common.buffer, 0);
1494
0
  }
1495
1496
#if defined(WITH_OPUS)
1497
1498
  if (opus_is_valid_samplerate(&context->common.format))
1499
  {
1500
    if (!context->common.encoder)
1501
    {
1502
      int opus_error = OPUS_OK;
1503
1504
      context->opus_decoder =
1505
          opus_decoder_create(context->common.format.nSamplesPerSec,
1506
                              context->common.format.nChannels, &opus_error);
1507
      if (opus_error != OPUS_OK)
1508
        return FALSE;
1509
    }
1510
    else
1511
    {
1512
      int opus_error = OPUS_OK;
1513
1514
      context->opus_encoder = opus_encoder_create(context->common.format.nSamplesPerSec,
1515
                                                  context->common.format.nChannels,
1516
                                                  OPUS_APPLICATION_VOIP, &opus_error);
1517
      if (opus_error != OPUS_OK)
1518
        return FALSE;
1519
1520
      opus_error =
1521
          opus_encoder_ctl(context->opus_encoder,
1522
                           OPUS_SET_BITRATE(context->common.format.nAvgBytesPerSec * 8));
1523
      if (opus_error != OPUS_OK)
1524
        return FALSE;
1525
    }
1526
  }
1527
1528
#endif
1529
#if defined(WITH_FAAD2)
1530
  context->faadSetup = FALSE;
1531
#endif
1532
#if defined(WITH_FAAC)
1533
1534
  if (context->encoder)
1535
  {
1536
    faacEncConfigurationPtr cfg;
1537
1538
    if (context->faac)
1539
      faacEncClose(context->faac);
1540
1541
    context->faac = faacEncOpen(targetFormat->nSamplesPerSec, targetFormat->nChannels,
1542
                                &context->faacInputSamples, &context->faacMaxOutputBytes);
1543
1544
    if (!context->faac)
1545
      return FALSE;
1546
1547
    cfg = faacEncGetCurrentConfiguration(context->faac);
1548
    cfg->inputFormat = FAAC_INPUT_16BIT;
1549
    cfg->outputFormat = 0;
1550
    cfg->mpegVersion = MPEG4;
1551
    cfg->useTns = 1;
1552
    cfg->bandWidth = targetFormat->nAvgBytesPerSec;
1553
    faacEncSetConfiguration(context->faac, cfg);
1554
  }
1555
1556
#endif
1557
#if defined(WITH_SOXR)
1558
  {
1559
    soxr_io_spec_t iospec = soxr_io_spec(SOXR_INT16, SOXR_INT16);
1560
    soxr_error_t error;
1561
    soxr_delete(context->sox);
1562
    context->sox =
1563
        soxr_create(context->common.format.nSamplesPerSec, targetFormat->nSamplesPerSec,
1564
                    targetFormat->nChannels, &error, &iospec, NULL, NULL);
1565
1566
    if (!context->sox || (error != 0))
1567
      return FALSE;
1568
  }
1569
#endif
1570
0
  return TRUE;
1571
0
#endif
1572
0
}
1573
1574
BOOL freerdp_dsp_common_context_init(FREERDP_DSP_COMMON_CONTEXT* context, BOOL encode)
1575
0
{
1576
0
  WINPR_ASSERT(context);
1577
0
  context->encoder = encode;
1578
0
  context->buffer = Stream_New(NULL, 1024);
1579
0
  if (!context->buffer)
1580
0
    goto fail;
1581
1582
0
  context->channelmix = Stream_New(NULL, 1024);
1583
0
  if (!context->channelmix)
1584
0
    goto fail;
1585
1586
0
  context->resample = Stream_New(NULL, 1024);
1587
0
  if (!context->resample)
1588
0
    goto fail;
1589
1590
0
  return TRUE;
1591
1592
0
fail:
1593
0
  freerdp_dsp_common_context_uninit(context);
1594
0
  return FALSE;
1595
0
}
1596
1597
void freerdp_dsp_common_context_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
1598
0
{
1599
0
  WINPR_ASSERT(context);
1600
1601
0
  Stream_Free(context->buffer, TRUE);
1602
0
  Stream_Free(context->channelmix, TRUE);
1603
0
  Stream_Free(context->resample, TRUE);
1604
1605
0
  context->buffer = NULL;
1606
0
  context->channelmix = NULL;
1607
0
  context->resample = NULL;
1608
0
}