G726-32 changes:
[asterisk/asterisk.git] / frame.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Frame and codec manipulation routines
22  *
23  * \author Mark Spencer <markster@digium.com> 
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <stdio.h>
35
36 #include "asterisk/lock.h"
37 #include "asterisk/frame.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/options.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/cli.h"
42 #include "asterisk/term.h"
43 #include "asterisk/utils.h"
44
45 #ifdef TRACE_FRAMES
46 static int headers = 0;
47 static struct ast_frame *headerlist = NULL;
48 AST_MUTEX_DEFINE_STATIC(framelock);
49 #endif
50
51 #define SMOOTHER_SIZE 8000
52
53 enum frame_type {
54         TYPE_HIGH,     /* 0x0 */
55         TYPE_LOW,      /* 0x1 */
56         TYPE_SILENCE,  /* 0x2 */
57         TYPE_DONTSEND  /* 0x3 */
58 };
59
60 #define TYPE_MASK 0x3
61
62 struct ast_smoother {
63         int size;
64         int format;
65         int readdata;
66         int optimizablestream;
67         int flags;
68         float samplesperbyte;
69         struct ast_frame f;
70         struct timeval delivery;
71         char data[SMOOTHER_SIZE];
72         char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
73         struct ast_frame *opt;
74         int len;
75 };
76
77 /*! \brief Definition of supported media formats (codecs) */
78 static struct ast_format_list {
79         int visible;    /*!< Can we see this entry */
80         int bits;       /*!< bitmask value */
81         char *name;     /*!< short name */
82         char *desc;     /*!< Description */
83 } AST_FORMAT_LIST[] = {                                 /*!< Bit number: comment  - Bit numbers are hard coded in show_codec() */
84         { 1, AST_FORMAT_G723_1 , "g723" , "G.723.1"},   /*!<  1 */
85         { 1, AST_FORMAT_GSM, "gsm" , "GSM"},            /*!<  2: codec_gsm.c */
86         { 1, AST_FORMAT_ULAW, "ulaw", "G.711 u-law" },  /*!<  3: codec_ulaw.c */
87         { 1, AST_FORMAT_ALAW, "alaw", "G.711 A-law" },  /*!<  4: codec_alaw.c */
88         { 1, AST_FORMAT_G726, "g726", "G.726 RFC3551" },/*!<  5: codec_g726.c */
89         { 1, AST_FORMAT_ADPCM, "adpcm" , "ADPCM"},      /*!<  6: codec_adpcm.c */
90         { 1, AST_FORMAT_SLINEAR, "slin",  "16 bit Signed Linear PCM"},  /*!< 7 */
91         { 1, AST_FORMAT_LPC10, "lpc10", "LPC10" },      /*!<  8: codec_lpc10.c */
92         { 1, AST_FORMAT_G729A, "g729", "G.729A" },      /*!<  9: Binary commercial distribution */
93         { 1, AST_FORMAT_SPEEX, "speex", "SpeeX" },      /*!< 10: codec_speex.c */
94         { 1, AST_FORMAT_ILBC, "ilbc", "iLBC"},          /*!< 11: codec_ilbc.c */
95         { 1, AST_FORMAT_G726_AAL2, "g726aal2", "G.726 AAL2" },  /*!<  12: codec_g726.c */
96         { 0, 0, "nothing", "undefined" },
97         { 0, 0, "nothing", "undefined" },
98         { 0, 0, "nothing", "undefined" },
99         { 0, 0, "nothing", "undefined" },
100         { 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" },        
101         { 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"},    /*!< 17: See format_jpeg.c */
102         { 1, AST_FORMAT_PNG, "png", "PNG image"},       /*!< 18: Image format */
103         { 1, AST_FORMAT_H261, "h261", "H.261 Video" },  /*!< 19: Video Passthrough */
104         { 1, AST_FORMAT_H263, "h263", "H.263 Video" },  /*!< 20: Passthrough support, see format_h263.c */
105         { 1, AST_FORMAT_H263_PLUS, "h263p", "H.263+ Video" },   /*!< 21: See format_h263.c */
106         { 1, AST_FORMAT_H264, "h264", "H.264 Video" },  /*!< 22: Passthrough support, see format_h263.c */
107         { 0, 0, "nothing", "undefined" },
108         { 0, 0, "nothing", "undefined" },
109         { 0, 0, "nothing", "undefined" },
110         { 0, AST_FORMAT_MAX_VIDEO, "maxvideo", "Maximum video format" },
111 };
112
113 struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
114
115 void ast_smoother_reset(struct ast_smoother *s, int size)
116 {
117         memset(s, 0, sizeof(*s));
118         s->size = size;
119 }
120
121 struct ast_smoother *ast_smoother_new(int size)
122 {
123         struct ast_smoother *s;
124         if (size < 1)
125                 return NULL;
126         if ((s = ast_malloc(sizeof(*s))))
127                 ast_smoother_reset(s, size);
128         return s;
129 }
130
131 int ast_smoother_get_flags(struct ast_smoother *s)
132 {
133         return s->flags;
134 }
135
136 void ast_smoother_set_flags(struct ast_smoother *s, int flags)
137 {
138         s->flags = flags;
139 }
140
141 int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
142 {
143         if (f->frametype != AST_FRAME_VOICE) {
144                 ast_log(LOG_WARNING, "Huh?  Can't smooth a non-voice frame!\n");
145                 return -1;
146         }
147         if (!s->format) {
148                 s->format = f->subclass;
149                 s->samplesperbyte = (float)f->samples / (float)f->datalen;
150         } else if (s->format != f->subclass) {
151                 ast_log(LOG_WARNING, "Smoother was working on %d format frames, now trying to feed %d?\n", s->format, f->subclass);
152                 return -1;
153         }
154         if (s->len + f->datalen > SMOOTHER_SIZE) {
155                 ast_log(LOG_WARNING, "Out of smoother space\n");
156                 return -1;
157         }
158         if (((f->datalen == s->size) || ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729)))
159                                  && !s->opt && (f->offset >= AST_MIN_OFFSET)) {
160                 if (!s->len) {
161                         /* Optimize by sending the frame we just got
162                            on the next read, thus eliminating the douple
163                            copy */
164                         s->opt = f;
165                         return 0;
166                 } else {
167                         s->optimizablestream++;
168                         if (s->optimizablestream > 10) {
169                                 /* For the past 10 rounds, we have input and output
170                                    frames of the correct size for this smoother, yet
171                                    we were unable to optimize because there was still
172                                    some cruft left over.  Lets just drop the cruft so
173                                    we can move to a fully optimized path */
174                                 s->len = 0;
175                                 s->opt = f;
176                                 return 0;
177                         }
178                 }
179         } else 
180                 s->optimizablestream = 0;
181         if (s->flags & AST_SMOOTHER_FLAG_G729) {
182                 if (s->len % 10) {
183                         ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
184                         return 0;
185                 }
186         }
187         if (swap)
188                 ast_swapcopy_samples(s->data+s->len, f->data, f->samples);
189         else
190                 memcpy(s->data + s->len, f->data, f->datalen);
191         /* If either side is empty, reset the delivery time */
192         if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery))      /* XXX really ? */
193                 s->delivery = f->delivery;
194         s->len += f->datalen;
195         return 0;
196 }
197
198 struct ast_frame *ast_smoother_read(struct ast_smoother *s)
199 {
200         struct ast_frame *opt;
201         int len;
202
203         /* IF we have an optimization frame, send it */
204         if (s->opt) {
205                 if (s->opt->offset < AST_FRIENDLY_OFFSET)
206                         ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).",
207                                                         s->opt->offset);
208                 opt = s->opt;
209                 s->opt = NULL;
210                 return opt;
211         }
212
213         /* Make sure we have enough data */
214         if (s->len < s->size) {
215                 /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */
216                 if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->size % 10)))
217                         return NULL;
218         }
219         len = s->size;
220         if (len > s->len)
221                 len = s->len;
222         /* Make frame */
223         s->f.frametype = AST_FRAME_VOICE;
224         s->f.subclass = s->format;
225         s->f.data = s->framedata + AST_FRIENDLY_OFFSET;
226         s->f.offset = AST_FRIENDLY_OFFSET;
227         s->f.datalen = len;
228         /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
229         s->f.samples = len * s->samplesperbyte; /* XXX rounding */
230         s->f.delivery = s->delivery;
231         /* Fill Data */
232         memcpy(s->f.data, s->data, len);
233         s->len -= len;
234         /* Move remaining data to the front if applicable */
235         if (s->len) {
236                 /* In principle this should all be fine because if we are sending
237                    G.729 VAD, the next timestamp will take over anyawy */
238                 memmove(s->data, s->data + len, s->len);
239                 if (!ast_tvzero(s->delivery)) {
240                         /* If we have delivery time, increment it, otherwise, leave it at 0 */
241                         s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, 8000));
242                 }
243         }
244         /* Return frame */
245         return &s->f;
246 }
247
248 void ast_smoother_free(struct ast_smoother *s)
249 {
250         free(s);
251 }
252
253 static struct ast_frame *ast_frame_header_new(void)
254 {
255         struct ast_frame *f = ast_calloc(1, sizeof(*f));
256 #ifdef TRACE_FRAMES
257         if (f) {
258                 headers++;
259                 f->prev = NULL;
260                 ast_mutex_lock(&framelock);
261                 f->next = headerlist;
262                 if (headerlist)
263                         headerlist->prev = f;
264                 headerlist = f;
265                 ast_mutex_unlock(&framelock);
266         }
267 #endif  
268         return f;
269 }
270
271 /*!
272  * \todo Important: I should be made more efficient.  Frame headers should
273  * most definitely be cached
274  */
275 void ast_frfree(struct ast_frame *fr)
276 {
277         if (fr->mallocd & AST_MALLOCD_DATA) {
278                 if (fr->data) 
279                         free(fr->data - fr->offset);
280         }
281         if (fr->mallocd & AST_MALLOCD_SRC) {
282                 if (fr->src)
283                         free((char *)fr->src);
284         }
285         if (fr->mallocd & AST_MALLOCD_HDR) {
286 #ifdef TRACE_FRAMES
287                 headers--;
288                 ast_mutex_lock(&framelock);
289                 if (fr->next)
290                         fr->next->prev = fr->prev;
291                 if (fr->prev)
292                         fr->prev->next = fr->next;
293                 else
294                         headerlist = fr->next;
295                 ast_mutex_unlock(&framelock);
296 #endif                  
297                 free(fr);
298         }
299 }
300
301 /*!
302  * \brief 'isolates' a frame by duplicating non-malloc'ed components
303  * (header, src, data).
304  * On return all components are malloc'ed
305  */
306 struct ast_frame *ast_frisolate(struct ast_frame *fr)
307 {
308         struct ast_frame *out;
309         void *newdata;
310         
311         if (!(fr->mallocd & AST_MALLOCD_HDR)) {
312                 /* Allocate a new header if needed */
313                 if (!(out = ast_frame_header_new()))
314                         return NULL;
315                 out->frametype = fr->frametype;
316                 out->subclass = fr->subclass;
317                 out->datalen = fr->datalen;
318                 out->samples = fr->samples;
319                 out->offset = fr->offset;
320                 out->data = fr->data;
321                 /* Copy the timing data */
322                 out->has_timing_info = fr->has_timing_info;
323                 if (fr->has_timing_info) {
324                         out->ts = fr->ts;
325                         out->len = fr->len;
326                         out->seqno = fr->seqno;
327                 }
328         } else
329                 out = fr;
330         
331         if (!(fr->mallocd & AST_MALLOCD_SRC)) {
332                 if (fr->src) {
333                         if (!(out->src = ast_strdup(fr->src))) {
334                                 if (out != fr)
335                                         free(out);
336                                 return NULL;
337                         }
338                 }
339         } else
340                 out->src = fr->src;
341         
342         if (!(fr->mallocd & AST_MALLOCD_DATA))  {
343                 if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
344                         if (out->src != fr->src)
345                                 free((void *) out->src);
346                         if (out != fr)
347                                 free(out);
348                         return NULL;
349                 }
350                 newdata += AST_FRIENDLY_OFFSET;
351                 out->offset = AST_FRIENDLY_OFFSET;
352                 out->datalen = fr->datalen;
353                 memcpy(newdata, fr->data, fr->datalen);
354                 out->data = newdata;
355         }
356
357         out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
358         
359         return out;
360 }
361
362 struct ast_frame *ast_frdup(struct ast_frame *f)
363 {
364         struct ast_frame *out;
365         int len, srclen = 0;
366         void *buf;
367         /* Start with standard stuff */
368         len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
369         /* If we have a source, add space for it */
370         /*
371          * XXX Watch out here - if we receive a src which is not terminated
372          * properly, we can be easily attacked. Should limit the size we deal with.
373          */
374         if (f->src)
375                 srclen = strlen(f->src);
376         if (srclen > 0)
377                 len += srclen + 1;
378         if (!(buf = ast_malloc(len)))
379                 return NULL;
380         out = buf;
381         /* Set us as having malloc'd header only, so it will eventually
382            get freed. */
383         out->frametype = f->frametype;
384         out->subclass = f->subclass;
385         out->datalen = f->datalen;
386         out->samples = f->samples;
387         out->delivery = f->delivery;
388         out->mallocd = AST_MALLOCD_HDR;
389         out->offset = AST_FRIENDLY_OFFSET;
390         out->data = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
391         if (srclen > 0) {
392                 out->src = out->data + f->datalen;
393                 /* Must have space since we allocated for it */
394                 strcpy((char *)out->src, f->src);
395         } else
396                 out->src = NULL;
397         out->prev = NULL;
398         out->next = NULL;
399         memcpy(out->data, f->data, out->datalen);       
400         out->has_timing_info = f->has_timing_info;
401         if (f->has_timing_info) {
402                 out->ts = f->ts;
403                 out->len = f->len;
404                 out->seqno = f->seqno;
405         }
406         return out;
407 }
408
409 #if 0
410 /*
411  * XXX
412  * This function is badly broken - it does not handle correctly
413  * partial reads on either header or body.
414  * However is it never used anywhere so we leave it commented out
415  */
416 struct ast_frame *ast_fr_fdread(int fd)
417 {
418         char buf[65536];
419         int res;        
420         struct ast_frame *f = (struct ast_frame *)buf;
421         int ttl = sizeof(*f);
422         /* Read a frame directly from there.  They're always in the
423            right format. */
424         
425         while(ttl) {
426                 res = read(fd, buf, ttl);
427                 if (res < 0) {
428                         ast_log(LOG_WARNING, "Bad read on %d: %s\n", fd, strerror(errno));
429                         return NULL;
430                 }
431                 ttl -= res;
432         }
433         
434         /* read the frame header */
435
436         /* Re-write data position */
437         f->data = buf + sizeof(*f);
438         f->offset = 0;
439         /* Forget about being mallocd */
440         f->mallocd = 0;
441         /* Re-write the source */
442         f->src = (char *)__FUNCTION__;
443         if (f->datalen > sizeof(buf) - sizeof(*f)) {
444                 /* Really bad read */
445                 ast_log(LOG_WARNING, "Strange read (%d bytes)\n", f->datalen);
446                 return NULL;
447         }
448         if (f->datalen) {
449                 if ((res = read(fd, f->data, f->datalen)) != f->datalen) {
450                         /* Bad read */
451                         ast_log(LOG_WARNING, "How very strange, expected %d, got %d\n", f->datalen, res);
452                         return NULL;
453                 }
454         }
455         if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
456                 return NULL;
457         }
458         return ast_frisolate(f);
459 }
460
461 /* Some convenient routines for sending frames to/from stream or datagram
462    sockets, pipes, etc (maybe even files) */
463
464 /*
465  * XXX this function is also partly broken because it does not handle
466  * partial writes. We comment it out too, and also the unique
467  * client it has, ast_fr_fdhangup()
468  */
469 int ast_fr_fdwrite(int fd, struct ast_frame *frame)
470 {
471         /* Write the frame exactly */
472         if (write(fd, frame, sizeof(*frame)) != sizeof(*frame)) {
473                 ast_log(LOG_WARNING, "Write error: %s\n", strerror(errno));
474                 return -1;
475         }
476         if (write(fd, frame->data, frame->datalen) != frame->datalen) {
477                 ast_log(LOG_WARNING, "Write error: %s\n", strerror(errno));
478                 return -1;
479         }
480         return 0;
481 }
482
483 int ast_fr_fdhangup(int fd)
484 {
485         struct ast_frame hangup = {
486                 AST_FRAME_CONTROL,
487                 AST_CONTROL_HANGUP
488         };
489         return ast_fr_fdwrite(fd, &hangup);
490 }
491
492 #endif /* unused functions */
493
494 void ast_swapcopy_samples(void *dst, const void *src, int samples)
495 {
496         int i;
497         unsigned short *dst_s = dst;
498         const unsigned short *src_s = src;
499
500         for (i = 0; i < samples; i++)
501                 dst_s[i] = (src_s[i]<<8) | (src_s[i]>>8);
502 }
503
504
505 struct ast_format_list *ast_get_format_list_index(int index) 
506 {
507         return &AST_FORMAT_LIST[index];
508 }
509
510 struct ast_format_list *ast_get_format_list(size_t *size) 
511 {
512         *size = (sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]));
513         return AST_FORMAT_LIST;
514 }
515
516 char* ast_getformatname(int format)
517 {
518         int x;
519         char *ret = "unknown";
520         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
521                 if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == format) {
522                         ret = AST_FORMAT_LIST[x].name;
523                         break;
524                 }
525         }
526         return ret;
527 }
528
529 char *ast_getformatname_multiple(char *buf, size_t size, int format)
530 {
531         int x;
532         unsigned len;
533         char *start, *end = buf;
534
535         if (!size)
536                 return buf;
537         snprintf(end, size, "0x%x (", format);
538         len = strlen(end);
539         end += len;
540         size -= len;
541         start = end;
542         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
543                 if (AST_FORMAT_LIST[x].visible && (AST_FORMAT_LIST[x].bits & format)) {
544                         snprintf(end, size,"%s|",AST_FORMAT_LIST[x].name);
545                         len = strlen(end);
546                         end += len;
547                         size -= len;
548                 }
549         }
550         if (start == end)
551                 snprintf(start, size, "nothing)");
552         else if (size > 1)
553                 *(end -1) = ')';
554         return buf;
555 }
556
557 static struct ast_codec_alias_table {
558         char *alias;
559         char *realname;
560 } ast_codec_alias_table[] = {
561         { "slinear", "slin"},
562         { "g723.1", "g723"},
563 };
564
565 static const char *ast_expand_codec_alias(const char *in)
566 {
567         int x;
568
569         for (x = 0; x < sizeof(ast_codec_alias_table) / sizeof(ast_codec_alias_table[0]); x++) {
570                 if(!strcmp(in,ast_codec_alias_table[x].alias))
571                         return ast_codec_alias_table[x].realname;
572         }
573         return in;
574 }
575
576 int ast_getformatbyname(const char *name)
577 {
578         int x, all, format = 0;
579
580         all = strcasecmp(name, "all") ? 0 : 1;
581         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
582                 if(AST_FORMAT_LIST[x].visible && (all || 
583                           !strcasecmp(AST_FORMAT_LIST[x].name,name) ||
584                           !strcasecmp(AST_FORMAT_LIST[x].name,ast_expand_codec_alias(name)))) {
585                         format |= AST_FORMAT_LIST[x].bits;
586                         if(!all)
587                                 break;
588                 }
589         }
590
591         return format;
592 }
593
594 char *ast_codec2str(int codec)
595 {
596         int x;
597         char *ret = "unknown";
598         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
599                 if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == codec) {
600                         ret = AST_FORMAT_LIST[x].desc;
601                         break;
602                 }
603         }
604         return ret;
605 }
606
607 static int show_codecs(int fd, int argc, char *argv[])
608 {
609         int i, found=0;
610         char hex[25];
611         
612         if ((argc < 2) || (argc > 3))
613                 return RESULT_SHOWUSAGE;
614
615         if (!ast_opt_dont_warn)
616                 ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n"
617                                 "\tIt does not indicate anything about your configuration.\n");
618
619         ast_cli(fd, "%11s %9s %10s   TYPE   %5s   %s\n","INT","BINARY","HEX","NAME","DESC");
620         ast_cli(fd, "--------------------------------------------------------------------------------\n");
621         if ((argc == 2) || (!strcasecmp(argv[1],"audio"))) {
622                 found = 1;
623                 for (i=0;i<11;i++) {
624                         snprintf(hex,25,"(0x%x)",1<<i);
625                         ast_cli(fd, "%11u (1 << %2d) %10s  audio   %5s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
626                 }
627         }
628
629         if ((argc == 2) || (!strcasecmp(argv[1],"image"))) {
630                 found = 1;
631                 for (i=16;i<18;i++) {
632                         snprintf(hex,25,"(0x%x)",1<<i);
633                         ast_cli(fd, "%11u (1 << %2d) %10s  image   %5s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
634                 }
635         }
636
637         if ((argc == 2) || (!strcasecmp(argv[1],"video"))) {
638                 found = 1;
639                 for (i=18;i<22;i++) {
640                         snprintf(hex,25,"(0x%x)",1<<i);
641                         ast_cli(fd, "%11u (1 << %2d) %10s  video   %5s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
642                 }
643         }
644
645         if (! found)
646                 return RESULT_SHOWUSAGE;
647         else
648                 return RESULT_SUCCESS;
649 }
650
651 static char frame_show_codecs_usage[] =
652 "Usage: show [audio|video|image] codecs\n"
653 "       Displays codec mapping\n";
654
655 static int show_codec_n(int fd, int argc, char *argv[])
656 {
657         int codec, i, found=0;
658
659         if (argc != 3)
660                 return RESULT_SHOWUSAGE;
661
662         if (sscanf(argv[2],"%d",&codec) != 1)
663                 return RESULT_SHOWUSAGE;
664
665         for (i = 0; i < 32; i++)
666                 if (codec & (1 << i)) {
667                         found = 1;
668                         ast_cli(fd, "%11u (1 << %2d)  %s\n",1 << i,i,ast_codec2str(1<<i));
669                 }
670
671         if (!found)
672                 ast_cli(fd, "Codec %d not found\n", codec);
673
674         return RESULT_SUCCESS;
675 }
676
677 static char frame_show_codec_n_usage[] =
678 "Usage: show codec <number>\n"
679 "       Displays codec mapping\n";
680
681 /*! Dump a frame for debugging purposes */
682 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
683 {
684         const char noname[] = "unknown";
685         char ftype[40] = "Unknown Frametype";
686         char cft[80];
687         char subclass[40] = "Unknown Subclass";
688         char csub[80];
689         char moreinfo[40] = "";
690         char cn[60];
691         char cp[40];
692         char cmn[40];
693
694         if (!name)
695                 name = noname;
696
697
698         if (!f) {
699                 ast_verbose("%s [ %s (NULL) ] [%s]\n", 
700                         term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
701                         term_color(cft, "HANGUP", COLOR_BRRED, COLOR_BLACK, sizeof(cft)), 
702                         term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
703                 return;
704         }
705         /* XXX We should probably print one each of voice and video when the format changes XXX */
706         if (f->frametype == AST_FRAME_VOICE)
707                 return;
708         if (f->frametype == AST_FRAME_VIDEO)
709                 return;
710         switch(f->frametype) {
711         case AST_FRAME_DTMF:
712                 strcpy(ftype, "DTMF");
713                 subclass[0] = f->subclass;
714                 subclass[1] = '\0';
715                 break;
716         case AST_FRAME_CONTROL:
717                 strcpy(ftype, "Control");
718                 switch(f->subclass) {
719                 case AST_CONTROL_HANGUP:
720                         strcpy(subclass, "Hangup");
721                         break;
722                 case AST_CONTROL_RING:
723                         strcpy(subclass, "Ring");
724                         break;
725                 case AST_CONTROL_RINGING:
726                         strcpy(subclass, "Ringing");
727                         break;
728                 case AST_CONTROL_ANSWER:
729                         strcpy(subclass, "Answer");
730                         break;
731                 case AST_CONTROL_BUSY:
732                         strcpy(subclass, "Busy");
733                         break;
734                 case AST_CONTROL_TAKEOFFHOOK:
735                         strcpy(subclass, "Take Off Hook");
736                         break;
737                 case AST_CONTROL_OFFHOOK:
738                         strcpy(subclass, "Line Off Hook");
739                         break;
740                 case AST_CONTROL_CONGESTION:
741                         strcpy(subclass, "Congestion");
742                         break;
743                 case AST_CONTROL_FLASH:
744                         strcpy(subclass, "Flash");
745                         break;
746                 case AST_CONTROL_WINK:
747                         strcpy(subclass, "Wink");
748                         break;
749                 case AST_CONTROL_OPTION:
750                         strcpy(subclass, "Option");
751                         break;
752                 case AST_CONTROL_RADIO_KEY:
753                         strcpy(subclass, "Key Radio");
754                         break;
755                 case AST_CONTROL_RADIO_UNKEY:
756                         strcpy(subclass, "Unkey Radio");
757                         break;
758                 case -1:
759                         strcpy(subclass, "Stop generators");
760                         break;
761                 default:
762                         snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass);
763                 }
764                 break;
765         case AST_FRAME_NULL:
766                 strcpy(ftype, "Null Frame");
767                 strcpy(subclass, "N/A");
768                 break;
769         case AST_FRAME_IAX:
770                 /* Should never happen */
771                 strcpy(ftype, "IAX Specific");
772                 snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass);
773                 break;
774         case AST_FRAME_TEXT:
775                 strcpy(ftype, "Text");
776                 strcpy(subclass, "N/A");
777                 ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
778                 break;
779         case AST_FRAME_IMAGE:
780                 strcpy(ftype, "Image");
781                 snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass));
782                 break;
783         case AST_FRAME_HTML:
784                 strcpy(ftype, "HTML");
785                 switch(f->subclass) {
786                 case AST_HTML_URL:
787                         strcpy(subclass, "URL");
788                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
789                         break;
790                 case AST_HTML_DATA:
791                         strcpy(subclass, "Data");
792                         break;
793                 case AST_HTML_BEGIN:
794                         strcpy(subclass, "Begin");
795                         break;
796                 case AST_HTML_END:
797                         strcpy(subclass, "End");
798                         break;
799                 case AST_HTML_LDCOMPLETE:
800                         strcpy(subclass, "Load Complete");
801                         break;
802                 case AST_HTML_NOSUPPORT:
803                         strcpy(subclass, "No Support");
804                         break;
805                 case AST_HTML_LINKURL:
806                         strcpy(subclass, "Link URL");
807                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
808                         break;
809                 case AST_HTML_UNLINK:
810                         strcpy(subclass, "Unlink");
811                         break;
812                 case AST_HTML_LINKREJECT:
813                         strcpy(subclass, "Link Reject");
814                         break;
815                 default:
816                         snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass);
817                         break;
818                 }
819                 break;
820         case AST_FRAME_MODEM:
821                 strcpy(ftype, "Modem");
822                 switch (f->subclass) {
823                 case AST_MODEM_T38:
824                         strcpy(subclass, "T.38");
825                         break;
826                 case AST_MODEM_V150:
827                         strcpy(subclass, "V.150");
828                         break;
829                 default:
830                         snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass);
831                         break;
832                 }
833                 break;
834         default:
835                 snprintf(ftype, sizeof(ftype), "Unknown Frametype '%d'", f->frametype);
836         }
837         if (!ast_strlen_zero(moreinfo))
838                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",  
839                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
840                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
841                             f->frametype, 
842                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
843                             f->subclass, 
844                             term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
845                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
846         else
847                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",  
848                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
849                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
850                             f->frametype, 
851                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
852                             f->subclass, 
853                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
854 }
855
856
857 #ifdef TRACE_FRAMES
858 static int show_frame_stats(int fd, int argc, char *argv[])
859 {
860         struct ast_frame *f;
861         int x=1;
862         if (argc != 3)
863                 return RESULT_SHOWUSAGE;
864         ast_cli(fd, "     Framer Statistics     \n");
865         ast_cli(fd, "---------------------------\n");
866         ast_cli(fd, "Total allocated headers: %d\n", headers);
867         ast_cli(fd, "Queue Dump:\n");
868         ast_mutex_lock(&framelock);
869         for (f=headerlist; f; f = f->next) {
870                 ast_cli(fd, "%d.  Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>");
871         }
872         ast_mutex_unlock(&framelock);
873         return RESULT_SUCCESS;
874 }
875
876 static char frame_stats_usage[] =
877 "Usage: show frame stats\n"
878 "       Displays debugging statistics from framer\n";
879 #endif
880
881 /* Builtin Asterisk CLI-commands for debugging */
882 static struct ast_cli_entry my_clis[] = {
883 { { "show", "codecs", NULL }, show_codecs, "Shows codecs", frame_show_codecs_usage },
884 { { "show", "audio", "codecs", NULL }, show_codecs, "Shows audio codecs", frame_show_codecs_usage },
885 { { "show", "video", "codecs", NULL }, show_codecs, "Shows video codecs", frame_show_codecs_usage },
886 { { "show", "image", "codecs", NULL }, show_codecs, "Shows image codecs", frame_show_codecs_usage },
887 { { "show", "codec", NULL }, show_codec_n, "Shows a specific codec", frame_show_codec_n_usage },
888 #ifdef TRACE_FRAMES
889 { { "show", "frame", "stats", NULL }, show_frame_stats, "Shows frame statistics", frame_stats_usage },
890 #endif
891 };
892
893 int init_framer(void)
894 {
895         ast_cli_register_multiple(my_clis, sizeof(my_clis)/sizeof(my_clis[0]) );
896         return 0;       
897 }
898
899 void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right) 
900 {
901         int x, differential = (int) 'A', mem;
902         char *from, *to;
903
904         if(right) {
905                 from = pref->order;
906                 to = buf;
907                 mem = size;
908         } else {
909                 to = pref->order;
910                 from = buf;
911                 mem = 32;
912         }
913
914         memset(to, 0, mem);
915         for (x = 0; x < 32 ; x++) {
916                 if(!from[x])
917                         break;
918                 to[x] = right ? (from[x] + differential) : (from[x] - differential);
919         }
920 }
921
922 int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) 
923 {
924         int x, codec; 
925         size_t total_len, slen;
926         char *formatname;
927         
928         memset(buf,0,size);
929         total_len = size;
930         buf[0] = '(';
931         total_len--;
932         for(x = 0; x < 32 ; x++) {
933                 if(total_len <= 0)
934                         break;
935                 if(!(codec = ast_codec_pref_index(pref,x)))
936                         break;
937                 if((formatname = ast_getformatname(codec))) {
938                         slen = strlen(formatname);
939                         if(slen > total_len)
940                                 break;
941                         strncat(buf,formatname,total_len);
942                         total_len -= slen;
943                 }
944                 if(total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) {
945                         strncat(buf,"|",total_len);
946                         total_len--;
947                 }
948         }
949         if(total_len) {
950                 strncat(buf,")",total_len);
951                 total_len--;
952         }
953
954         return size - total_len;
955 }
956
957 int ast_codec_pref_index(struct ast_codec_pref *pref, int index) 
958 {
959         int slot = 0;
960
961         
962         if((index >= 0) && (index < sizeof(pref->order))) {
963                 slot = pref->order[index];
964         }
965
966         return slot ? AST_FORMAT_LIST[slot-1].bits : 0;
967 }
968
969 /*! \brief Remove codec from pref list */
970 void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
971 {
972         struct ast_codec_pref oldorder;
973         int x, y = 0;
974         int slot;
975
976         if(!pref->order[0])
977                 return;
978
979         memcpy(&oldorder, pref, sizeof(oldorder));
980         memset(pref, 0, sizeof(*pref));
981
982         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
983                 slot = oldorder.order[x];
984                 if(! slot)
985                         break;
986                 if(AST_FORMAT_LIST[slot-1].bits != format)
987                         pref->order[y++] = slot;
988         }
989         
990 }
991
992 /*! \brief Append codec to list */
993 int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
994 {
995         int x, newindex = -1;
996
997         ast_codec_pref_remove(pref, format);
998
999         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1000                 if(AST_FORMAT_LIST[x].bits == format) {
1001                         newindex = x + 1;
1002                         break;
1003                 }
1004         }
1005
1006         if(newindex) {
1007                 for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1008                         if(!pref->order[x]) {
1009                                 pref->order[x] = newindex;
1010                                 break;
1011                         }
1012                 }
1013         }
1014
1015         return x;
1016 }
1017
1018
1019 /*! \brief Pick a codec */
1020 int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best)
1021 {
1022         int x, ret = 0, slot;
1023
1024         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1025                 slot = pref->order[x];
1026
1027                 if (!slot)
1028                         break;
1029                 if (formats & AST_FORMAT_LIST[slot-1].bits) {
1030                         ret = AST_FORMAT_LIST[slot-1].bits;
1031                         break;
1032                 }
1033         }
1034         if(ret & AST_FORMAT_AUDIO_MASK)
1035                 return ret;
1036
1037         if (option_debug > 3)
1038                 ast_log(LOG_DEBUG, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
1039
1040         return find_best ? ast_best_codec(formats) : 0;
1041 }
1042
1043 void ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing) 
1044 {
1045         char *parse;
1046         char *this;
1047         int format;
1048
1049         parse = ast_strdupa(list);
1050         while ((this = strsep(&parse, ","))) {
1051                 if (!(format = ast_getformatbyname(this))) {
1052                         ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", this);
1053                         continue;
1054                 }
1055
1056                 if (mask) {
1057                         if (allowing)
1058                                 *mask |= format;
1059                         else
1060                                 *mask &= ~format;
1061                 }
1062
1063                 /* Set up a preference list for audio. Do not include video in preferences 
1064                    since we can not transcode video and have to use whatever is offered
1065                  */
1066                 if (pref && (format & AST_FORMAT_AUDIO_MASK)) {
1067                         if (strcasecmp(this, "all")) {
1068                                 if (allowing)
1069                                         ast_codec_pref_append(pref, format);
1070                                 else
1071                                         ast_codec_pref_remove(pref, format);
1072                         } else if (!allowing) {
1073                                 memset(pref, 0, sizeof(*pref));
1074                         }
1075                 }
1076         }
1077 }
1078
1079 static int g723_len(unsigned char buf)
1080 {
1081         enum frame_type type = buf & TYPE_MASK;
1082
1083         switch(type) {
1084         case TYPE_DONTSEND:
1085                 return 0;
1086                 break;
1087         case TYPE_SILENCE:
1088                 return 4;
1089                 break;
1090         case TYPE_HIGH:
1091                 return 24;
1092                 break;
1093         case TYPE_LOW:
1094                 return 20;
1095                 break;
1096         default:
1097                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
1098         }
1099         return -1;
1100 }
1101
1102 static int g723_samples(unsigned char *buf, int maxlen)
1103 {
1104         int pos = 0;
1105         int samples = 0;
1106         int res;
1107         while(pos < maxlen) {
1108                 res = g723_len(buf[pos]);
1109                 if (res <= 0)
1110                         break;
1111                 samples += 240;
1112                 pos += res;
1113         }
1114         return samples;
1115 }
1116
1117 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
1118 {
1119         int byte = bit / 8;       /* byte containing first bit */
1120         int rem = 8 - (bit % 8);  /* remaining bits in first byte */
1121         unsigned char ret = 0;
1122         
1123         if (n <= 0 || n > 8)
1124                 return 0;
1125
1126         if (rem < n) {
1127                 ret = (data[byte] << (n - rem));
1128                 ret |= (data[byte + 1] >> (8 - n + rem));
1129         } else {
1130                 ret = (data[byte] >> (rem - n));
1131         }
1132
1133         return (ret & (0xff >> (8 - n)));
1134 }
1135
1136 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
1137 {
1138         static int SpeexWBSubModeSz[] = {
1139                 0, 36, 112, 192,
1140                 352, 0, 0, 0 };
1141         int off = bit;
1142         unsigned char c;
1143
1144         /* skip up to two wideband frames */
1145         if (((len * 8 - off) >= 5) && 
1146                 get_n_bits_at(data, 1, off)) {
1147                 c = get_n_bits_at(data, 3, off + 1);
1148                 off += SpeexWBSubModeSz[c];
1149
1150                 if (((len * 8 - off) >= 5) && 
1151                         get_n_bits_at(data, 1, off)) {
1152                         c = get_n_bits_at(data, 3, off + 1);
1153                         off += SpeexWBSubModeSz[c];
1154
1155                         if (((len * 8 - off) >= 5) && 
1156                                 get_n_bits_at(data, 1, off)) {
1157                                 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
1158                                 return -1;
1159                         }
1160                 }
1161
1162         }
1163         return off - bit;
1164 }
1165
1166 static int speex_samples(unsigned char *data, int len)
1167 {
1168         static int SpeexSubModeSz[] = {
1169                5, 43, 119, 160,
1170                 220, 300, 364, 492, 
1171                 79, 0, 0, 0,
1172                 0, 0, 0, 0 };
1173         static int SpeexInBandSz[] = { 
1174                 1, 1, 4, 4,
1175                 4, 4, 4, 4,
1176                 8, 8, 16, 16,
1177                 32, 32, 64, 64 };
1178         int bit = 0;
1179         int cnt = 0;
1180         int off;
1181         unsigned char c;
1182
1183         while ((len * 8 - bit) >= 5) {
1184                 /* skip wideband frames */
1185                 off = speex_get_wb_sz_at(data, len, bit);
1186                 if (off < 0)  {
1187                         ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
1188                         break;
1189                 }
1190                 bit += off;
1191
1192                 if ((len * 8 - bit) < 5) {
1193                         ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n");
1194                         break;
1195                 }
1196
1197                 /* get control bits */
1198                 c = get_n_bits_at(data, 5, bit);
1199                 bit += 5;
1200
1201                 if (c == 15) { 
1202                         /* terminator */
1203                         break; 
1204                 } else if (c == 14) {
1205                         /* in-band signal; next 4 bits contain signal id */
1206                         c = get_n_bits_at(data, 4, bit);
1207                         bit += 4;
1208                         bit += SpeexInBandSz[c];
1209                 } else if (c == 13) {
1210                         /* user in-band; next 5 bits contain msg len */
1211                         c = get_n_bits_at(data, 5, bit);
1212                         bit += 5;
1213                         bit += c * 8;
1214                 } else if (c > 8) {
1215                         /* unknown */
1216                         break;
1217                 } else {
1218                         /* skip number bits for submode (less the 5 control bits) */
1219                         bit += SpeexSubModeSz[c] - 5;
1220                         cnt += 160; /* new frame */
1221                 }
1222         }
1223         return cnt;
1224 }
1225
1226 int ast_codec_get_samples(struct ast_frame *f)
1227 {
1228         int samples=0;
1229         switch(f->subclass) {
1230         case AST_FORMAT_SPEEX:
1231                 samples = speex_samples(f->data, f->datalen);
1232                 break;
1233         case AST_FORMAT_G723_1:
1234                 samples = g723_samples(f->data, f->datalen);
1235                 break;
1236         case AST_FORMAT_ILBC:
1237                 samples = 240 * (f->datalen / 50);
1238                 break;
1239         case AST_FORMAT_GSM:
1240                 samples = 160 * (f->datalen / 33);
1241                 break;
1242         case AST_FORMAT_G729A:
1243                 samples = f->datalen * 8;
1244                 break;
1245         case AST_FORMAT_SLINEAR:
1246                 samples = f->datalen / 2;
1247                 break;
1248         case AST_FORMAT_LPC10:
1249                 /* assumes that the RTP packet contains one LPC10 frame */
1250                 samples = 22 * 8;
1251                 samples += (((char *)(f->data))[7] & 0x1) * 8;
1252                 break;
1253         case AST_FORMAT_ULAW:
1254         case AST_FORMAT_ALAW:
1255                 samples = f->datalen;
1256                 break;
1257         case AST_FORMAT_ADPCM:
1258         case AST_FORMAT_G726:
1259         case AST_FORMAT_G726_AAL2:
1260                 samples = f->datalen * 2;
1261                 break;
1262         default:
1263                 ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
1264         }
1265         return samples;
1266 }
1267
1268 int ast_codec_get_len(int format, int samples)
1269 {
1270         int len = 0;
1271
1272         /* XXX Still need speex, g723, and lpc10 XXX */ 
1273         switch(format) {
1274         case AST_FORMAT_ILBC:
1275                 len = (samples / 240) * 50;
1276                 break;
1277         case AST_FORMAT_GSM:
1278                 len = (samples / 160) * 33;
1279                 break;
1280         case AST_FORMAT_G729A:
1281                 len = samples / 8;
1282                 break;
1283         case AST_FORMAT_SLINEAR:
1284                 len = samples * 2;
1285                 break;
1286         case AST_FORMAT_ULAW:
1287         case AST_FORMAT_ALAW:
1288                 len = samples;
1289                 break;
1290         case AST_FORMAT_ADPCM:
1291         case AST_FORMAT_G726:
1292         case AST_FORMAT_G726_AAL2:
1293                 len = samples / 2;
1294                 break;
1295         default:
1296                 ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
1297         }
1298
1299         return len;
1300 }
1301
1302 int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
1303 {
1304         int count;
1305         short *fdata = f->data;
1306         short adjust_value = abs(adjustment);
1307
1308         if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR))
1309                 return -1;
1310
1311         if (!adjustment)
1312                 return 0;
1313
1314         for (count = 0; count < f->samples; count++) {
1315                 if (adjustment > 0) {
1316                         ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
1317                 } else if (adjustment < 0) {
1318                         ast_slinear_saturated_divide(&fdata[count], &adjust_value);
1319                 }
1320         }
1321
1322         return 0;
1323 }
1324
1325 int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
1326 {
1327         int count;
1328         short *data1, *data2;
1329
1330         if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR))
1331                 return -1;
1332
1333         if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR))
1334                 return -1;
1335
1336         if (f1->samples != f2->samples)
1337                 return -1;
1338
1339         for (count = 0, data1 = f1->data, data2 = f2->data;
1340              count < f1->samples;
1341              count++, data1++, data2++)
1342                 ast_slinear_saturated_add(data1, data2);
1343
1344         return 0;
1345 }
1346
1347 struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe)
1348 {
1349         struct ast_frame *cur, *oldhead;
1350         int len=0;
1351         if (f && dupe)
1352                 f = ast_frdup(f);
1353         if (!f)
1354                 return head;
1355
1356         f->next = NULL;
1357         if (!head) 
1358                 return f;
1359         cur = head;
1360         while(cur->next) {
1361                 cur = cur->next;
1362                 len++;
1363                 if (len >= maxlen) {
1364                         oldhead = head;
1365                         head = head->next;
1366                         ast_frfree(oldhead);
1367                 }
1368         }
1369         return head;
1370 }