comparison intercom/intercomd.cpp @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children c6c5a16ce2f2
comparison
equal deleted inserted replaced
1:9cadc470e3da 2:13be24d74cd2
1 /* intercomd.cpp
2 *
3 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005).
4 * All Rights Reserved.
5 * Author: Andre Adrian
6 *
7 * Voice over IP Intercom with Telephone conference and Acoustic Echo
8 * Cancellation using unicast RTP messages (RFC3550, RFC3551)
9 *
10 * Attention. This source code is for Linux only! You need:
11 * same endian for CPU and soundcard for 16bit PCM audio sample
12 * Open Source Sound (OSS) support
13 * ALSA Sound support for hardware (2-channel) AEC
14 *
15 * Format Sourcecode:
16 indent -kr -i2 -nlp -ci2 -l72 -lc72 -nut intercomd.cpp
17 *
18 * global Replace (one replace per line only!)
19 sed -i "s/PIT_MIN/G729_PIT_MIN/" *.h *.cpp
20 *
21 */
22
23 const char VERSION[] = "0.4.1";
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <math.h>
29 #include <stdarg.h>
30 #include <syslog.h>
31
32 /* Error handling */
33 #include <assert.h>
34 #include <errno.h>
35 extern int errno;
36
37 /* low level io */
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <sys/ioctl.h>
42 #include <unistd.h>
43 #include <sys/select.h>
44 #include <sys/time.h>
45
46 /* Socket io */
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50
51 /* IETF iLBC codec */
52 extern "C" {
53 #include "ilbc/iLBC_define.h"
54 #include "ilbc/iLBC_encode.h"
55 #include "ilbc/iLBC_decode.h"
56 }
57
58 /* ITU-T G.711 codec */
59 extern "C" {
60 #include "g711/g711.h"
61 }
62
63 /* 3GPP GSM codec */
64 extern "C" {
65 #include "gsm/private.h"
66 #include "gsm/gsm.h"
67 #include "gsm/rpeltp.h"
68 }
69
70 /* ITU-T G.726 codec */
71 extern "C" {
72 #include "g726/g726.h"
73 #include "g726/g726_rfc3551.h"
74 }
75
76 /* Speex codec */
77 extern "C" {
78 #include <speex/speex.h>
79 /* Note: if you use the RPM speex-devel on SuSE 9.1 change the
80 * header file above from <speex/speex.h> to <speex.h> */
81 }
82
83 #include "sinuston.h"
84
85 typedef unsigned char Byte;
86 typedef short Word16;
87
88 #ifdef EFRSTUB
89 /* EFR stubs - because of function name conflict in EFR and G.729 */
90 class EFR {
91 public:
92 int EFR::initEncode(int dtx_mode_) {
93 return 0;
94 };
95 int EFR::encode( /* (o) len in byte of encoded_data */
96 Byte * encoded_data, /* (o) The encoded bytes */
97 Word16 * data /* (i) The signal block to encode */
98 ) {
99 return 0;
100 };
101 int EFR::initDecode() {
102 return 0;
103 };
104 int EFR::decode( /* (o) Number of decoded samples or 0 for error */
105 Word16 * decoded_data, /* (o) Decoded signal block */
106 Byte * encoded_data, /* (i) Encoded bytes */
107 Word16 mode /* (i) 0=PL, 1=Normal */
108 ) {
109 return 0;
110 };
111 };
112 #else
113 /* 3GPP GSM-EFR codec */
114 #include "efr/typedef.h"
115 #include "efr/efr.h"
116 #endif
117
118 #ifdef G729STUB
119 /* G.729 stubs - because of function name conflict in EFR and G.729 */
120 class G729 {
121 public:
122 int G729::initEncode(int dummy) {
123 return 0;
124 };
125
126 int G729::encode( /* len in byte of encoded_data */
127 Byte * encoded_data, /* (o) The encoded bytes */
128 Word16 * data /* (i) The signal block to encode */
129 ) {
130 return 0;
131 };
132 int G729::initDecode() {
133 return 0;
134 };
135
136 int G729::decode( /* (o) Number of decoded samples */
137 Word16 * decoded_data, /* (o) Decoded signal block */
138 Byte * encoded_data, /* (i) Encoded bytes */
139 Word16 mode /* (i) 0=PL, 1=Normal */
140 ) {
141 return 0;
142 };
143 };
144 #else
145 /* ITU-T G.729 codec */
146 #include "g729/typedef.h"
147 #include "g729/ld8k.h"
148 #include "g729/g729.h"
149 #endif
150
151
152 /* intercom */
153 #include "rtp.h"
154 #include "udp.h"
155 #include "tcp.h"
156 #include "aec.h"
157 #include "oss.h"
158 #include "cirbuf.h"
159 #include "intercomd.h"
160
161 /* Design Constants */
162 #define PARTNERS 5 /* maximum telephony partners */
163
164 /* End of Design Constants */
165 #define MAXPACKSIZE 160 /* maximum size of 20ms encoded audio */
166 #define ILBC_MODE 20
167 #define FRAMESIZE (20*8*WIDEB*2) /* compression frame size */
168 #define MTU 1460 /* max. MTU size without Headers */
169
170 /* Globals */
171 int wdisplay = NO; /* export aec.cpp */
172
173
174 /* audio */
175 static CIRBUF mic_cirbuf;
176 static CIRBUF spk_cirbuf;
177 static AEC aec;
178 static int channels = 1;
179 static int audio_wr_fd = -1; // Audio Output (speaker)
180 static int packetlc = NO;
181 static SINUSTON sinuston; // Erweiterung Christian Dorge
182 static int sinuson = 0; // Sinustonaktivierung
183
184 /* network transmitting to partners */
185 static in_addr_t to_ip[PARTNERS];
186 static RTP to_rtp[PARTNERS];
187 static UDP to_udp[PARTNERS];
188 static iLBC_Enc_Inst_t enc_ilbc[PARTNERS];
189 static G726_state enc_g726[PARTNERS];
190 static EFR enc_efr[PARTNERS];
191 static G729 enc_g729[PARTNERS];
192 static gsm enc_gsm[PARTNERS];
193 static SpeexBits enc_spxbits[PARTNERS];
194 static void *enc_spx[PARTNERS];
195 static CIRBUF conf_cirbuf[PARTNERS];
196 static char tx_buf[PARTNERS][MTU];
197 static char *tx_pbuf[PARTNERS];
198 static int tx_frame[PARTNERS];
199 static int to_partners = 0;
200 static int telephone_conference = NO;
201 static int tx_frames = 4;
202 static int tx_payloadt = PT_iLBC; /* default Codec */
203 static int tx_packsize = NO_OF_BYTES_20MS;
204 static unsigned long to_ssrc = 0;
205
206 /* network receiving from partners */
207 static in_addr_t from_ip[PARTNERS];
208 static unsigned long from_ssrc[PARTNERS];
209 static int from_cnt[PARTNERS];
210 static CIRBUF from_cirbuf[PARTNERS];
211 static iLBC_Dec_Inst_t dec_ilbc[PARTNERS];
212 static G726_state dec_g726[PARTNERS];
213 static EFR dec_efr[PARTNERS];
214 static G729 dec_g729[PARTNERS];
215 static gsm dec_gsm[PARTNERS];
216 static SpeexBits dec_spxbits[PARTNERS];
217 static void *dec_spx[PARTNERS];
218 static int from_partners = 0;
219 static int from_rx_pt[PARTNERS];
220 static RTP from_rtp[PARTNERS];
221
222 /*----------------------------------------------------------------*
223 * iLBC Encoder interface function
224 *---------------------------------------------------------------*/
225
226 short encode( /* (o) Number of bytes encoded */
227 iLBC_Enc_Inst_t * iLBCenc_inst, /* (i/o) Encoder instance */
228 unsigned char *encoded_data, /* (o) The encoded bytes */
229 short *data /* (i) The signal block to encode */
230 )
231 {
232 float block[BLOCKL_MAX];
233 int k;
234
235 /* convert signal to float */
236
237 for (k = 0; k < iLBCenc_inst->blockl; k++)
238 block[k] = (float) data[k];
239
240 /* do the actual encoding */
241
242 iLBC_encode(encoded_data, block, iLBCenc_inst);
243
244 return (iLBCenc_inst->no_of_bytes);
245 }
246
247 short spx_encode( /* (o) Number of bytes encoded */
248 SpeexBits *bits,
249 void *enc_state,
250 unsigned char *encoded_data, /* (o) The encoded bytes */
251 short *data /* (i) The signal block to encode */
252 )
253 {
254 float block[20*WIDEB*8];
255 unsigned int k;
256
257 /* convert signal to float */
258
259 for (k = 0; k < sizeof(block) / sizeof(float); k++)
260 block[k] = (float) data[k];
261
262 /* do the actual encoding */
263
264 speex_bits_reset(bits);
265 speex_encode(enc_state, block, bits);
266 int bytes = speex_bits_write(bits, (char *)encoded_data, 200);
267
268 // RPM speex-devel 1.0.3 has different size then Speex 1.1.7
269 if (bytes != SZ_SPX) {
270 static int errcnt = 0;
271 if (++errcnt > 0) {
272 errcnt = -250;
273 syslog(LOG_WARNING, "%s:%d: %s: Error bytes = %d, Update Speex lib to 1.1\n", \
274 __FILE__, __LINE__, __PRETTY_FUNCTION__, bytes); \
275 }
276 }
277 return SZ_SPX;
278 }
279
280 void tx_buf_init(int i)
281 {
282 tx_pbuf[i] = tx_buf[i];
283 tx_frame[i] = 0;
284 }
285
286 int encode_any(int i, Byte * encoded_data, short *buf)
287 {
288 static int once = 0;
289 int len = 0;
290 switch (tx_payloadt) {
291 case PT_PCMA:
292 len = 160;
293 alaw_compress(len, buf, encoded_data);
294 break;
295 case PT_PCMU:
296 len = 160;
297 ulaw_compress(len, buf, encoded_data);
298 break;
299 case PT_GSM:
300 gsm_encode(enc_gsm[i], buf, encoded_data);
301 len = 33;
302 break;
303 case PT_EFR:
304 len = enc_efr[i].encode(encoded_data, buf);
305 break;
306 case PT_G729:
307 /* G.729 is a 10ms per frame codec */
308 enc_g729[i].encode(encoded_data, buf);
309 len = 2 * enc_g729[i].encode(encoded_data + 10, buf + 80);
310 break;
311 case PT_iLBC:
312 len = encode(&enc_ilbc[i], encoded_data, buf);
313 break;
314 case PT_SPX:
315 len = spx_encode(&enc_spxbits[i], enc_spx[i], encoded_data, buf);
316 if (!once) {
317 printf("speex encode len = %d\n", len);
318 once = 1;
319 }
320 break;
321 case PT_G726:
322 len = g726_encode(&enc_g726[i], encoded_data, buf);
323 break;
324 }
325 return len;
326 }
327
328 static int packet_loss = 0;
329
330 int audio_read(int audio_rd_fd)
331 {
332 /* fat software interrupt routine: read audio, send UDP packets */
333
334 short mic_buf[FRAGSIZE / 2];
335 if (1 == channels) {
336 size_t len = read(audio_rd_fd, mic_buf, FRAGSIZE);
337 return_if(len != FRAGSIZE, ERROR);
338
339 if (0 == to_partners) {
340 /* start assembling send packets only if we have a target */
341 return OKAY;
342 }
343
344 short spk_buf[FRAGSIZE / 2];
345 spk_cirbuf.pop((char *) spk_buf, FRAGSIZE);
346
347 /* Acoustic Echo Cancellation - using software buffers */
348 int i;
349 for (i = 0; i < FRAGSIZE / 2; ++i) {
350 mic_buf[i] = aec.doAEC(mic_buf[i], spk_buf[i]);
351 }
352 } else {
353 short mic2_buf[FRAGSIZE];
354 size_t len = read(audio_rd_fd, mic2_buf, 2 * FRAGSIZE);
355 return_if(len != 2 * FRAGSIZE, ERROR);
356
357 if (0 == to_partners) {
358 /* start assembling send packets only if we have a target */
359 return OKAY;
360 }
361
362 /* Acoustic Echo Cancellation - using hardware audio mixer */
363 int i;
364 for (i = 0; i < FRAGSIZE / 2; ++i) {
365 mic_buf[i] = aec.doAEC(mic2_buf[2 * i], mic2_buf[2 * i + 1]);
366 }
367 }
368
369 int ret = mic_cirbuf.push((char *) mic_buf, FRAGSIZE);
370 if (ret < 0) {
371 syslog(LOG_WARNING, "mic_cirbuf.push overrun\n");
372 }
373
374 if (mic_cirbuf.getlen() >= FRAMESIZE) {
375 /* My RFC3551 interpretation: Only one RTP Header for packets
376 * with a number of frames */
377 int i;
378 for (i = 0; i < PARTNERS; ++i) {
379 if (to_ip[i] && 0 == tx_frame[i]) {
380 to_rtp[i].reset_csrc();
381
382 /* add ssrc from partners in csrc field */
383 if (telephone_conference) {
384 int j;
385 for (j = 0; j < PARTNERS; ++j) {
386 /* do not mix in origin */
387 if (from_ssrc[j] && (to_ip[i] != from_ip[j])) {
388 to_rtp[i].add_csrc(from_ssrc[j]);
389 }
390 }
391 }
392 /* put RTP header */
393 tx_pbuf[i] = RTP_network_copy(tx_pbuf[i], &to_rtp[i]);
394 }
395 }
396
397 /* put payload (audio) */
398 short micbuf[FRAMESIZE / 2];
399 mic_cirbuf.pop((char *) micbuf, FRAMESIZE);
400
401 if (telephone_conference) {
402 /* telephone conference mix - everybody from/to everybody else */
403 short from_buf[PARTNERS][FRAMESIZE / sizeof(short)];
404 short sum_buf[FRAMESIZE / sizeof(short)];
405 int i, k;
406 unsigned int j;
407
408 /* get audio from other partners */
409 for (i = 0; i < PARTNERS; ++i) {
410 conf_cirbuf[i].pop((char *) from_buf[i], FRAMESIZE);
411 }
412
413 for (i = 0; i < PARTNERS; ++i) {
414 if (to_ip[i]) {
415 for (j = 0; j < FRAMESIZE / sizeof(short); ++j) {
416 /* mix */
417 long sum = micbuf[j];
418 for (k = 0; k < PARTNERS; ++k) {
419 if (to_ip[i] != from_ip[k]) { /* do not mix in origin */
420 sum += from_buf[k][j];
421 }
422 }
423 /* clip */
424 if (sum > 32767) {
425 sum_buf[j] = 32767;
426 } else if (sum < -32767) {
427 sum_buf[j] = -32767;
428 } else {
429 sum_buf[j] = sum;
430 }
431 }
432 /* do encoding (audio compression) */
433 Byte encoded_data[MAXPACKSIZE];
434 int len = encode_any(i, encoded_data, sum_buf);
435
436 /* distribute to transmit buffers */
437 memcpy(tx_pbuf[i], encoded_data, len);
438 tx_pbuf[i] += len;
439 assert(tx_pbuf[i] - tx_buf[i] <= MTU);
440 }
441 }
442 } else {
443 /* intercom conference mixing - central node from/to other nodes */
444 /* do encoding (audio compression) */
445 Byte encoded_data[MAXPACKSIZE];
446 int len = encode_any(0, encoded_data, micbuf);
447
448 /* distribute to transmit buffers */
449 int i;
450 for (i = 0; i < PARTNERS; ++i) {
451 if (to_ip[i]) {
452 memcpy(tx_pbuf[i], encoded_data, len);
453 tx_pbuf[i] += len;
454 assert(tx_pbuf[i] - tx_buf[i] <= MTU);
455 }
456 }
457 }
458
459 /* transmit data packet(s) */
460 for (i = 0; i < PARTNERS; ++i) {
461 if (to_ip[i] && ++tx_frame[i] >= tx_frames) {
462
463 if (random() >= packet_loss) { // simulate packet loss
464 to_udp[i].send(tx_buf[i], tx_pbuf[i] - tx_buf[i]);
465 }
466
467 /* prepare next go */
468 tx_buf_init(i);
469 to_rtp[i].next(tx_frames * 20 * 8);
470 }
471 }
472 }
473 return OKAY;
474 }
475
476 void partner_timeout()
477 {
478 /* Delete old from_ssrc[] entries - this is not very quick! */
479 int i;
480 for (i = 0; i < PARTNERS; ++i) {
481 if (from_ssrc[i] && from_cnt[i] == 0) {
482 char s[20];
483 print_gui("d %s\n", iptoa(s, from_ip[i]));
484 from_ssrc[i] = 0;
485 from_ip[i] = 0;
486 from_rx_pt[i] = -1;
487 from_rtp[i].reset_csrc();
488 --from_partners;
489 if (0 == from_partners) {
490 /* no more demand for PCM out */
491 close(audio_wr_fd);
492 audio_wr_fd = -1;
493 }
494 }
495 from_cnt[i] = 0;
496 }
497 }
498
499
500 int partner_lookup(unsigned long ssrc, in_addr_t ip)
501 {
502 /* search */
503 int i;
504 for (i = 0; i < PARTNERS; ++i) {
505 if (from_ssrc[i] == ssrc) {
506 ++from_cnt[i];
507 return i; /* old entry */
508 }
509 }
510 /* add new entry */
511 for (i = 0; i < PARTNERS; ++i) {
512 if (0 == from_ssrc[i]) {
513 if (0 == from_partners) {
514 spk_cirbuf.init();
515 }
516 from_ssrc[i] = ssrc;
517 from_ip[i] = ip;
518 from_cnt[i] = 1;
519
520 initDecode(dec_ilbc + i, ILBC_MODE, 1);
521 enc_efr[i].initDecode();
522 enc_g729[i].initDecode();
523 rpeltp_delete(dec_gsm[i]);
524 dec_gsm[i] = rpeltp_init();
525 speex_bits_destroy(dec_spxbits + i);
526 speex_decoder_destroy(dec_spx[i]);
527 speex_bits_init(dec_spxbits + i);
528 dec_spx[i] = speex_decoder_init(&speex_wb_mode);
529 int value = SPX_ENH;
530 speex_decoder_ctl(dec_spx[i], SPEEX_SET_ENH, &value);
531
532 from_cirbuf[i].init();
533 conf_cirbuf[i].init();
534 ++from_partners;
535 char s[20];
536 print_gui("r %s\n", iptoa(s, ip));
537
538 printf("from_ssrc[%d] = %08lx\n", i, from_ssrc[i]);
539 return i;
540 }
541 }
542 return ERROR;
543 }
544
545 /*----------------------------------------------------------------*
546 * iLBC Decoder interface function
547 *---------------------------------------------------------------*/
548
549 short decode( /* (o) Number of decoded samples */
550 iLBC_Dec_Inst_t * iLBCdec_inst, /* (i/o) Decoder instance */
551 short *decoded_data, /* (o) Decoded signal block */
552 unsigned char *encoded_data, /* (i) Encoded bytes */
553 short mode /* (i) 0=PL, 1=Normal */
554 )
555 {
556 int k;
557 float decblock[BLOCKL_MAX], dtmp;
558
559 /* check if mode is valid */
560
561 if (mode < 0 || mode > 1) {
562 printf("\nERROR - Wrong mode - 0, 1 allowed\n");
563 exit(3);
564 }
565
566 /* do actual decoding of block */
567 iLBC_decode(decblock, encoded_data, iLBCdec_inst, mode);
568
569 /* convert to short */
570
571 for (k = 0; k < iLBCdec_inst->blockl; k++) {
572 dtmp = decblock[k];
573
574 if (dtmp < MIN_SAMPLE)
575 dtmp = MIN_SAMPLE;
576 else if (dtmp > MAX_SAMPLE)
577 dtmp = MAX_SAMPLE;
578 decoded_data[k] = (short) dtmp;
579 }
580
581 return (iLBCdec_inst->blockl);
582 }
583
584 short spx_decode( /* (o) Number of decoded samples */
585 SpeexBits *bits,
586 void *dec_state,
587 short *decoded_data, /* (o) Decoded signal block */
588 unsigned char *encoded_data, /* (i) Encoded bytes */
589 short mode /* (i) 0=PL, 1=Normal */
590 )
591 {
592 unsigned int k;
593 float decblock[20*WIDEB*8];
594
595 /* do actual decoding of block */
596 if (bits)
597 speex_bits_read_from(bits, (char *)encoded_data, SZ_SPX);
598 speex_decode(dec_state, bits, decblock);
599
600 /* convert to short */
601
602 for (k = 0; k < sizeof(decblock) / sizeof(float); k++) {
603 decoded_data[k] = (short)decblock[k];
604 }
605
606 return 20*WIDEB*8;
607 }
608
609 void audio_write()
610 {
611 int i;
612 unsigned int j;
613 short from_buf[PARTNERS][FRAGSIZE / sizeof(short)];
614 short sum_buf[FRAGSIZE / sizeof(short)];
615 int playout = 0; // is 1 if we have audio, not silence
616
617 /* get audio */
618 for (i = 0; i < PARTNERS; ++i) {
619 int ret = from_cirbuf[i].pop((char *) from_buf[i], FRAGSIZE);
620 if (OKAY == ret) playout = 1;
621 if (packetlc && ERROR == ret && from_ssrc[i] && audio_wr_fd >= 0) {
622 // printf("audio_write() PLC ch=%d ret=%d \n", i, ret);
623
624 /* do Packet Loss Concealment */
625 short decoded_data[FRAMESIZE / 2];
626 int len;
627 switch (from_rx_pt[i]) {
628 case PT_iLBC:
629 len = decode(dec_ilbc + i, decoded_data, NULL, 0);
630 from_cirbuf[i].push((char *) decoded_data, 2 * len);
631 from_cirbuf[i].pop((char *) from_buf[i], FRAGSIZE);
632 playout = 1;
633 break;
634 case PT_SPX:
635 Byte spx_dummy[SZ_SPX];
636 memset(spx_dummy, 0, SZ_SPX);
637 len = spx_decode(NULL, dec_spx[i],
638 decoded_data, spx_dummy, 1);
639 from_cirbuf[i].push((char *) decoded_data, 2 * len);
640 from_cirbuf[i].pop((char *) from_buf[i], FRAGSIZE);
641 playout = 1;
642 break;
643 case PT_EFR:
644 Byte efr_dummy[31];
645 memset(efr_dummy, 0, 31);
646 efr_dummy[0] = 0xC0;
647 len = dec_efr[i].decode(decoded_data, efr_dummy, 0);
648 from_cirbuf[i].push((char *) decoded_data, 2 * len);
649 from_cirbuf[i].pop((char *) from_buf[i], FRAGSIZE);
650 playout = 1;
651 break;
652 case PT_G729:
653 Byte g729_dummy[20];
654 memset(g729_dummy, 0, 20);
655 len = dec_g729[i].decode(decoded_data, g729_dummy, 0);
656 len +=
657 dec_g729[i].decode(decoded_data + 80, g729_dummy + 10, 0);
658 from_cirbuf[i].push((char *) decoded_data, 2 * len);
659 from_cirbuf[i].pop((char *) from_buf[i], FRAGSIZE);
660 playout = 1;
661 break;
662 }
663 }
664 }
665
666 // if (!playout) return; // knistern with AD1985
667
668 // audio mixing with sinuston
669 for (j = 0; j < FRAGSIZE / sizeof(short); ++j) {
670 /* mix */
671 long sum = 0;
672 for (i = 0; i < PARTNERS; ++i) {
673 sum += from_buf[i][j];
674 }
675 /* clip */
676 if (sum > 32767) {
677 sum = 32767;
678 } else if (sum < -32767) {
679 sum = -32767;
680 }
681 if (sinuson && playout) {
682 // Sinuston dazumischen 11jul2005 adrian
683 sum = sinuston.mischen(sum);
684 }
685 sum_buf[j] = sum;
686 }
687
688 if (1 == channels) {
689 if (from_partners > 0) {
690 /* save for 1-channel AEC */
691 int ret = spk_cirbuf.push((char *) sum_buf, FRAGSIZE);
692 if (ret < 0) {
693 /* syslog(LOG_WARNING, "spk_cirbuf.push overrun\n"); */
694 }
695 }
696 if (audio_wr_fd < 0) {
697 /* late audio write open */
698 audio_wr_fd = audio_init("/dev/dsp", channels, O_WRONLY);
699 }
700 if (audio_wr_fd >= 0) {
701 write(audio_wr_fd, sum_buf, FRAGSIZE);
702 }
703 } else {
704 short sum2_buf[FRAGSIZE];
705 int i;
706 for (i = 0; i < FRAGSIZE / 2; ++i) {
707 sum2_buf[2 * i] = 0; /* left channel nothing */
708 sum2_buf[2 * i + 1] = sum_buf[i]; /* right channel spk */
709 }
710 if (audio_wr_fd < 0) {
711 /* late audio write open */
712 audio_wr_fd = audio_init("/dev/dsp", channels, O_WRONLY);
713 }
714 if (audio_wr_fd >= 0) {
715 write(audio_wr_fd, sum2_buf, 2 * FRAGSIZE);
716 }
717 }
718 }
719
720 static unsigned short rtp_port = 5004; /* see RFC3551 */
721
722 int udp_read(int udp_fd)
723 {
724 /* software interrupt routine */
725 char buf[MTU];
726 struct sockaddr_in from_sock;
727 socklen_t from_socklen = sizeof(sockaddr_in);
728 RTP rtp_in;
729
730 int len = recvfrom(udp_fd, buf, MTU, 0,
731 (struct sockaddr *) &from_sock, &from_socklen);
732
733 /* check Port number */
734 in_addr_t from_ip = ntohl(from_sock.sin_addr.s_addr);
735 in_port_t from_port = ntohs(from_sock.sin_port);
736 return_if(from_port != rtp_port, ERROR);
737
738 char *pbuf = RTP_host_copy(&rtp_in, buf);
739 len -= (pbuf - buf);
740 return_if(len < 0, ERROR);
741 int rc = rtp_in.check();
742 return_if(rc, ERROR);
743
744 int partner = partner_lookup(rtp_in.getssrc(), from_ip);
745 return_if(partner < 0, ERROR);
746
747 /* Avoid Megaphone (station with itself) audio loop */
748 if (to_ssrc == rtp_in.getssrc()) {
749 // return ERROR;
750 }
751
752 /* Avoid telephone conference style audio loop (multipath) */
753 int i;
754 for (i = 0; i < PARTNERS; ++i) {
755 /* drop packets with SSRC the same as an known CSRC */
756 if (i != partner && from_rtp[i].find_csrc(rtp_in.getssrc())) {
757 return ERROR;
758 }
759 }
760 /* to avoid silence with audio loops: Only if above test passed
761 * copy rtp_in */
762 from_rtp[partner] = rtp_in; /* die CSRC */
763
764 int rx_frames = 0;
765 int rx_pt = rtp_in.get_pt();
766 /* detect number of frames and dynamic payload type from length */
767 switch (len) {
768 case 1 * 20:
769 rx_frames = 1;
770 break; /* G729 */
771 case 1 * 33:
772 rx_frames = 1;
773 break; /* GSM */
774 case 1 * 31:
775 rx_frames = 1;
776 rx_pt = PT_EFR;
777 break;
778 case 1 * 38:
779 rx_frames = 1;
780 rx_pt = PT_iLBC;
781 break;
782 case 1 * SZ_SPX:
783 rx_frames = 1;
784 rx_pt = PT_SPX;
785 break;
786 case 1 * 80: /* or 4*20 */
787 switch (rx_pt) {
788 case PT_G729:
789 rx_frames = 4;
790 break;
791 default:
792 rx_frames = 1;
793 rx_pt = PT_G726;
794 break;
795 }
796 break;
797 case 1 * 160: /* or 2*80 */
798 switch (rx_pt) {
799 case PT_PCMA:
800 case PT_PCMU:
801 rx_frames = 1; /* G711 */
802 break;
803 default:
804 rx_frames = 2; /* G726 32kbps */
805 rx_pt = PT_G726;
806 break;
807 }
808 break;
809
810 case 2 * 20:
811 rx_frames = 2;
812 break;
813 case 2 * 33:
814 rx_frames = 2;
815 break;
816 case 2 * 31:
817 rx_frames = 2;
818 rx_pt = PT_EFR;
819 break;
820 case 2 * 38:
821 rx_frames = 2;
822 rx_pt = PT_iLBC;
823 break;
824 case 2 * SZ_SPX:
825 rx_frames = 2;
826 rx_pt = PT_SPX;
827 break;
828 case 2 * 160: /* or 4*80 */
829 switch (rx_pt) {
830 case PT_PCMA:
831 case PT_PCMU:
832 rx_frames = 2; /* G711 */
833 break;
834 default:
835 rx_frames = 4; /* G726 32kbps */
836 rx_pt = PT_G726;
837 break;
838 }
839 break;
840
841 case 3 * 20:
842 rx_frames = 3;
843 break;
844 case 3 * 33:
845 rx_frames = 3;
846 break;
847 case 3 * 31:
848 rx_frames = 3;
849 rx_pt = PT_EFR;
850 break;
851 case 3 * 38:
852 rx_frames = 3;
853 rx_pt = PT_iLBC;
854 break;
855 case 3 * SZ_SPX:
856 rx_frames = 3;
857 rx_pt = PT_SPX;
858 break;
859 case 3 * 80:
860 rx_frames = 3;
861 rx_pt = PT_G726;
862 break;
863 case 3 * 160:
864 rx_frames = 3;
865 break;
866
867 case 4 * 33:
868 rx_frames = 4;
869 break;
870 case 4 * 31:
871 rx_frames = 4;
872 rx_pt = PT_EFR;
873 break;
874 case 4 * 38:
875 rx_frames = 4;
876 rx_pt = PT_iLBC;
877 break;
878 case 4 * SZ_SPX:
879 rx_frames = 4;
880 rx_pt = PT_SPX;
881 break;
882 case 4 * 160:
883 rx_frames = 4;
884 break;
885 };
886 return_if(0 == rx_frames, ERROR);
887
888 from_rx_pt[partner] = rx_pt;
889 for (i = 0; i < rx_frames; ++i) {
890 /* do decoding (audio decompression) */
891 short decoded_data[FRAMESIZE / 2];
892 switch (rx_pt) {
893 case PT_PCMA:
894 len = 160;
895 alaw_expand(len, (Byte *) pbuf, decoded_data);
896 pbuf += 160;
897 break;
898 case PT_PCMU:
899 len = 160;
900 ulaw_expand(len, (Byte *) pbuf, decoded_data);
901 pbuf += 160;
902 break;
903 case PT_GSM:
904 len = 160;
905 gsm_decode(dec_gsm[partner], (Byte *) pbuf, decoded_data);
906 pbuf += 33;
907 break;
908 case PT_EFR:
909 len = dec_efr[partner].decode(decoded_data, (Byte *) pbuf, 1);
910 pbuf += 31;
911 break;
912 case PT_G729:
913 len = dec_g729[partner].decode(decoded_data, (Byte *) pbuf, 1);
914 len +=
915 dec_g729[partner].decode(decoded_data + 80,
916 (Byte *) (pbuf + 10), 1);
917 pbuf += 20;
918 break;
919 case PT_iLBC:
920 len = decode(dec_ilbc + partner, decoded_data, (Byte *) pbuf, 1);
921 pbuf += 38;
922 break;
923 case PT_SPX:
924 len = spx_decode(dec_spxbits + partner, dec_spx[partner],
925 decoded_data, (Byte *) pbuf, 1);
926 pbuf += SZ_SPX;
927 break;
928 case PT_G726:
929 len =
930 g726_decode(dec_g726 + partner, decoded_data, (Byte *) pbuf, 1);
931 pbuf += 80;
932 break;
933 }
934 return_if(len != FRAMESIZE / 2, ERROR);
935
936 int ret = from_cirbuf[partner].push((char *) decoded_data, 2 * len);
937 if (ret < 0) {
938 syslog(LOG_WARNING, "from_cirbuf[%d].push overrun=%d\n", partner,
939 ret / FRAGSIZE);
940 }
941 if (telephone_conference) {
942 ret = conf_cirbuf[partner].push((char *) decoded_data, 2 * len);
943 if (ret < 0) {
944 /* syslog(LOG_WARNING, "conf_cirbuf[%d].push overrun=%d\n",
945 partner, ret/FRAGSIZE); */
946 }
947 }
948 }
949 return OKAY;
950 }
951
952 void spx_encoder_init(int i)
953 {
954 speex_bits_init(enc_spxbits + i);
955 enc_spx[i] = speex_encoder_init(&speex_wb_mode);
956 int value = SPX_QUALITY;
957 speex_encoder_ctl(enc_spx[i], SPEEX_SET_QUALITY, &value);
958 value = SPX_BITRATE;
959 speex_encoder_ctl(enc_spx[i], SPEEX_SET_BITRATE, &value);
960 value = SPX_COMPLEXITY;
961 speex_encoder_ctl(enc_spx[i], SPEEX_SET_COMPLEXITY, &value);
962 }
963
964 // user command
965 void command(char *cmd, int udp_fd)
966 {
967 /* delete special characters like \r, \n */
968 unsigned int i;
969 for (i = 0; i < strlen(cmd); ++i) {
970 if (cmd[i] < ' ') { /* hack: assume ASCII coding */
971 cmd[i] = 0;
972 break;
973 }
974 }
975 in_addr_t ip;
976 switch (cmd[0]) {
977 default:
978 printf("voipconf commands:\n"
979 "c IP-Adress - connect to IP-Adress\n"
980 "h IP-Adress - hang-up IP-Adress\n\n");
981 fflush(stdout);
982 break;
983 case 'p':
984 /* do nothing */
985 break;
986 case 'c':
987 ip = atoip(cmd + 2);
988 for (i = 0; i < PARTNERS; ++i) {
989 if (0 == to_ip[i]) {
990 if (0 == to_partners) {
991 mic_cirbuf.init();
992 }
993 tx_buf_init(i);
994 to_ip[i] = ip;
995 to_rtp[i].init(tx_payloadt, to_ssrc);
996 to_udp[i].send_init(cmd + 2, rtp_port, udp_fd);
997 switch (tx_payloadt) {
998 case PT_EFR:
999 enc_efr[i].initEncode(0);
1000 break;
1001 case PT_G729:
1002 enc_g729[i].initEncode(0);
1003 break;
1004 case PT_iLBC:
1005 initEncode(enc_ilbc + i, ILBC_MODE);
1006 break;
1007 case PT_GSM:
1008 rpeltp_delete(enc_gsm[i]);
1009 enc_gsm[i] = rpeltp_init();
1010 break;
1011 case PT_SPX:
1012 speex_bits_destroy(enc_spxbits + i);
1013 speex_encoder_destroy(enc_spx[i]);
1014 spx_encoder_init(i);
1015 break;
1016 }
1017 ++to_partners;
1018 break;
1019 }
1020 }
1021 break;
1022 case 'h':
1023 ip = atoip(cmd + 2);
1024 for (i = 0; i < PARTNERS; ++i) {
1025 if (ip == to_ip[i]) {
1026 to_ip[i] = 0;
1027 to_udp[i].send_close();
1028 --to_partners;
1029
1030 print_gui("%s\n", cmd); /* Tcl/Tk needs \n */
1031 break;
1032 }
1033 }
1034 break;
1035 }
1036
1037 /* syslog(LOG_WARNING, "cmd=%s to_partners=%d\n", cmd, to_partners); */
1038 }
1039
1040 #define CMDLEN 80
1041
1042 // local signalling from intercom.tcl
1043 int gui_read(int gui_fd, int udp_fd)
1044 {
1045 char cmd[CMDLEN];
1046
1047 int len = read(gui_fd, cmd, CMDLEN);
1048
1049 if (len <= 0) {
1050 syslog(LOG_WARNING, "gui_read() close\n");
1051 int ret = shutdown(gui_fd, SHUT_RDWR);
1052 assert_errno(ret >= 0);
1053
1054 return -1;
1055 }
1056
1057 command(cmd, udp_fd);
1058
1059 return gui_fd;
1060 }
1061
1062 static int gui_fd = -1;
1063
1064 int print_gui(const char *fmt, ...)
1065 {
1066 /* in fmt: Formatstring as printf */
1067 /* in ...: Parameter(s) as printf */
1068
1069 if (gui_fd >= 0) {
1070 char s[MTU];
1071 va_list ap;
1072 va_start(ap, fmt);
1073 (void) vsnprintf(s, MTU, fmt, ap);
1074 va_end(ap);
1075
1076 int len = strlen(s);
1077
1078 return write(gui_fd, s, len);
1079 } else {
1080 return ERROR;
1081 }
1082 }
1083
1084 struct timeval difftimeval(struct timeval time1, struct timeval time2)
1085 {
1086 struct timeval diff;
1087
1088 diff.tv_usec = time1.tv_usec - time2.tv_usec;
1089 if (diff.tv_usec < 0) {
1090 diff.tv_usec += 1000000;
1091 time2.tv_usec += 1;
1092 }
1093 diff.tv_sec = time1.tv_sec - time2.tv_sec;
1094
1095 return diff;
1096 }
1097
1098 float dB2q(float dB)
1099 {
1100 /* Dezibel to Ratio */
1101 return powf(10.0f, dB / 20.0f);
1102 }
1103 float q2dB(float q)
1104 {
1105 /* Ratio to Dezibel */
1106 return 20.0f * log10f(q);
1107 }
1108
1109 /* program main loop. OS Event handler */
1110 int loop(int audio_rd_fd, int udp_fd, int gui_listen_fd)
1111 {
1112
1113 struct timeval timeout;
1114 fd_set read_fds;
1115 int max_fd = 64; /* should be max(fd, ..) + 1 */
1116 static struct timeval last_partner_timeout;
1117 static struct timeval last_getambient;
1118 static struct timeval last_spkout;
1119 static long remainder_spkout = 0;
1120 struct timezone tz;
1121 static int mic_int, spk_int, time_int;
1122
1123 openlog(NULL, LOG_PERROR, LOG_WARNING);
1124
1125 gettimeofday(&last_partner_timeout, &tz);
1126 gettimeofday(&last_getambient, &tz);
1127 gettimeofday(&last_spkout, &tz);
1128 for (;;) {
1129 timeout.tv_sec = 0;
1130 timeout.tv_usec = FRAGTIME * 1000;
1131 FD_ZERO(&read_fds);
1132 FD_SET(audio_rd_fd, &read_fds);
1133 FD_SET(udp_fd, &read_fds);
1134 FD_SET(gui_listen_fd, &read_fds);
1135 if (gui_fd >= 0) {
1136 FD_SET(gui_fd, &read_fds);
1137 }
1138 // int ret = select(max_fd, &read_fds, NULL, NULL, &timeout);
1139 int ret = select(max_fd, &read_fds, NULL, NULL, NULL);
1140 assert_errno(ret >= 0);
1141
1142 if (FD_ISSET(audio_rd_fd, &read_fds)) {
1143 audio_read(audio_rd_fd);
1144 ++mic_int;
1145 }
1146 if (FD_ISSET(udp_fd, &read_fds)) {
1147 udp_read(udp_fd);
1148 }
1149 if (FD_ISSET(gui_listen_fd, &read_fds)) {
1150 gui_fd = tcp_server_init2(gui_listen_fd);
1151 }
1152 if (gui_fd >= 0) {
1153 if (FD_ISSET(gui_fd, &read_fds)) {
1154 gui_fd = gui_read(gui_fd, udp_fd);
1155 }
1156 }
1157 #if 0
1158 if ((mic_int % (5000 / FRAGTIME)) == 0) {
1159 printf("int: mic %d spk %d time %d\n", mic_int, spk_int,
1160 time_int);
1161 }
1162 #endif
1163
1164 struct timeval now, diff;
1165 if (packetlc) {
1166 gettimeofday(&now, &tz);
1167 diff = difftimeval(now, last_spkout);
1168 if (diff.tv_usec + remainder_spkout >= FRAGTIME * 1000) {
1169 ++time_int;
1170 last_spkout = now;
1171 /* Linux time resolution is more coarse (15ms) then mic
1172 * time interval (4ms), therefore remainder calculation */
1173 remainder_spkout =
1174 diff.tv_usec + remainder_spkout - FRAGTIME * 1000;
1175 if (audio_wr_fd < 0) {
1176 /* new output: fill up Open Sound System (OSS) buffer
1177 * to compensate Operation System Jitter */
1178 // audio_write();
1179 }
1180 audio_write();
1181 ++spk_int;
1182 }
1183 } else {
1184 /* because of problems with Intel ICH5/Analog Devices AD1985
1185 * not together with audio_read() */
1186 audio_write();
1187 }
1188
1189 gettimeofday(&now, &tz);
1190 diff = difftimeval(now, last_partner_timeout);
1191 if (diff.tv_usec >= 160000) { /* 2*PACKETDURATION in usec */
1192 last_partner_timeout = now;
1193 partner_timeout();
1194 }
1195 #if 0
1196 gettimeofday(&now, &tz);
1197 diff = difftimeval(now, last_getambient);
1198 if (diff.tv_sec >= 2) {
1199 last_getambient = now;
1200 // if (to_partners > 0) {
1201 // float ambient = aec.getambient();
1202 // float ambientdB = q2dB(ambient / 32767.0f);
1203 // syslog(LOG_WARNING, "Ambient = %2.0f dB\n", ambientdB);
1204 float xfastdB = q2dB(aec.xfast / 32767.0f);
1205 float dfastdB = q2dB(aec.dfast / 32767.0f);
1206 float efastdB = q2dB(aec.efast / 32767.0f);
1207 float xslowdB = q2dB(aec.xslow / 32767.0f);
1208 float dslowdB = q2dB(aec.dslow / 32767.0f);
1209 syslog(LOG_WARNING, "ratio= %2.0f / %2.0f / %2.0f / %2.0f e= %2.0f\n",
1210 dfastdB, xfastdB, dslowdB, xslowdB, efastdB);
1211 // }
1212 }
1213 #endif
1214 }
1215 return ERROR;
1216 }
1217
1218 int main(int argc, char *argv[])
1219 {
1220 int i;
1221 float ambient = 0.0f;
1222 float dB;
1223
1224 #if WIDEB==1
1225 tx_payloadt = PT_iLBC;
1226 tx_packsize = SZ_iLBC;
1227 printf("Narrowband DFS VoIP Intercom %s\n", VERSION);
1228 #else
1229 tx_payloadt = PT_SPX;
1230 tx_packsize = SZ_SPX;
1231 printf("Wideband DFS VoIP Intercom %s\n", VERSION);
1232 #endif
1233 for (i = 1; i < argc && '-' == argv[i][0]; ++i) {
1234 switch (argv[i][1]) {
1235 case 'a': /* set Ambient (No Talking) Noise level */
1236 ambient = atof(argv[++i]);
1237 break;
1238 case 'b': /* No AES */
1239 dB = atof(argv[++i]);
1240 if (dB < 0.0f) {
1241 aec.setaes(dB2q(dB));
1242 } else {
1243 aec.setaes(0.0f); // 0 is no AES
1244 }
1245 break;
1246 case 'e':
1247 sinuson = 1; /* Sinuston 2040Hz zumischen */
1248 break;
1249 case 'k': /* packet loss concealment */
1250 packetlc = YES;
1251 break;
1252 case 'f': /* Frames */
1253 tx_frames = atoi(argv[++i]);
1254 if (tx_frames < 1)
1255 tx_frames = 1;
1256 if (tx_frames > 4)
1257 tx_frames = 4;
1258 break;
1259 case 'l': /* use hardware AEC and Line-in for microphone */
1260 channels = 2;
1261 break;
1262 case 'm': /* use hardware AEC and Mic-in for microphone */
1263 channels = 2;
1264 break;
1265 case 'p': /* RTP Portnumber */
1266 rtp_port = atoi(argv[++i]);
1267 rtp_port &= 0xFFFE; /* RFC3551: RTP port has even port number */
1268 break;
1269 case 's': /* simulated Packet loss */
1270 packet_loss = (RAND_MAX / 100) * atoi(argv[++i]);
1271 break;
1272 case 't': /* Telephone conference call (true conference) */
1273 telephone_conference = YES;
1274 break;
1275 case 'w': /* visualize vector w */
1276 aec.openwdisplay();
1277 break;
1278 #if WIDEB==1
1279 case 'A': /* set G.711 A-law */
1280 tx_payloadt = PT_PCMA;
1281 tx_packsize = 160; /* see RFC3551 */
1282 break;
1283 case 'U': /* set G.711 u-law */
1284 tx_payloadt = PT_PCMU;
1285 tx_packsize = 160; /* see RFC3551 */
1286 break;
1287 case '6': /* set G.726 codec */
1288 tx_payloadt = PT_G726;
1289 tx_packsize = 80; /* see RFC3551 */
1290 break;
1291 case 'G': /* set GSM codec */
1292 tx_payloadt = PT_GSM;
1293 tx_packsize = 33; /* see RFC3551 */
1294 break;
1295 case 'E': /* set GSM-EFR codec */
1296 tx_payloadt = PT_EFR;
1297 tx_packsize = 31; /* see RFC3551 */
1298 break;
1299 case '9': /* set G.729 codec */
1300 tx_payloadt = PT_G729;
1301 tx_packsize = 20; /* see RFC3551 */
1302 break;
1303 #else
1304 case 'S': /* set Speex codec */
1305 tx_payloadt = PT_SPX;
1306 tx_packsize = SZ_SPX; /* 16.8kBit/s Wideband */
1307 break;
1308 #endif
1309 }
1310 }
1311
1312 /* do -a option even if codec options follows */
1313 if (ambient != 0.0f) {
1314 aec.setambient(MAXPCM * dB2q(ambient));
1315 }
1316
1317 /* init Sinuston fuer Transmitter */
1318 sinuston.frequenz(2040, WIDEB*8000, -24.0f);
1319
1320 /* open Audio Receive */
1321 int audio_rd_fd = audio_init("/dev/dsp", channels, O_RDONLY);
1322 assert(audio_rd_fd >= 0);
1323
1324 /* open Network Receive */
1325 int udp_fd = UDP_recv_init(rtp_port);
1326 assert(udp_fd >= 0);
1327
1328 /* open Graphical User Interface as TCP server */
1329 int gui_listen_fd = tcp_server_init(4999);
1330
1331 /* codec Initialization */
1332 int j;
1333 for (j = 0; j < PARTNERS; ++j) {
1334 /* iLBC */
1335 initEncode(enc_ilbc + j, ILBC_MODE);
1336 initDecode(dec_ilbc + j, ILBC_MODE, 1);
1337
1338 /* GSM-EFR */
1339 enc_efr[j].initEncode(0);
1340 dec_efr[j].initDecode();
1341
1342 /* G.729 */
1343 enc_g729[j].initEncode(0);
1344 dec_g729[j].initDecode();
1345
1346 /* GSM */
1347 enc_gsm[i] = rpeltp_init();
1348 dec_gsm[i] = rpeltp_init();
1349
1350 /* Speex */
1351 spx_encoder_init(j);
1352
1353 speex_bits_init(dec_spxbits + j);
1354 dec_spx[j] = speex_decoder_init(&speex_wb_mode); // Wideband
1355 int value = SPX_ENH;
1356 speex_decoder_ctl(dec_spx[j], SPEEX_SET_ENH, &value);
1357 }
1358
1359 /* open Network Transmit Partner (Connections) */
1360 to_ssrc = random32(tx_payloadt);
1361 printf("to_ssrc = %08lx\n", to_ssrc);
1362 for (; i < argc; ++i) {
1363 if (0 == to_partners) {
1364 mic_cirbuf.init();
1365 }
1366 tx_buf_init(to_partners);
1367 to_ip[to_partners] = atoip(argv[i]);
1368 to_rtp[to_partners].init(tx_payloadt, to_ssrc);
1369 to_udp[to_partners].send_init(argv[i], rtp_port, udp_fd);
1370 ++to_partners;
1371 }
1372
1373 loop(audio_rd_fd, udp_fd, gui_listen_fd);
1374
1375 return OKAY;
1376 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.