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