1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11// TODO(hlundin): Reformat file to meet style guide.
12
13/* header includes */
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#ifdef WIN32
18#include <winsock2.h>
19#endif
20#ifdef WEBRTC_LINUX
21#include <netinet/in.h>
22#endif
23
24#include <assert.h>
25
26#include <algorithm>
27
28#include "webrtc/base/checks.h"
29#include "webrtc/typedefs.h"
30
31// needed for NetEqDecoder
32#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
33#include "webrtc/modules/audio_coding/neteq/include/neteq.h"
34
35/************************/
36/* Define payload types */
37/************************/
38
39#include "PayloadTypes.h"
40
41namespace {
42const size_t kRtpDataSize = 8000;
43}
44
45/*********************/
46/* Misc. definitions */
47/*********************/
48
49#define STOPSENDTIME 3000
50#define RESTARTSENDTIME 0  // 162500
51#define FIRSTLINELEN 40
52#define CHECK_NOT_NULL(a)                                                \
53  if ((a) == 0) {                                                        \
54    printf("\n %s \n line: %d \nerror at %s\n", __FILE__, __LINE__, #a); \
55    return (-1);                                                         \
56  }
57
58//#define MULTIPLE_SAME_TIMESTAMP
59#define REPEAT_PACKET_DISTANCE 17
60#define REPEAT_PACKET_COUNT 1  // number of extra packets to send
61
62//#define INSERT_OLD_PACKETS
63#define OLD_PACKET 5  // how many seconds too old should the packet be?
64
65//#define TIMESTAMP_WRAPAROUND
66
67//#define RANDOM_DATA
68//#define RANDOM_PAYLOAD_DATA
69#define RANDOM_SEED 10
70
71//#define INSERT_DTMF_PACKETS
72//#define NO_DTMF_OVERDUB
73#define DTMF_PACKET_INTERVAL 2000
74#define DTMF_DURATION 500
75
76#define STEREO_MODE_FRAME 0
77#define STEREO_MODE_SAMPLE_1 1  // 1 octet per sample
78#define STEREO_MODE_SAMPLE_2 2  // 2 octets per sample
79
80/*************************/
81/* Function declarations */
82/*************************/
83
84void NetEQTest_GetCodec_and_PT(char* name,
85                               webrtc::NetEqDecoder* codec,
86                               int* PT,
87                               size_t frameLen,
88                               int* fs,
89                               int* bitrate,
90                               int* useRed);
91int NetEQTest_init_coders(webrtc::NetEqDecoder coder,
92                          size_t enc_frameSize,
93                          int bitrate,
94                          int sampfreq,
95                          int vad,
96                          size_t numChannels);
97void defineCodecs(webrtc::NetEqDecoder* usedCodec, int* noOfCodecs);
98int NetEQTest_free_coders(webrtc::NetEqDecoder coder, size_t numChannels);
99size_t NetEQTest_encode(webrtc::NetEqDecoder coder,
100                        int16_t* indata,
101                        size_t frameLen,
102                        unsigned char* encoded,
103                        int sampleRate,
104                        int* vad,
105                        int useVAD,
106                        int bitrate,
107                        size_t numChannels);
108void makeRTPheader(unsigned char* rtp_data,
109                   int payloadType,
110                   int seqNo,
111                   uint32_t timestamp,
112                   uint32_t ssrc);
113int makeRedundantHeader(unsigned char* rtp_data,
114                        int* payloadType,
115                        int numPayloads,
116                        uint32_t* timestamp,
117                        uint16_t* blockLen,
118                        int seqNo,
119                        uint32_t ssrc);
120size_t makeDTMFpayload(unsigned char* payload_data,
121                       int Event,
122                       int End,
123                       int Volume,
124                       int Duration);
125void stereoDeInterleave(int16_t* audioSamples, size_t numSamples);
126void stereoInterleave(unsigned char* data, size_t dataLen, size_t stride);
127
128/*********************/
129/* Codec definitions */
130/*********************/
131
132#include "webrtc_vad.h"
133
134#if ((defined CODEC_PCM16B) || (defined NETEQ_ARBITRARY_CODEC))
135#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h"
136#endif
137#ifdef CODEC_G711
138#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h"
139#endif
140#ifdef CODEC_G729
141#include "G729Interface.h"
142#endif
143#ifdef CODEC_G729_1
144#include "G729_1Interface.h"
145#endif
146#ifdef CODEC_AMR
147#include "AMRInterface.h"
148#include "AMRCreation.h"
149#endif
150#ifdef CODEC_AMRWB
151#include "AMRWBInterface.h"
152#include "AMRWBCreation.h"
153#endif
154#ifdef CODEC_ILBC
155#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h"
156#endif
157#if (defined CODEC_ISAC || defined CODEC_ISAC_SWB)
158#include "webrtc/modules/audio_coding/codecs/isac/main/include/isac.h"
159#endif
160#ifdef NETEQ_ISACFIX_CODEC
161#include "webrtc/modules/audio_coding/codecs/isac/fix/include/isacfix.h"
162#ifdef CODEC_ISAC
163#error Cannot have both ISAC and ISACfix defined. Please de-select one.
164#endif
165#endif
166#ifdef CODEC_G722
167#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h"
168#endif
169#ifdef CODEC_G722_1_24
170#include "G722_1Interface.h"
171#endif
172#ifdef CODEC_G722_1_32
173#include "G722_1Interface.h"
174#endif
175#ifdef CODEC_G722_1_16
176#include "G722_1Interface.h"
177#endif
178#ifdef CODEC_G722_1C_24
179#include "G722_1Interface.h"
180#endif
181#ifdef CODEC_G722_1C_32
182#include "G722_1Interface.h"
183#endif
184#ifdef CODEC_G722_1C_48
185#include "G722_1Interface.h"
186#endif
187#ifdef CODEC_G726
188#include "G726Creation.h"
189#include "G726Interface.h"
190#endif
191#ifdef CODEC_GSMFR
192#include "GSMFRInterface.h"
193#include "GSMFRCreation.h"
194#endif
195#if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
196     defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
197#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
198#endif
199#if ((defined CODEC_SPEEX_8) || (defined CODEC_SPEEX_16))
200#include "SpeexInterface.h"
201#endif
202#ifdef CODEC_OPUS
203#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h"
204#endif
205
206/***********************************/
207/* Global codec instance variables */
208/***********************************/
209
210WebRtcVadInst* VAD_inst[2];
211
212#ifdef CODEC_G722
213G722EncInst* g722EncState[2];
214#endif
215
216#ifdef CODEC_G722_1_24
217G722_1_24_encinst_t* G722_1_24enc_inst[2];
218#endif
219#ifdef CODEC_G722_1_32
220G722_1_32_encinst_t* G722_1_32enc_inst[2];
221#endif
222#ifdef CODEC_G722_1_16
223G722_1_16_encinst_t* G722_1_16enc_inst[2];
224#endif
225#ifdef CODEC_G722_1C_24
226G722_1C_24_encinst_t* G722_1C_24enc_inst[2];
227#endif
228#ifdef CODEC_G722_1C_32
229G722_1C_32_encinst_t* G722_1C_32enc_inst[2];
230#endif
231#ifdef CODEC_G722_1C_48
232G722_1C_48_encinst_t* G722_1C_48enc_inst[2];
233#endif
234#ifdef CODEC_G726
235G726_encinst_t* G726enc_inst[2];
236#endif
237#ifdef CODEC_G729
238G729_encinst_t* G729enc_inst[2];
239#endif
240#ifdef CODEC_G729_1
241G729_1_inst_t* G729_1_inst[2];
242#endif
243#ifdef CODEC_AMR
244AMR_encinst_t* AMRenc_inst[2];
245int16_t AMR_bitrate;
246#endif
247#ifdef CODEC_AMRWB
248AMRWB_encinst_t* AMRWBenc_inst[2];
249int16_t AMRWB_bitrate;
250#endif
251#ifdef CODEC_ILBC
252IlbcEncoderInstance* iLBCenc_inst[2];
253#endif
254#ifdef CODEC_ISAC
255ISACStruct* ISAC_inst[2];
256#endif
257#ifdef NETEQ_ISACFIX_CODEC
258ISACFIX_MainStruct* ISAC_inst[2];
259#endif
260#ifdef CODEC_ISAC_SWB
261ISACStruct* ISACSWB_inst[2];
262#endif
263#ifdef CODEC_GSMFR
264GSMFR_encinst_t* GSMFRenc_inst[2];
265#endif
266#if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
267     defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
268CNG_enc_inst* CNGenc_inst[2];
269#endif
270#ifdef CODEC_SPEEX_8
271SPEEX_encinst_t* SPEEX8enc_inst[2];
272#endif
273#ifdef CODEC_SPEEX_16
274SPEEX_encinst_t* SPEEX16enc_inst[2];
275#endif
276#ifdef CODEC_OPUS
277OpusEncInst* opus_inst[2];
278#endif
279
280int main(int argc, char* argv[]) {
281  size_t packet_size;
282  int fs;
283  webrtc::NetEqDecoder usedCodec;
284  int payloadType;
285  int bitrate = 0;
286  int useVAD, vad;
287  int useRed = 0;
288  size_t len, enc_len;
289  int16_t org_data[4000];
290  unsigned char rtp_data[kRtpDataSize];
291  int16_t seqNo = 0xFFF;
292  uint32_t ssrc = 1235412312;
293  uint32_t timestamp = 0xAC1245;
294  uint16_t length, plen;
295  uint32_t offset;
296  double sendtime = 0;
297  int red_PT[2] = {0};
298  uint32_t red_TS[2] = {0};
299  uint16_t red_len[2] = {0};
300  size_t RTPheaderLen = 12;
301  uint8_t red_data[kRtpDataSize];
302#ifdef INSERT_OLD_PACKETS
303  uint16_t old_length, old_plen;
304  size_t old_enc_len;
305  int first_old_packet = 1;
306  unsigned char old_rtp_data[kRtpDataSize];
307  size_t packet_age = 0;
308#endif
309#ifdef INSERT_DTMF_PACKETS
310  int NTone = 1;
311  int DTMFfirst = 1;
312  uint32_t DTMFtimestamp;
313  bool dtmfSent = false;
314#endif
315  bool usingStereo = false;
316  size_t stereoMode = 0;
317  size_t numChannels = 1;
318
319  /* check number of parameters */
320  if ((argc != 6) && (argc != 7)) {
321    /* print help text and exit */
322    printf("Application to encode speech into an RTP stream.\n");
323    printf("The program reads a PCM file and encodes is using the specified "
324           "codec.\n");
325    printf("The coded speech is packetized in RTP packest and written to the "
326           "output file.\n");
327    printf("The format of the RTP stream file is simlilar to that of "
328           "rtpplay,\n");
329    printf("but with the receive time euqal to 0 for all packets.\n");
330    printf("Usage:\n\n");
331    printf("%s PCMfile RTPfile frameLen codec useVAD bitrate\n", argv[0]);
332    printf("where:\n");
333
334    printf("PCMfile      : PCM speech input file\n\n");
335
336    printf("RTPfile      : RTP stream output file\n\n");
337
338    printf("frameLen     : 80...960...  Number of samples per packet (limit "
339           "depends on codec)\n\n");
340
341    printf("codecName\n");
342#ifdef CODEC_PCM16B
343    printf("             : pcm16b       16 bit PCM (8kHz)\n");
344#endif
345#ifdef CODEC_PCM16B_WB
346    printf("             : pcm16b_wb   16 bit PCM (16kHz)\n");
347#endif
348#ifdef CODEC_PCM16B_32KHZ
349    printf("             : pcm16b_swb32 16 bit PCM (32kHz)\n");
350#endif
351#ifdef CODEC_PCM16B_48KHZ
352    printf("             : pcm16b_swb48 16 bit PCM (48kHz)\n");
353#endif
354#ifdef CODEC_G711
355    printf("             : pcma         g711 A-law (8kHz)\n");
356#endif
357#ifdef CODEC_G711
358    printf("             : pcmu         g711 u-law (8kHz)\n");
359#endif
360#ifdef CODEC_G729
361    printf("             : g729         G729 (8kHz and 8kbps) CELP (One-Three "
362           "frame(s)/packet)\n");
363#endif
364#ifdef CODEC_G729_1
365    printf("             : g729.1       G729.1 (16kHz) variable rate (8--32 "
366           "kbps)\n");
367#endif
368#ifdef CODEC_G722_1_16
369    printf("             : g722.1_16    G722.1 coder (16kHz) (g722.1 with "
370           "16kbps)\n");
371#endif
372#ifdef CODEC_G722_1_24
373    printf("             : g722.1_24    G722.1 coder (16kHz) (the 24kbps "
374           "version)\n");
375#endif
376#ifdef CODEC_G722_1_32
377    printf("             : g722.1_32    G722.1 coder (16kHz) (the 32kbps "
378           "version)\n");
379#endif
380#ifdef CODEC_G722_1C_24
381    printf("             : g722.1C_24    G722.1 C coder (32kHz) (the 24kbps "
382           "version)\n");
383#endif
384#ifdef CODEC_G722_1C_32
385    printf("             : g722.1C_32    G722.1 C coder (32kHz) (the 32kbps "
386           "version)\n");
387#endif
388#ifdef CODEC_G722_1C_48
389    printf("             : g722.1C_48    G722.1 C coder (32kHz) (the 48kbps "
390           "version)\n");
391#endif
392
393#ifdef CODEC_G726
394    printf("             : g726_16      G726 coder (8kHz) 16kbps\n");
395    printf("             : g726_24      G726 coder (8kHz) 24kbps\n");
396    printf("             : g726_32      G726 coder (8kHz) 32kbps\n");
397    printf("             : g726_40      G726 coder (8kHz) 40kbps\n");
398#endif
399#ifdef CODEC_AMR
400    printf("             : AMRXk        Adaptive Multi Rate CELP codec "
401           "(8kHz)\n");
402    printf("                            X = 4.75, 5.15, 5.9, 6.7, 7.4, 7.95, "
403           "10.2 or 12.2\n");
404#endif
405#ifdef CODEC_AMRWB
406    printf("             : AMRwbXk      Adaptive Multi Rate Wideband CELP "
407           "codec (16kHz)\n");
408    printf("                            X = 7, 9, 12, 14, 16, 18, 20, 23 or "
409           "24\n");
410#endif
411#ifdef CODEC_ILBC
412    printf("             : ilbc         iLBC codec (8kHz and 13.8kbps)\n");
413#endif
414#ifdef CODEC_ISAC
415    printf("             : isac         iSAC (16kHz and 32.0 kbps). To set "
416           "rate specify a rate parameter as last parameter\n");
417#endif
418#ifdef CODEC_ISAC_SWB
419    printf("             : isacswb       iSAC SWB (32kHz and 32.0-52.0 kbps). "
420           "To set rate specify a rate parameter as last parameter\n");
421#endif
422#ifdef CODEC_GSMFR
423    printf("             : gsmfr        GSM FR codec (8kHz and 13kbps)\n");
424#endif
425#ifdef CODEC_G722
426    printf("             : g722         g722 coder (16kHz) (the 64kbps "
427           "version)\n");
428#endif
429#ifdef CODEC_SPEEX_8
430    printf("             : speex8       speex coder (8 kHz)\n");
431#endif
432#ifdef CODEC_SPEEX_16
433    printf("             : speex16      speex coder (16 kHz)\n");
434#endif
435#ifdef CODEC_RED
436#ifdef CODEC_G711
437    printf("             : red_pcm      Redundancy RTP packet with 2*G711A "
438           "frames\n");
439#endif
440#ifdef CODEC_ISAC
441    printf("             : red_isac     Redundancy RTP packet with 2*iSAC "
442           "frames\n");
443#endif
444#endif  // CODEC_RED
445#ifdef CODEC_OPUS
446    printf("             : opus         Opus codec with FEC (48kHz, 32kbps, FEC"
447        " on and tuned for 5%% packet losses)\n");
448#endif
449    printf("\n");
450
451#if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
452     defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
453    printf("useVAD       : 0 Voice Activity Detection is switched off\n");
454    printf("             : 1 Voice Activity Detection is switched on\n\n");
455#else
456    printf("useVAD       : 0 Voice Activity Detection switched off (on not "
457           "supported)\n\n");
458#endif
459    printf("bitrate      : Codec bitrate in bps (only applies to vbr "
460           "codecs)\n\n");
461
462    return (0);
463  }
464
465  FILE* in_file = fopen(argv[1], "rb");
466  CHECK_NOT_NULL(in_file);
467  printf("Input file: %s\n", argv[1]);
468  FILE* out_file = fopen(argv[2], "wb");
469  CHECK_NOT_NULL(out_file);
470  printf("Output file: %s\n\n", argv[2]);
471  int packet_size_int = atoi(argv[3]);
472  if (packet_size_int <= 0) {
473     printf("Packet size %d must be positive", packet_size_int);
474     return -1;
475  }
476  printf("Packet size: %d\n", packet_size_int);
477  packet_size = static_cast<size_t>(packet_size_int);
478
479  // check for stereo
480  if (argv[4][strlen(argv[4]) - 1] == '*') {
481    // use stereo
482    usingStereo = true;
483    numChannels = 2;
484    argv[4][strlen(argv[4]) - 1] = '\0';
485  }
486
487  NetEQTest_GetCodec_and_PT(argv[4], &usedCodec, &payloadType, packet_size, &fs,
488                            &bitrate, &useRed);
489
490  if (useRed) {
491    RTPheaderLen = 12 + 4 + 1; /* standard RTP = 12; 4 bytes per redundant
492                                  payload, except last one which is 1 byte */
493  }
494
495  useVAD = atoi(argv[5]);
496#if !(defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
497      defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
498  if (useVAD != 0) {
499    printf("Error: this simulation does not support VAD/DTX/CNG\n");
500  }
501#endif
502
503  // check stereo type
504  if (usingStereo) {
505    switch (usedCodec) {
506      // sample based codecs
507      case webrtc::NetEqDecoder::kDecoderPCMu:
508      case webrtc::NetEqDecoder::kDecoderPCMa:
509      case webrtc::NetEqDecoder::kDecoderG722: {
510        // 1 octet per sample
511        stereoMode = STEREO_MODE_SAMPLE_1;
512        break;
513      }
514      case webrtc::NetEqDecoder::kDecoderPCM16B:
515      case webrtc::NetEqDecoder::kDecoderPCM16Bwb:
516      case webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz:
517      case webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz: {
518        // 2 octets per sample
519        stereoMode = STEREO_MODE_SAMPLE_2;
520        break;
521      }
522
523      // fixed-rate frame codecs (with internal VAD)
524      default: {
525        printf("Cannot use codec %s as stereo codec\n", argv[4]);
526        exit(0);
527      }
528    }
529  }
530
531  if ((usedCodec == webrtc::NetEqDecoder::kDecoderISAC) ||
532      (usedCodec == webrtc::NetEqDecoder::kDecoderISACswb)) {
533    if (argc != 7) {
534      if (usedCodec == webrtc::NetEqDecoder::kDecoderISAC) {
535        bitrate = 32000;
536        printf("Running iSAC at default bitrate of 32000 bps (to specify "
537               "explicitly add the bps as last parameter)\n");
538      } else  // (usedCodec==webrtc::kDecoderISACswb)
539      {
540        bitrate = 56000;
541        printf("Running iSAC at default bitrate of 56000 bps (to specify "
542               "explicitly add the bps as last parameter)\n");
543      }
544    } else {
545      bitrate = atoi(argv[6]);
546      if (usedCodec == webrtc::NetEqDecoder::kDecoderISAC) {
547        if ((bitrate < 10000) || (bitrate > 32000)) {
548          printf("Error: iSAC bitrate must be between 10000 and 32000 bps (%i "
549                 "is invalid)\n", bitrate);
550          exit(0);
551        }
552        printf("Running iSAC at bitrate of %i bps\n", bitrate);
553      } else  // (usedCodec==webrtc::kDecoderISACswb)
554      {
555        if ((bitrate < 32000) || (bitrate > 56000)) {
556          printf("Error: iSAC SWB bitrate must be between 32000 and 56000 bps "
557                 "(%i is invalid)\n", bitrate);
558          exit(0);
559        }
560      }
561    }
562  } else {
563    if (argc == 7) {
564      printf("Error: Bitrate parameter can only be specified for iSAC, G.723, "
565             "and G.729.1\n");
566      exit(0);
567    }
568  }
569
570  if (useRed) {
571    printf("Redundancy engaged. ");
572  }
573  printf("Used codec: %i\n", static_cast<int>(usedCodec));
574  printf("Payload type: %i\n", payloadType);
575
576  NetEQTest_init_coders(usedCodec, packet_size, bitrate, fs, useVAD,
577                        numChannels);
578
579  /* write file header */
580  // fprintf(out_file, "#!RTPencode%s\n", "1.0");
581  fprintf(out_file, "#!rtpplay%s \n",
582          "1.0");               // this is the string that rtpplay needs
583  uint32_t dummy_variable = 0;  // should be converted to network endian format,
584                                // but does not matter when 0
585  if (fwrite(&dummy_variable, 4, 1, out_file) != 1) {
586    return -1;
587  }
588  if (fwrite(&dummy_variable, 4, 1, out_file) != 1) {
589    return -1;
590  }
591  if (fwrite(&dummy_variable, 4, 1, out_file) != 1) {
592    return -1;
593  }
594  if (fwrite(&dummy_variable, 2, 1, out_file) != 1) {
595    return -1;
596  }
597  if (fwrite(&dummy_variable, 2, 1, out_file) != 1) {
598    return -1;
599  }
600
601#ifdef TIMESTAMP_WRAPAROUND
602  timestamp = 0xFFFFFFFF - fs * 10; /* should give wrap-around in 10 seconds */
603#endif
604#if defined(RANDOM_DATA) | defined(RANDOM_PAYLOAD_DATA)
605  srand(RANDOM_SEED);
606#endif
607
608  /* if redundancy is used, the first redundant payload is zero length */
609  red_len[0] = 0;
610
611  /* read first frame */
612  len = fread(org_data, 2, packet_size * numChannels, in_file) / numChannels;
613
614  /* de-interleave if stereo */
615  if (usingStereo) {
616    stereoDeInterleave(org_data, len * numChannels);
617  }
618
619  while (len == packet_size) {
620#ifdef INSERT_DTMF_PACKETS
621    dtmfSent = false;
622
623    if (sendtime >= NTone * DTMF_PACKET_INTERVAL) {
624      if (sendtime < NTone * DTMF_PACKET_INTERVAL + DTMF_DURATION) {
625        // tone has not ended
626        if (DTMFfirst == 1) {
627          DTMFtimestamp = timestamp;  // save this timestamp
628          DTMFfirst = 0;
629        }
630        makeRTPheader(rtp_data, NETEQ_CODEC_AVT_PT, seqNo, DTMFtimestamp, ssrc);
631        enc_len = makeDTMFpayload(
632            &rtp_data[12], NTone % 12, 0, 4,
633            (int)(sendtime - NTone * DTMF_PACKET_INTERVAL) * (fs / 1000) + len);
634      } else {
635        // tone has ended
636        makeRTPheader(rtp_data, NETEQ_CODEC_AVT_PT, seqNo, DTMFtimestamp, ssrc);
637        enc_len = makeDTMFpayload(&rtp_data[12], NTone % 12, 1, 4,
638                                  DTMF_DURATION * (fs / 1000));
639        NTone++;
640        DTMFfirst = 1;
641      }
642
643      /* write RTP packet to file */
644      length = htons(static_cast<unsigned short>(12 + enc_len + 8));
645      plen = htons(static_cast<unsigned short>(12 + enc_len));
646      offset = (uint32_t)sendtime;  //(timestamp/(fs/1000));
647      offset = htonl(offset);
648      if (fwrite(&length, 2, 1, out_file) != 1) {
649        return -1;
650      }
651      if (fwrite(&plen, 2, 1, out_file) != 1) {
652        return -1;
653      }
654      if (fwrite(&offset, 4, 1, out_file) != 1) {
655        return -1;
656      }
657      if (fwrite(rtp_data, 12 + enc_len, 1, out_file) != 1) {
658        return -1;
659      }
660
661      dtmfSent = true;
662    }
663#endif
664
665#ifdef NO_DTMF_OVERDUB
666    /* If DTMF is sent, we should not send any speech packets during the same
667     * time */
668    if (dtmfSent) {
669      enc_len = 0;
670    } else {
671#endif
672      /* encode frame */
673      enc_len =
674          NetEQTest_encode(usedCodec, org_data, packet_size, &rtp_data[12], fs,
675                           &vad, useVAD, bitrate, numChannels);
676
677      if (usingStereo && stereoMode != STEREO_MODE_FRAME && vad == 1) {
678        // interleave the encoded payload for sample-based codecs (not for CNG)
679        stereoInterleave(&rtp_data[12], enc_len, stereoMode);
680      }
681#ifdef NO_DTMF_OVERDUB
682    }
683#endif
684
685    if (enc_len > 0 &&
686        (sendtime <= STOPSENDTIME || sendtime > RESTARTSENDTIME)) {
687      if (useRed) {
688        if (red_len[0] > 0) {
689          memmove(&rtp_data[RTPheaderLen + red_len[0]], &rtp_data[12], enc_len);
690          memcpy(&rtp_data[RTPheaderLen], red_data, red_len[0]);
691
692          red_len[1] = static_cast<uint16_t>(enc_len);
693          red_TS[1] = timestamp;
694          if (vad)
695            red_PT[1] = payloadType;
696          else
697            red_PT[1] = NETEQ_CODEC_CN_PT;
698
699          makeRedundantHeader(rtp_data, red_PT, 2, red_TS, red_len, seqNo++,
700                              ssrc);
701
702          enc_len += red_len[0] + RTPheaderLen - 12;
703        } else {  // do not use redundancy payload for this packet, i.e., only
704                  // last payload
705          memmove(&rtp_data[RTPheaderLen - 4], &rtp_data[12], enc_len);
706          // memcpy(&rtp_data[RTPheaderLen], red_data, red_len[0]);
707
708          red_len[1] = static_cast<uint16_t>(enc_len);
709          red_TS[1] = timestamp;
710          if (vad)
711            red_PT[1] = payloadType;
712          else
713            red_PT[1] = NETEQ_CODEC_CN_PT;
714
715          makeRedundantHeader(rtp_data, red_PT, 2, red_TS, red_len, seqNo++,
716                              ssrc);
717
718          enc_len += red_len[0] + RTPheaderLen - 4 -
719                     12;  // 4 is length of redundancy header (not used)
720        }
721      } else {
722        /* make RTP header */
723        if (vad)  // regular speech data
724          makeRTPheader(rtp_data, payloadType, seqNo++, timestamp, ssrc);
725        else  // CNG data
726          makeRTPheader(rtp_data, NETEQ_CODEC_CN_PT, seqNo++, timestamp, ssrc);
727      }
728#ifdef MULTIPLE_SAME_TIMESTAMP
729      int mult_pack = 0;
730      do {
731#endif  // MULTIPLE_SAME_TIMESTAMP
732        /* write RTP packet to file */
733        length = htons(static_cast<unsigned short>(12 + enc_len + 8));
734        plen = htons(static_cast<unsigned short>(12 + enc_len));
735        offset = (uint32_t)sendtime;
736        //(timestamp/(fs/1000));
737        offset = htonl(offset);
738        if (fwrite(&length, 2, 1, out_file) != 1) {
739          return -1;
740        }
741        if (fwrite(&plen, 2, 1, out_file) != 1) {
742          return -1;
743        }
744        if (fwrite(&offset, 4, 1, out_file) != 1) {
745          return -1;
746        }
747#ifdef RANDOM_DATA
748        for (size_t k = 0; k < 12 + enc_len; k++) {
749          rtp_data[k] = rand() + rand();
750        }
751#endif
752#ifdef RANDOM_PAYLOAD_DATA
753        for (size_t k = 12; k < 12 + enc_len; k++) {
754          rtp_data[k] = rand() + rand();
755        }
756#endif
757        if (fwrite(rtp_data, 12 + enc_len, 1, out_file) != 1) {
758          return -1;
759        }
760#ifdef MULTIPLE_SAME_TIMESTAMP
761      } while ((seqNo % REPEAT_PACKET_DISTANCE == 0) &&
762               (mult_pack++ < REPEAT_PACKET_COUNT));
763#endif  // MULTIPLE_SAME_TIMESTAMP
764
765#ifdef INSERT_OLD_PACKETS
766      if (packet_age >= OLD_PACKET * fs) {
767        if (!first_old_packet) {
768          // send the old packet
769          if (fwrite(&old_length, 2, 1, out_file) != 1) {
770            return -1;
771          }
772          if (fwrite(&old_plen, 2, 1, out_file) != 1) {
773            return -1;
774          }
775          if (fwrite(&offset, 4, 1, out_file) != 1) {
776            return -1;
777          }
778          if (fwrite(old_rtp_data, 12 + old_enc_len, 1, out_file) != 1) {
779            return -1;
780          }
781        }
782        // store current packet as old
783        old_length = length;
784        old_plen = plen;
785        memcpy(old_rtp_data, rtp_data, 12 + enc_len);
786        old_enc_len = enc_len;
787        first_old_packet = 0;
788        packet_age = 0;
789      }
790      packet_age += packet_size;
791#endif
792
793      if (useRed) {
794/* move data to redundancy store */
795#ifdef CODEC_ISAC
796        if (usedCodec == webrtc::NetEqDecoder::kDecoderISAC) {
797          assert(!usingStereo);  // Cannot handle stereo yet
798          red_len[0] = WebRtcIsac_GetRedPayload(ISAC_inst[0], red_data);
799        } else {
800#endif
801          memcpy(red_data, &rtp_data[RTPheaderLen + red_len[0]], enc_len);
802          red_len[0] = red_len[1];
803#ifdef CODEC_ISAC
804        }
805#endif
806        red_TS[0] = red_TS[1];
807        red_PT[0] = red_PT[1];
808      }
809    }
810
811    /* read next frame */
812    len = fread(org_data, 2, packet_size * numChannels, in_file) / numChannels;
813    /* de-interleave if stereo */
814    if (usingStereo) {
815      stereoDeInterleave(org_data, len * numChannels);
816    }
817
818    if (payloadType == NETEQ_CODEC_G722_PT)
819      timestamp += len >> 1;
820    else
821      timestamp += len;
822
823    sendtime += (double)len / (fs / 1000);
824  }
825
826  NetEQTest_free_coders(usedCodec, numChannels);
827  fclose(in_file);
828  fclose(out_file);
829  printf("Done!\n");
830
831  return (0);
832}
833
834/****************/
835/* Subfunctions */
836/****************/
837
838void NetEQTest_GetCodec_and_PT(char* name,
839                               webrtc::NetEqDecoder* codec,
840                               int* PT,
841                               size_t frameLen,
842                               int* fs,
843                               int* bitrate,
844                               int* useRed) {
845  *bitrate = 0; /* Default bitrate setting */
846  *useRed = 0;  /* Default no redundancy */
847
848  if (!strcmp(name, "pcmu")) {
849    *codec = webrtc::NetEqDecoder::kDecoderPCMu;
850    *PT = NETEQ_CODEC_PCMU_PT;
851    *fs = 8000;
852  } else if (!strcmp(name, "pcma")) {
853    *codec = webrtc::NetEqDecoder::kDecoderPCMa;
854    *PT = NETEQ_CODEC_PCMA_PT;
855    *fs = 8000;
856  } else if (!strcmp(name, "pcm16b")) {
857    *codec = webrtc::NetEqDecoder::kDecoderPCM16B;
858    *PT = NETEQ_CODEC_PCM16B_PT;
859    *fs = 8000;
860  } else if (!strcmp(name, "pcm16b_wb")) {
861    *codec = webrtc::NetEqDecoder::kDecoderPCM16Bwb;
862    *PT = NETEQ_CODEC_PCM16B_WB_PT;
863    *fs = 16000;
864  } else if (!strcmp(name, "pcm16b_swb32")) {
865    *codec = webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz;
866    *PT = NETEQ_CODEC_PCM16B_SWB32KHZ_PT;
867    *fs = 32000;
868  } else if (!strcmp(name, "pcm16b_swb48")) {
869    *codec = webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz;
870    *PT = NETEQ_CODEC_PCM16B_SWB48KHZ_PT;
871    *fs = 48000;
872  } else if (!strcmp(name, "g722")) {
873    *codec = webrtc::NetEqDecoder::kDecoderG722;
874    *PT = NETEQ_CODEC_G722_PT;
875    *fs = 16000;
876  } else if ((!strcmp(name, "ilbc")) &&
877             ((frameLen % 240 == 0) || (frameLen % 160 == 0))) {
878    *fs = 8000;
879    *codec = webrtc::NetEqDecoder::kDecoderILBC;
880    *PT = NETEQ_CODEC_ILBC_PT;
881  } else if (!strcmp(name, "isac")) {
882    *fs = 16000;
883    *codec = webrtc::NetEqDecoder::kDecoderISAC;
884    *PT = NETEQ_CODEC_ISAC_PT;
885  } else if (!strcmp(name, "isacswb")) {
886    *fs = 32000;
887    *codec = webrtc::NetEqDecoder::kDecoderISACswb;
888    *PT = NETEQ_CODEC_ISACSWB_PT;
889  } else if (!strcmp(name, "red_pcm")) {
890    *codec = webrtc::NetEqDecoder::kDecoderPCMa;
891    *PT = NETEQ_CODEC_PCMA_PT; /* this will be the PT for the sub-headers */
892    *fs = 8000;
893    *useRed = 1;
894  } else if (!strcmp(name, "red_isac")) {
895    *codec = webrtc::NetEqDecoder::kDecoderISAC;
896    *PT = NETEQ_CODEC_ISAC_PT; /* this will be the PT for the sub-headers */
897    *fs = 16000;
898    *useRed = 1;
899  } else if (!strcmp(name, "opus")) {
900    *codec = webrtc::NetEqDecoder::kDecoderOpus;
901    *PT = NETEQ_CODEC_OPUS_PT; /* this will be the PT for the sub-headers */
902    *fs = 48000;
903  } else {
904    printf("Error: Not a supported codec (%s)\n", name);
905    exit(0);
906  }
907}
908
909int NetEQTest_init_coders(webrtc::NetEqDecoder coder,
910                          size_t enc_frameSize,
911                          int bitrate,
912                          int sampfreq,
913                          int vad,
914                          size_t numChannels) {
915  int ok = 0;
916
917  for (size_t k = 0; k < numChannels; k++) {
918    VAD_inst[k] = WebRtcVad_Create();
919    if (!VAD_inst[k]) {
920      printf("Error: Couldn't allocate memory for VAD instance\n");
921      exit(0);
922    }
923    ok = WebRtcVad_Init(VAD_inst[k]);
924    if (ok == -1) {
925      printf("Error: Initialization of VAD struct failed\n");
926      exit(0);
927    }
928
929#if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
930     defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
931    ok = WebRtcCng_CreateEnc(&CNGenc_inst[k]);
932    if (ok != 0) {
933      printf("Error: Couldn't allocate memory for CNG encoding instance\n");
934      exit(0);
935    }
936    if (sampfreq <= 16000) {
937      ok = WebRtcCng_InitEnc(CNGenc_inst[k], sampfreq, 200, 5);
938      if (ok == -1) {
939        printf("Error: Initialization of CNG struct failed. Error code %d\n",
940               WebRtcCng_GetErrorCodeEnc(CNGenc_inst[k]));
941        exit(0);
942      }
943    }
944#endif
945
946    switch (coder) {
947#ifdef CODEC_PCM16B
948      case webrtc::NetEqDecoder::kDecoderPCM16B:
949#endif
950#ifdef CODEC_PCM16B_WB
951      case webrtc::NetEqDecoder::kDecoderPCM16Bwb:
952#endif
953#ifdef CODEC_PCM16B_32KHZ
954      case webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz:
955#endif
956#ifdef CODEC_PCM16B_48KHZ
957      case webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz:
958#endif
959#ifdef CODEC_G711
960      case webrtc::NetEqDecoder::kDecoderPCMu:
961      case webrtc::NetEqDecoder::kDecoderPCMa:
962#endif
963        // do nothing
964        break;
965#ifdef CODEC_G729
966      case webrtc::kDecoderG729:
967        if (sampfreq == 8000) {
968          if ((enc_frameSize == 80) || (enc_frameSize == 160) ||
969              (enc_frameSize == 240) || (enc_frameSize == 320) ||
970              (enc_frameSize == 400) || (enc_frameSize == 480)) {
971            ok = WebRtcG729_CreateEnc(&G729enc_inst[k]);
972            if (ok != 0) {
973              printf("Error: Couldn't allocate memory for G729 encoding "
974                     "instance\n");
975              exit(0);
976            }
977          } else {
978            printf("\nError: g729 only supports 10, 20, 30, 40, 50 or 60 "
979                   "ms!!\n\n");
980            exit(0);
981          }
982          WebRtcG729_EncoderInit(G729enc_inst[k], vad);
983          if ((vad == 1) && (enc_frameSize != 80)) {
984            printf("\nError - This simulation only supports VAD for G729 at "
985                   "10ms packets (not %" PRIuS "ms)\n", (enc_frameSize >> 3));
986          }
987        } else {
988          printf("\nError - g729 is only developed for 8kHz \n");
989          exit(0);
990        }
991        break;
992#endif
993#ifdef CODEC_G729_1
994      case webrtc::kDecoderG729_1:
995        if (sampfreq == 16000) {
996          if ((enc_frameSize == 320) || (enc_frameSize == 640) ||
997              (enc_frameSize == 960)) {
998            ok = WebRtcG7291_Create(&G729_1_inst[k]);
999            if (ok != 0) {
1000              printf("Error: Couldn't allocate memory for G.729.1 codec "
1001                     "instance\n");
1002              exit(0);
1003            }
1004          } else {
1005            printf("\nError: G.729.1 only supports 20, 40 or 60 ms!!\n\n");
1006            exit(0);
1007          }
1008          if (!(((bitrate >= 12000) && (bitrate <= 32000) &&
1009                 (bitrate % 2000 == 0)) ||
1010                (bitrate == 8000))) {
1011            /* must be 8, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, or 32 kbps */
1012            printf("\nError: G.729.1 bitrate must be 8000 or 12000--32000 in "
1013                   "steps of 2000 bps\n");
1014            exit(0);
1015          }
1016          WebRtcG7291_EncoderInit(G729_1_inst[k], bitrate, 0 /* flag8kHz*/,
1017                                  0 /*flagG729mode*/);
1018        } else {
1019          printf("\nError - G.729.1 input is always 16 kHz \n");
1020          exit(0);
1021        }
1022        break;
1023#endif
1024#ifdef CODEC_SPEEX_8
1025      case webrtc::kDecoderSPEEX_8:
1026        if (sampfreq == 8000) {
1027          if ((enc_frameSize == 160) || (enc_frameSize == 320) ||
1028              (enc_frameSize == 480)) {
1029            ok = WebRtcSpeex_CreateEnc(&SPEEX8enc_inst[k], sampfreq);
1030            if (ok != 0) {
1031              printf("Error: Couldn't allocate memory for Speex encoding "
1032                     "instance\n");
1033              exit(0);
1034            }
1035          } else {
1036            printf("\nError: Speex only supports 20, 40, and 60 ms!!\n\n");
1037            exit(0);
1038          }
1039          if ((vad == 1) && (enc_frameSize != 160)) {
1040            printf("\nError - This simulation only supports VAD for Speex at "
1041                   "20ms packets (not %" PRIuS "ms)\n",
1042                (enc_frameSize >> 3));
1043            vad = 0;
1044          }
1045          ok = WebRtcSpeex_EncoderInit(SPEEX8enc_inst[k], 0 /*vbr*/,
1046                                       3 /*complexity*/, vad);
1047          if (ok != 0)
1048            exit(0);
1049        } else {
1050          printf("\nError - Speex8 called with sample frequency other than 8 "
1051                 "kHz.\n\n");
1052        }
1053        break;
1054#endif
1055#ifdef CODEC_SPEEX_16
1056      case webrtc::kDecoderSPEEX_16:
1057        if (sampfreq == 16000) {
1058          if ((enc_frameSize == 320) || (enc_frameSize == 640) ||
1059              (enc_frameSize == 960)) {
1060            ok = WebRtcSpeex_CreateEnc(&SPEEX16enc_inst[k], sampfreq);
1061            if (ok != 0) {
1062              printf("Error: Couldn't allocate memory for Speex encoding "
1063                     "instance\n");
1064              exit(0);
1065            }
1066          } else {
1067            printf("\nError: Speex only supports 20, 40, and 60 ms!!\n\n");
1068            exit(0);
1069          }
1070          if ((vad == 1) && (enc_frameSize != 320)) {
1071            printf("\nError - This simulation only supports VAD for Speex at "
1072                   "20ms packets (not %" PRIuS "ms)\n",
1073                (enc_frameSize >> 4));
1074            vad = 0;
1075          }
1076          ok = WebRtcSpeex_EncoderInit(SPEEX16enc_inst[k], 0 /*vbr*/,
1077                                       3 /*complexity*/, vad);
1078          if (ok != 0)
1079            exit(0);
1080        } else {
1081          printf("\nError - Speex16 called with sample frequency other than 16 "
1082                 "kHz.\n\n");
1083        }
1084        break;
1085#endif
1086
1087#ifdef CODEC_G722_1_16
1088      case webrtc::kDecoderG722_1_16:
1089        if (sampfreq == 16000) {
1090          ok = WebRtcG7221_CreateEnc16(&G722_1_16enc_inst[k]);
1091          if (ok != 0) {
1092            printf("Error: Couldn't allocate memory for G.722.1 instance\n");
1093            exit(0);
1094          }
1095          if (enc_frameSize == 320) {
1096          } else {
1097            printf("\nError: G722.1 only supports 20 ms!!\n\n");
1098            exit(0);
1099          }
1100          WebRtcG7221_EncoderInit16((G722_1_16_encinst_t*)G722_1_16enc_inst[k]);
1101        } else {
1102          printf("\nError - G722.1 is only developed for 16kHz \n");
1103          exit(0);
1104        }
1105        break;
1106#endif
1107#ifdef CODEC_G722_1_24
1108      case webrtc::kDecoderG722_1_24:
1109        if (sampfreq == 16000) {
1110          ok = WebRtcG7221_CreateEnc24(&G722_1_24enc_inst[k]);
1111          if (ok != 0) {
1112            printf("Error: Couldn't allocate memory for G.722.1 instance\n");
1113            exit(0);
1114          }
1115          if (enc_frameSize == 320) {
1116          } else {
1117            printf("\nError: G722.1 only supports 20 ms!!\n\n");
1118            exit(0);
1119          }
1120          WebRtcG7221_EncoderInit24((G722_1_24_encinst_t*)G722_1_24enc_inst[k]);
1121        } else {
1122          printf("\nError - G722.1 is only developed for 16kHz \n");
1123          exit(0);
1124        }
1125        break;
1126#endif
1127#ifdef CODEC_G722_1_32
1128      case webrtc::kDecoderG722_1_32:
1129        if (sampfreq == 16000) {
1130          ok = WebRtcG7221_CreateEnc32(&G722_1_32enc_inst[k]);
1131          if (ok != 0) {
1132            printf("Error: Couldn't allocate memory for G.722.1 instance\n");
1133            exit(0);
1134          }
1135          if (enc_frameSize == 320) {
1136          } else {
1137            printf("\nError: G722.1 only supports 20 ms!!\n\n");
1138            exit(0);
1139          }
1140          WebRtcG7221_EncoderInit32((G722_1_32_encinst_t*)G722_1_32enc_inst[k]);
1141        } else {
1142          printf("\nError - G722.1 is only developed for 16kHz \n");
1143          exit(0);
1144        }
1145        break;
1146#endif
1147#ifdef CODEC_G722_1C_24
1148      case webrtc::kDecoderG722_1C_24:
1149        if (sampfreq == 32000) {
1150          ok = WebRtcG7221C_CreateEnc24(&G722_1C_24enc_inst[k]);
1151          if (ok != 0) {
1152            printf("Error: Couldn't allocate memory for G.722.1C instance\n");
1153            exit(0);
1154          }
1155          if (enc_frameSize == 640) {
1156          } else {
1157            printf("\nError: G722.1 C only supports 20 ms!!\n\n");
1158            exit(0);
1159          }
1160          WebRtcG7221C_EncoderInit24(
1161              (G722_1C_24_encinst_t*)G722_1C_24enc_inst[k]);
1162        } else {
1163          printf("\nError - G722.1 C is only developed for 32kHz \n");
1164          exit(0);
1165        }
1166        break;
1167#endif
1168#ifdef CODEC_G722_1C_32
1169      case webrtc::kDecoderG722_1C_32:
1170        if (sampfreq == 32000) {
1171          ok = WebRtcG7221C_CreateEnc32(&G722_1C_32enc_inst[k]);
1172          if (ok != 0) {
1173            printf("Error: Couldn't allocate memory for G.722.1C instance\n");
1174            exit(0);
1175          }
1176          if (enc_frameSize == 640) {
1177          } else {
1178            printf("\nError: G722.1 C only supports 20 ms!!\n\n");
1179            exit(0);
1180          }
1181          WebRtcG7221C_EncoderInit32(
1182              (G722_1C_32_encinst_t*)G722_1C_32enc_inst[k]);
1183        } else {
1184          printf("\nError - G722.1 C is only developed for 32kHz \n");
1185          exit(0);
1186        }
1187        break;
1188#endif
1189#ifdef CODEC_G722_1C_48
1190      case webrtc::kDecoderG722_1C_48:
1191        if (sampfreq == 32000) {
1192          ok = WebRtcG7221C_CreateEnc48(&G722_1C_48enc_inst[k]);
1193          if (ok != 0) {
1194            printf("Error: Couldn't allocate memory for G.722.1C instance\n");
1195            exit(0);
1196          }
1197          if (enc_frameSize == 640) {
1198          } else {
1199            printf("\nError: G722.1 C only supports 20 ms!!\n\n");
1200            exit(0);
1201          }
1202          WebRtcG7221C_EncoderInit48(
1203              (G722_1C_48_encinst_t*)G722_1C_48enc_inst[k]);
1204        } else {
1205          printf("\nError - G722.1 C is only developed for 32kHz \n");
1206          exit(0);
1207        }
1208        break;
1209#endif
1210#ifdef CODEC_G722
1211      case webrtc::NetEqDecoder::kDecoderG722:
1212        if (sampfreq == 16000) {
1213          if (enc_frameSize % 2 == 0) {
1214          } else {
1215            printf(
1216                "\nError - g722 frames must have an even number of "
1217                "enc_frameSize\n");
1218            exit(0);
1219          }
1220          WebRtcG722_CreateEncoder(&g722EncState[k]);
1221          WebRtcG722_EncoderInit(g722EncState[k]);
1222        } else {
1223          printf("\nError - g722 is only developed for 16kHz \n");
1224          exit(0);
1225        }
1226        break;
1227#endif
1228#ifdef CODEC_AMR
1229      case webrtc::kDecoderAMR:
1230        if (sampfreq == 8000) {
1231          ok = WebRtcAmr_CreateEnc(&AMRenc_inst[k]);
1232          if (ok != 0) {
1233            printf(
1234                "Error: Couldn't allocate memory for AMR encoding instance\n");
1235            exit(0);
1236          }
1237          if ((enc_frameSize == 160) || (enc_frameSize == 320) ||
1238              (enc_frameSize == 480)) {
1239          } else {
1240            printf("\nError - AMR must have a multiple of 160 enc_frameSize\n");
1241            exit(0);
1242          }
1243          WebRtcAmr_EncoderInit(AMRenc_inst[k], vad);
1244          WebRtcAmr_EncodeBitmode(AMRenc_inst[k], AMRBandwidthEfficient);
1245          AMR_bitrate = bitrate;
1246        } else {
1247          printf("\nError - AMR is only developed for 8kHz \n");
1248          exit(0);
1249        }
1250        break;
1251#endif
1252#ifdef CODEC_AMRWB
1253      case webrtc::kDecoderAMRWB:
1254        if (sampfreq == 16000) {
1255          ok = WebRtcAmrWb_CreateEnc(&AMRWBenc_inst[k]);
1256          if (ok != 0) {
1257            printf("Error: Couldn't allocate memory for AMRWB encoding "
1258                   "instance\n");
1259            exit(0);
1260          }
1261          if (((enc_frameSize / 320) > 3) || ((enc_frameSize % 320) != 0)) {
1262            printf("\nError - AMRwb must have frameSize of 20, 40 or 60ms\n");
1263            exit(0);
1264          }
1265          WebRtcAmrWb_EncoderInit(AMRWBenc_inst[k], vad);
1266          if (bitrate == 7000) {
1267            AMRWB_bitrate = AMRWB_MODE_7k;
1268          } else if (bitrate == 9000) {
1269            AMRWB_bitrate = AMRWB_MODE_9k;
1270          } else if (bitrate == 12000) {
1271            AMRWB_bitrate = AMRWB_MODE_12k;
1272          } else if (bitrate == 14000) {
1273            AMRWB_bitrate = AMRWB_MODE_14k;
1274          } else if (bitrate == 16000) {
1275            AMRWB_bitrate = AMRWB_MODE_16k;
1276          } else if (bitrate == 18000) {
1277            AMRWB_bitrate = AMRWB_MODE_18k;
1278          } else if (bitrate == 20000) {
1279            AMRWB_bitrate = AMRWB_MODE_20k;
1280          } else if (bitrate == 23000) {
1281            AMRWB_bitrate = AMRWB_MODE_23k;
1282          } else if (bitrate == 24000) {
1283            AMRWB_bitrate = AMRWB_MODE_24k;
1284          }
1285          WebRtcAmrWb_EncodeBitmode(AMRWBenc_inst[k], AMRBandwidthEfficient);
1286
1287        } else {
1288          printf("\nError - AMRwb is only developed for 16kHz \n");
1289          exit(0);
1290        }
1291        break;
1292#endif
1293#ifdef CODEC_ILBC
1294      case webrtc::NetEqDecoder::kDecoderILBC:
1295        if (sampfreq == 8000) {
1296          ok = WebRtcIlbcfix_EncoderCreate(&iLBCenc_inst[k]);
1297          if (ok != 0) {
1298            printf("Error: Couldn't allocate memory for iLBC encoding "
1299                   "instance\n");
1300            exit(0);
1301          }
1302          if ((enc_frameSize == 160) || (enc_frameSize == 240) ||
1303              (enc_frameSize == 320) || (enc_frameSize == 480)) {
1304          } else {
1305            printf("\nError - iLBC only supports 160, 240, 320 and 480 "
1306                   "enc_frameSize (20, 30, 40 and 60 ms)\n");
1307            exit(0);
1308          }
1309          if ((enc_frameSize == 160) || (enc_frameSize == 320)) {
1310            /* 20 ms version */
1311            WebRtcIlbcfix_EncoderInit(iLBCenc_inst[k], 20);
1312          } else {
1313            /* 30 ms version */
1314            WebRtcIlbcfix_EncoderInit(iLBCenc_inst[k], 30);
1315          }
1316        } else {
1317          printf("\nError - iLBC is only developed for 8kHz \n");
1318          exit(0);
1319        }
1320        break;
1321#endif
1322#ifdef CODEC_ISAC
1323      case webrtc::NetEqDecoder::kDecoderISAC:
1324        if (sampfreq == 16000) {
1325          ok = WebRtcIsac_Create(&ISAC_inst[k]);
1326          if (ok != 0) {
1327            printf("Error: Couldn't allocate memory for iSAC instance\n");
1328            exit(0);
1329          }
1330          if ((enc_frameSize == 480) || (enc_frameSize == 960)) {
1331          } else {
1332            printf("\nError - iSAC only supports frameSize (30 and 60 ms)\n");
1333            exit(0);
1334          }
1335          WebRtcIsac_EncoderInit(ISAC_inst[k], 1);
1336          if ((bitrate < 10000) || (bitrate > 32000)) {
1337            printf("\nError - iSAC bitrate has to be between 10000 and 32000 "
1338                   "bps (not %i)\n",
1339                bitrate);
1340            exit(0);
1341          }
1342          WebRtcIsac_Control(ISAC_inst[k], bitrate,
1343                             static_cast<int>(enc_frameSize >> 4));
1344        } else {
1345          printf("\nError - iSAC only supports 480 or 960 enc_frameSize (30 or "
1346                 "60 ms)\n");
1347          exit(0);
1348        }
1349        break;
1350#endif
1351#ifdef NETEQ_ISACFIX_CODEC
1352      case webrtc::kDecoderISAC:
1353        if (sampfreq == 16000) {
1354          ok = WebRtcIsacfix_Create(&ISAC_inst[k]);
1355          if (ok != 0) {
1356            printf("Error: Couldn't allocate memory for iSAC instance\n");
1357            exit(0);
1358          }
1359          if ((enc_frameSize == 480) || (enc_frameSize == 960)) {
1360          } else {
1361            printf("\nError - iSAC only supports frameSize (30 and 60 ms)\n");
1362            exit(0);
1363          }
1364          WebRtcIsacfix_EncoderInit(ISAC_inst[k], 1);
1365          if ((bitrate < 10000) || (bitrate > 32000)) {
1366            printf("\nError - iSAC bitrate has to be between 10000 and 32000 "
1367                   "bps (not %i)\n", bitrate);
1368            exit(0);
1369          }
1370          WebRtcIsacfix_Control(ISAC_inst[k], bitrate, enc_frameSize >> 4);
1371        } else {
1372          printf("\nError - iSAC only supports 480 or 960 enc_frameSize (30 or "
1373                 "60 ms)\n");
1374          exit(0);
1375        }
1376        break;
1377#endif
1378#ifdef CODEC_ISAC_SWB
1379      case webrtc::NetEqDecoder::kDecoderISACswb:
1380        if (sampfreq == 32000) {
1381          ok = WebRtcIsac_Create(&ISACSWB_inst[k]);
1382          if (ok != 0) {
1383            printf("Error: Couldn't allocate memory for iSAC SWB instance\n");
1384            exit(0);
1385          }
1386          if (enc_frameSize == 960) {
1387          } else {
1388            printf("\nError - iSAC SWB only supports frameSize 30 ms\n");
1389            exit(0);
1390          }
1391          ok = WebRtcIsac_SetEncSampRate(ISACSWB_inst[k], 32000);
1392          if (ok != 0) {
1393            printf("Error: Couldn't set sample rate for iSAC SWB instance\n");
1394            exit(0);
1395          }
1396          WebRtcIsac_EncoderInit(ISACSWB_inst[k], 1);
1397          if ((bitrate < 32000) || (bitrate > 56000)) {
1398            printf("\nError - iSAC SWB bitrate has to be between 32000 and "
1399                   "56000 bps (not %i)\n", bitrate);
1400            exit(0);
1401          }
1402          WebRtcIsac_Control(ISACSWB_inst[k], bitrate,
1403                             static_cast<int>(enc_frameSize >> 5));
1404        } else {
1405          printf("\nError - iSAC SWB only supports 960 enc_frameSize (30 "
1406                 "ms)\n");
1407          exit(0);
1408        }
1409        break;
1410#endif
1411#ifdef CODEC_GSMFR
1412      case webrtc::kDecoderGSMFR:
1413        if (sampfreq == 8000) {
1414          ok = WebRtcGSMFR_CreateEnc(&GSMFRenc_inst[k]);
1415          if (ok != 0) {
1416            printf("Error: Couldn't allocate memory for GSM FR encoding "
1417                   "instance\n");
1418            exit(0);
1419          }
1420          if ((enc_frameSize == 160) || (enc_frameSize == 320) ||
1421              (enc_frameSize == 480)) {
1422          } else {
1423            printf("\nError - GSM FR must have a multiple of 160 "
1424                   "enc_frameSize\n");
1425            exit(0);
1426          }
1427          WebRtcGSMFR_EncoderInit(GSMFRenc_inst[k], 0);
1428        } else {
1429          printf("\nError - GSM FR is only developed for 8kHz \n");
1430          exit(0);
1431        }
1432        break;
1433#endif
1434#ifdef CODEC_OPUS
1435      case webrtc::NetEqDecoder::kDecoderOpus:
1436        ok = WebRtcOpus_EncoderCreate(&opus_inst[k], 1, 0);
1437        if (ok != 0) {
1438          printf("Error: Couldn't allocate memory for Opus encoding "
1439                 "instance\n");
1440          exit(0);
1441        }
1442        WebRtcOpus_EnableFec(opus_inst[k]);
1443        WebRtcOpus_SetPacketLossRate(opus_inst[k], 5);
1444        break;
1445#endif
1446      default:
1447        printf("Error: unknown codec in call to NetEQTest_init_coders.\n");
1448        exit(0);
1449        break;
1450    }
1451    if (ok != 0) {
1452      return (ok);
1453    }
1454  }  // end for
1455
1456  return (0);
1457}
1458
1459int NetEQTest_free_coders(webrtc::NetEqDecoder coder, size_t numChannels) {
1460  for (size_t k = 0; k < numChannels; k++) {
1461    WebRtcVad_Free(VAD_inst[k]);
1462#if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \
1463     defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48))
1464    WebRtcCng_FreeEnc(CNGenc_inst[k]);
1465#endif
1466
1467    switch (coder) {
1468#ifdef CODEC_PCM16B
1469      case webrtc::NetEqDecoder::kDecoderPCM16B:
1470#endif
1471#ifdef CODEC_PCM16B_WB
1472      case webrtc::NetEqDecoder::kDecoderPCM16Bwb:
1473#endif
1474#ifdef CODEC_PCM16B_32KHZ
1475      case webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz:
1476#endif
1477#ifdef CODEC_PCM16B_48KHZ
1478      case webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz:
1479#endif
1480#ifdef CODEC_G711
1481      case webrtc::NetEqDecoder::kDecoderPCMu:
1482      case webrtc::NetEqDecoder::kDecoderPCMa:
1483#endif
1484        // do nothing
1485        break;
1486#ifdef CODEC_G729
1487      case webrtc::NetEqDecoder::kDecoderG729:
1488        WebRtcG729_FreeEnc(G729enc_inst[k]);
1489        break;
1490#endif
1491#ifdef CODEC_G729_1
1492      case webrtc::NetEqDecoder::kDecoderG729_1:
1493        WebRtcG7291_Free(G729_1_inst[k]);
1494        break;
1495#endif
1496#ifdef CODEC_SPEEX_8
1497      case webrtc::NetEqDecoder::kDecoderSPEEX_8:
1498        WebRtcSpeex_FreeEnc(SPEEX8enc_inst[k]);
1499        break;
1500#endif
1501#ifdef CODEC_SPEEX_16
1502      case webrtc::NetEqDecoder::kDecoderSPEEX_16:
1503        WebRtcSpeex_FreeEnc(SPEEX16enc_inst[k]);
1504        break;
1505#endif
1506
1507#ifdef CODEC_G722_1_16
1508      case webrtc::NetEqDecoder::kDecoderG722_1_16:
1509        WebRtcG7221_FreeEnc16(G722_1_16enc_inst[k]);
1510        break;
1511#endif
1512#ifdef CODEC_G722_1_24
1513      case webrtc::NetEqDecoder::kDecoderG722_1_24:
1514        WebRtcG7221_FreeEnc24(G722_1_24enc_inst[k]);
1515        break;
1516#endif
1517#ifdef CODEC_G722_1_32
1518      case webrtc::NetEqDecoder::kDecoderG722_1_32:
1519        WebRtcG7221_FreeEnc32(G722_1_32enc_inst[k]);
1520        break;
1521#endif
1522#ifdef CODEC_G722_1C_24
1523      case webrtc::NetEqDecoder::kDecoderG722_1C_24:
1524        WebRtcG7221C_FreeEnc24(G722_1C_24enc_inst[k]);
1525        break;
1526#endif
1527#ifdef CODEC_G722_1C_32
1528      case webrtc::NetEqDecoder::kDecoderG722_1C_32:
1529        WebRtcG7221C_FreeEnc32(G722_1C_32enc_inst[k]);
1530        break;
1531#endif
1532#ifdef CODEC_G722_1C_48
1533      case webrtc::NetEqDecoder::kDecoderG722_1C_48:
1534        WebRtcG7221C_FreeEnc48(G722_1C_48enc_inst[k]);
1535        break;
1536#endif
1537#ifdef CODEC_G722
1538      case webrtc::NetEqDecoder::kDecoderG722:
1539        WebRtcG722_FreeEncoder(g722EncState[k]);
1540        break;
1541#endif
1542#ifdef CODEC_AMR
1543      case webrtc::NetEqDecoder::kDecoderAMR:
1544        WebRtcAmr_FreeEnc(AMRenc_inst[k]);
1545        break;
1546#endif
1547#ifdef CODEC_AMRWB
1548      case webrtc::NetEqDecoder::kDecoderAMRWB:
1549        WebRtcAmrWb_FreeEnc(AMRWBenc_inst[k]);
1550        break;
1551#endif
1552#ifdef CODEC_ILBC
1553      case webrtc::NetEqDecoder::kDecoderILBC:
1554        WebRtcIlbcfix_EncoderFree(iLBCenc_inst[k]);
1555        break;
1556#endif
1557#ifdef CODEC_ISAC
1558      case webrtc::NetEqDecoder::kDecoderISAC:
1559        WebRtcIsac_Free(ISAC_inst[k]);
1560        break;
1561#endif
1562#ifdef NETEQ_ISACFIX_CODEC
1563      case webrtc::NetEqDecoder::kDecoderISAC:
1564        WebRtcIsacfix_Free(ISAC_inst[k]);
1565        break;
1566#endif
1567#ifdef CODEC_ISAC_SWB
1568      case webrtc::NetEqDecoder::kDecoderISACswb:
1569        WebRtcIsac_Free(ISACSWB_inst[k]);
1570        break;
1571#endif
1572#ifdef CODEC_GSMFR
1573      case webrtc::NetEqDecoder::kDecoderGSMFR:
1574        WebRtcGSMFR_FreeEnc(GSMFRenc_inst[k]);
1575        break;
1576#endif
1577#ifdef CODEC_OPUS
1578      case webrtc::NetEqDecoder::kDecoderOpus:
1579        WebRtcOpus_EncoderFree(opus_inst[k]);
1580        break;
1581#endif
1582      default:
1583        printf("Error: unknown codec in call to NetEQTest_init_coders.\n");
1584        exit(0);
1585        break;
1586    }
1587  }
1588
1589  return (0);
1590}
1591
1592size_t NetEQTest_encode(webrtc::NetEqDecoder coder,
1593                        int16_t* indata,
1594                        size_t frameLen,
1595                        unsigned char* encoded,
1596                        int sampleRate,
1597                        int* vad,
1598                        int useVAD,
1599                        int bitrate,
1600                        size_t numChannels) {
1601  size_t cdlen = 0;
1602  int16_t* tempdata;
1603  static int first_cng = 1;
1604  size_t tempLen;
1605  *vad = 1;
1606
1607  // check VAD first
1608  if (useVAD) {
1609    *vad = 0;
1610
1611    size_t sampleRate_10 = static_cast<size_t>(10 * sampleRate / 1000);
1612    size_t sampleRate_20 = static_cast<size_t>(20 * sampleRate / 1000);
1613    size_t sampleRate_30 = static_cast<size_t>(30 * sampleRate / 1000);
1614    for (size_t k = 0; k < numChannels; k++) {
1615      tempLen = frameLen;
1616      tempdata = &indata[k * frameLen];
1617      int localVad = 0;
1618      /* Partition the signal and test each chunk for VAD.
1619         All chunks must be VAD=0 to produce a total VAD=0. */
1620      while (tempLen >= sampleRate_10) {
1621        if ((tempLen % sampleRate_30) == 0) {  // tempLen is multiple of 30ms
1622          localVad |= WebRtcVad_Process(VAD_inst[k], sampleRate, tempdata,
1623                                        sampleRate_30);
1624          tempdata += sampleRate_30;
1625          tempLen -= sampleRate_30;
1626        } else if (tempLen >= sampleRate_20) {  // tempLen >= 20ms
1627          localVad |= WebRtcVad_Process(VAD_inst[k], sampleRate, tempdata,
1628                                        sampleRate_20);
1629          tempdata += sampleRate_20;
1630          tempLen -= sampleRate_20;
1631        } else {  // use 10ms
1632          localVad |= WebRtcVad_Process(VAD_inst[k], sampleRate, tempdata,
1633                                        sampleRate_10);
1634          tempdata += sampleRate_10;
1635          tempLen -= sampleRate_10;
1636        }
1637      }
1638
1639      // aggregate all VAD decisions over all channels
1640      *vad |= localVad;
1641    }
1642
1643    if (!*vad) {
1644      // all channels are silent
1645      cdlen = 0;
1646      for (size_t k = 0; k < numChannels; k++) {
1647        WebRtcCng_Encode(CNGenc_inst[k], &indata[k * frameLen],
1648                         (frameLen <= 640 ? frameLen : 640) /* max 640 */,
1649                         encoded, &tempLen, first_cng);
1650        encoded += tempLen;
1651        cdlen += tempLen;
1652      }
1653      *vad = 0;
1654      first_cng = 0;
1655      return (cdlen);
1656    }
1657  }
1658
1659  // loop over all channels
1660  size_t totalLen = 0;
1661
1662  for (size_t k = 0; k < numChannels; k++) {
1663    /* Encode with the selected coder type */
1664    if (coder == webrtc::NetEqDecoder::kDecoderPCMu) { /*g711 u-law */
1665#ifdef CODEC_G711
1666      cdlen = WebRtcG711_EncodeU(indata, frameLen, encoded);
1667#endif
1668    } else if (coder == webrtc::NetEqDecoder::kDecoderPCMa) { /*g711 A-law */
1669#ifdef CODEC_G711
1670      cdlen = WebRtcG711_EncodeA(indata, frameLen, encoded);
1671    }
1672#endif
1673#ifdef CODEC_PCM16B
1674    else if ((coder == webrtc::NetEqDecoder::kDecoderPCM16B) ||
1675             (coder == webrtc::NetEqDecoder::kDecoderPCM16Bwb) ||
1676             (coder == webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz) ||
1677             (coder == webrtc::NetEqDecoder::
1678                           kDecoderPCM16Bswb48kHz)) { /*pcm16b (8kHz, 16kHz,
1679                                                        32kHz or 48kHz) */
1680      cdlen = WebRtcPcm16b_Encode(indata, frameLen, encoded);
1681    }
1682#endif
1683#ifdef CODEC_G722
1684    else if (coder == webrtc::NetEqDecoder::kDecoderG722) { /*g722 */
1685      cdlen = WebRtcG722_Encode(g722EncState[k], indata, frameLen, encoded);
1686      assert(cdlen == frameLen >> 1);
1687    }
1688#endif
1689#ifdef CODEC_ILBC
1690    else if (coder == webrtc::NetEqDecoder::kDecoderILBC) { /*iLBC */
1691      cdlen = static_cast<size_t>(std::max(
1692          WebRtcIlbcfix_Encode(iLBCenc_inst[k], indata, frameLen, encoded), 0));
1693    }
1694#endif
1695#if (defined(CODEC_ISAC) || \
1696     defined(NETEQ_ISACFIX_CODEC))            // TODO(hlundin): remove all
1697                                              // NETEQ_ISACFIX_CODEC
1698    else if (coder == webrtc::NetEqDecoder::kDecoderISAC) { /*iSAC */
1699      int noOfCalls = 0;
1700      int res = 0;
1701      while (res <= 0) {
1702#ifdef CODEC_ISAC /* floating point */
1703        res =
1704            WebRtcIsac_Encode(ISAC_inst[k], &indata[noOfCalls * 160], encoded);
1705#else /* fixed point */
1706        res = WebRtcIsacfix_Encode(ISAC_inst[k], &indata[noOfCalls * 160],
1707                                   encoded);
1708#endif
1709        noOfCalls++;
1710      }
1711      cdlen = static_cast<size_t>(res);
1712    }
1713#endif
1714#ifdef CODEC_ISAC_SWB
1715    else if (coder == webrtc::NetEqDecoder::kDecoderISACswb) { /* iSAC SWB */
1716      int noOfCalls = 0;
1717      int res = 0;
1718      while (res <= 0) {
1719        res = WebRtcIsac_Encode(ISACSWB_inst[k], &indata[noOfCalls * 320],
1720                                encoded);
1721        noOfCalls++;
1722      }
1723      cdlen = static_cast<size_t>(res);
1724    }
1725#endif
1726#ifdef CODEC_OPUS
1727    cdlen = WebRtcOpus_Encode(opus_inst[k], indata, frameLen, kRtpDataSize - 12,
1728                              encoded);
1729    RTC_CHECK_GT(cdlen, 0u);
1730#endif
1731    indata += frameLen;
1732    encoded += cdlen;
1733    totalLen += cdlen;
1734
1735  }  // end for
1736
1737  first_cng = 1;
1738  return (totalLen);
1739}
1740
1741void makeRTPheader(unsigned char* rtp_data,
1742                   int payloadType,
1743                   int seqNo,
1744                   uint32_t timestamp,
1745                   uint32_t ssrc) {
1746  rtp_data[0] = 0x80;
1747  rtp_data[1] = payloadType & 0xFF;
1748  rtp_data[2] = (seqNo >> 8) & 0xFF;
1749  rtp_data[3] = seqNo & 0xFF;
1750  rtp_data[4] = timestamp >> 24;
1751  rtp_data[5] = (timestamp >> 16) & 0xFF;
1752  rtp_data[6] = (timestamp >> 8) & 0xFF;
1753  rtp_data[7] = timestamp & 0xFF;
1754  rtp_data[8] = ssrc >> 24;
1755  rtp_data[9] = (ssrc >> 16) & 0xFF;
1756  rtp_data[10] = (ssrc >> 8) & 0xFF;
1757  rtp_data[11] = ssrc & 0xFF;
1758}
1759
1760int makeRedundantHeader(unsigned char* rtp_data,
1761                        int* payloadType,
1762                        int numPayloads,
1763                        uint32_t* timestamp,
1764                        uint16_t* blockLen,
1765                        int seqNo,
1766                        uint32_t ssrc) {
1767  int i;
1768  unsigned char* rtpPointer;
1769  uint16_t offset;
1770
1771  /* first create "standard" RTP header */
1772  makeRTPheader(rtp_data, NETEQ_CODEC_RED_PT, seqNo, timestamp[numPayloads - 1],
1773                ssrc);
1774
1775  rtpPointer = &rtp_data[12];
1776
1777  /* add one sub-header for each redundant payload (not the primary) */
1778  for (i = 0; i < numPayloads - 1; i++) {
1779    if (blockLen[i] > 0) {
1780      offset = static_cast<uint16_t>(timestamp[numPayloads - 1] - timestamp[i]);
1781
1782      // Byte |0|       |1       2     |  3       |
1783      // Bit  |0|1234567|01234567012345|6701234567|
1784      //      |F|payload|   timestamp  |   block  |
1785      //      | |  type |    offset    |  length  |
1786      rtpPointer[0] = (payloadType[i] & 0x7F) | 0x80;
1787      rtpPointer[1] = (offset >> 6) & 0xFF;
1788      rtpPointer[2] = ((offset & 0x3F) << 2) | ((blockLen[i] >> 8) & 0x03);
1789      rtpPointer[3] = blockLen[i] & 0xFF;
1790
1791      rtpPointer += 4;
1792    }
1793  }
1794
1795  // Bit  |0|1234567|
1796  //      |0|payload|
1797  //      | |  type |
1798  rtpPointer[0] = payloadType[numPayloads - 1] & 0x7F;
1799  ++rtpPointer;
1800
1801  return rtpPointer - rtp_data;  // length of header in bytes
1802}
1803
1804size_t makeDTMFpayload(unsigned char* payload_data,
1805                       int Event,
1806                       int End,
1807                       int Volume,
1808                       int Duration) {
1809  unsigned char E, R, V;
1810  R = 0;
1811  V = (unsigned char)Volume;
1812  if (End == 0) {
1813    E = 0x00;
1814  } else {
1815    E = 0x80;
1816  }
1817  payload_data[0] = (unsigned char)Event;
1818  payload_data[1] = (unsigned char)(E | R | V);
1819  // Duration equals 8 times time_ms, default is 8000 Hz.
1820  payload_data[2] = (unsigned char)((Duration >> 8) & 0xFF);
1821  payload_data[3] = (unsigned char)(Duration & 0xFF);
1822  return (4);
1823}
1824
1825void stereoDeInterleave(int16_t* audioSamples, size_t numSamples) {
1826  int16_t* tempVec;
1827  int16_t* readPtr, *writeL, *writeR;
1828
1829  if (numSamples == 0)
1830    return;
1831
1832  tempVec = (int16_t*)malloc(sizeof(int16_t) * numSamples);
1833  if (tempVec == NULL) {
1834    printf("Error allocating memory\n");
1835    exit(0);
1836  }
1837
1838  memcpy(tempVec, audioSamples, numSamples * sizeof(int16_t));
1839
1840  writeL = audioSamples;
1841  writeR = &audioSamples[numSamples / 2];
1842  readPtr = tempVec;
1843
1844  for (size_t k = 0; k < numSamples; k += 2) {
1845    *writeL = *readPtr;
1846    readPtr++;
1847    *writeR = *readPtr;
1848    readPtr++;
1849    writeL++;
1850    writeR++;
1851  }
1852
1853  free(tempVec);
1854}
1855
1856void stereoInterleave(unsigned char* data, size_t dataLen, size_t stride) {
1857  unsigned char* ptrL, *ptrR;
1858  unsigned char temp[10];
1859
1860  if (stride > 10) {
1861    exit(0);
1862  }
1863
1864  if (dataLen % 1 != 0) {
1865    // must be even number of samples
1866    printf("Error: cannot interleave odd sample number\n");
1867    exit(0);
1868  }
1869
1870  ptrL = data + stride;
1871  ptrR = &data[dataLen / 2];
1872
1873  while (ptrL < ptrR) {
1874    // copy from right pointer to temp
1875    memcpy(temp, ptrR, stride);
1876
1877    // shift data between pointers
1878    memmove(ptrL + stride, ptrL, ptrR - ptrL);
1879
1880    // copy from temp to left pointer
1881    memcpy(ptrL, temp, stride);
1882
1883    // advance pointers
1884    ptrL += stride * 2;
1885    ptrR += stride;
1886  }
1887}
1888