Let's also include aclocal.m4
[asterisk-bristuff.git] / formats / format_ilbc.c
blob78d11791098a49ba84ca2775990aaabfc6d7828e
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Brian K. West <brian@bkw.org>
5 *
6 * Copyright (C) 1999 - 2005, Digium, Inc.
8 * Mark Spencer <markster@digium.com>
10 * See http://www.asterisk.org for more information about
11 * the Asterisk project. Please do not directly contact
12 * any of the maintainers of this project for assistance;
13 * the project provides a web site, mailing lists and IRC
14 * channels for your use.
16 * This program is free software, distributed under the terms of
17 * the GNU General Public License Version 2. See the LICENSE file
18 * at the top of the source tree.
21 /*! \file
23 * \brief Save to raw, headerless iLBC data.
24 * \arg File name extension: ilbc
25 * \ingroup formats
28 #include "asterisk.h"
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32 #include <unistd.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <stdlib.h>
36 #include <sys/time.h>
37 #include <stdio.h>
38 #include <errno.h>
39 #include <string.h>
41 #include "asterisk/lock.h"
42 #include "asterisk/channel.h"
43 #include "asterisk/file.h"
44 #include "asterisk/logger.h"
45 #include "asterisk/sched.h"
46 #include "asterisk/module.h"
47 #include "asterisk/endian.h"
49 /* Some Ideas for this code came from makeg729e.c by Jeffrey Chilton */
51 /* Portions of the conversion code are by guido@sienanet.it */
53 #define ILBC_BUF_SIZE 50 /* One Real iLBC Frame */
54 #define ILBC_SAMPLES 240
56 static struct ast_frame *ilbc_read(struct ast_filestream *s, int *whennext)
58 int res;
59 /* Send a frame from the file to the appropriate channel */
60 s->fr.frametype = AST_FRAME_VOICE;
61 s->fr.subclass = AST_FORMAT_ILBC;
62 s->fr.mallocd = 0;
63 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, ILBC_BUF_SIZE);
64 if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
65 if (res)
66 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
67 return NULL;
69 *whennext = s->fr.samples = ILBC_SAMPLES;
70 return &s->fr;
73 static int ilbc_write(struct ast_filestream *fs, struct ast_frame *f)
75 int res;
76 if (f->frametype != AST_FRAME_VOICE) {
77 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
78 return -1;
80 if (f->subclass != AST_FORMAT_ILBC) {
81 ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%d)!\n", f->subclass);
82 return -1;
84 if (f->datalen % 50) {
85 ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 50\n", f->datalen);
86 return -1;
88 if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
89 ast_log(LOG_WARNING, "Bad write (%d/50): %s\n", res, strerror(errno));
90 return -1;
92 return 0;
95 static int ilbc_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
97 long bytes;
98 off_t min,cur,max,offset=0;
99 min = 0;
100 cur = ftello(fs->f);
101 fseeko(fs->f, 0, SEEK_END);
102 max = ftello(fs->f);
104 bytes = ILBC_BUF_SIZE * (sample_offset / ILBC_SAMPLES);
105 if (whence == SEEK_SET)
106 offset = bytes;
107 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
108 offset = cur + bytes;
109 else if (whence == SEEK_END)
110 offset = max - bytes;
111 if (whence != SEEK_FORCECUR) {
112 offset = (offset > max)?max:offset;
114 /* protect against seeking beyond begining. */
115 offset = (offset < min)?min:offset;
116 if (fseeko(fs->f, offset, SEEK_SET) < 0)
117 return -1;
118 return 0;
121 static int ilbc_trunc(struct ast_filestream *fs)
123 /* Truncate file to current length */
124 if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
125 return -1;
126 return 0;
129 static off_t ilbc_tell(struct ast_filestream *fs)
131 off_t offset = ftello(fs->f);
132 return (offset/ILBC_BUF_SIZE)*ILBC_SAMPLES;
135 static const struct ast_format ilbc_f = {
136 .name = "iLBC",
137 .exts = "ilbc",
138 .format = AST_FORMAT_ILBC,
139 .write = ilbc_write,
140 .seek = ilbc_seek,
141 .trunc = ilbc_trunc,
142 .tell = ilbc_tell,
143 .read = ilbc_read,
144 .buf_size = ILBC_BUF_SIZE + AST_FRIENDLY_OFFSET,
147 static int load_module(void)
149 return ast_format_register(&ilbc_f);
152 static int unload_module(void)
154 return ast_format_unregister(ilbc_f.name);
157 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw iLBC data");