Coverage Report

Created: 2024-05-20 06:11

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