Asterisk - The Open Source Telephony Project GIT-master-f36a736
format_sln.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Anthony Minessale
5 * Anthony Minessale (anthmct@yahoo.com)
6 *
7 * See http://www.asterisk.org for more information about
8 * the Asterisk project. Please do not directly contact
9 * any of the maintainers of this project for assistance;
10 * the project provides a web site, mailing lists and IRC
11 * channels for your use.
12 *
13 * This program is free software, distributed under the terms of
14 * the GNU General Public License Version 2. See the LICENSE file
15 * at the top of the source tree.
16 */
17
18/*! \file
19 *
20 * \brief RAW SLINEAR Formats
21 * \ingroup formats
22 */
23
24/*** MODULEINFO
25 <support_level>core</support_level>
26 ***/
27
28#include "asterisk.h"
29
30#include "asterisk/mod_format.h"
31#include "asterisk/module.h"
32#include "asterisk/endian.h"
34
35static struct ast_frame *generic_read(struct ast_filestream *s, int *whennext, unsigned int buf_size)
36{
37 size_t res;
38
39 /* Send a frame from the file to the appropriate channel */
41 if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
42 if (res) {
43 ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
45 strerror(errno));
46 }
47 return NULL;
48 }
49 *whennext = s->fr.samples = res/2;
50 s->fr.datalen = res;
51 return &s->fr;
52}
53
54static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
55{
56 int res;
57
58 /* Don't try to write an interpolated frame */
59 if (f->datalen == 0) {
60 return 0;
61 }
62
63 if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
64 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
65 return -1;
66 }
67 return 0;
68}
69
70static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
71{
72 off_t offset=0, min = 0, cur, max;
73
74 sample_offset <<= 1;
75
76 if ((cur = ftello(fs->f)) < 0) {
77 ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
78 return -1;
79 }
80
81 if (fseeko(fs->f, 0, SEEK_END) < 0) {
82 ast_log(AST_LOG_WARNING, "Unable to seek to end of sln filestream %p: %s\n", fs, strerror(errno));
83 return -1;
84 }
85
86 if ((max = ftello(fs->f)) < 0) {
87 ast_log(AST_LOG_WARNING, "Unable to determine max position in sln filestream %p: %s\n", fs, strerror(errno));
88 return -1;
89 }
90
91 if (whence == SEEK_SET)
92 offset = sample_offset;
93 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
94 offset = sample_offset + cur;
95 else if (whence == SEEK_END)
96 offset = max - sample_offset;
97 if (whence != SEEK_FORCECUR) {
99 }
100 /* always protect against seeking past begining. */
101 offset = (offset < min)?min:offset;
102 return fseeko(fs->f, offset, SEEK_SET);
103}
104
105static int slinear_trunc(struct ast_filestream *fs)
106{
107 int fd;
108 off_t cur;
109
110 if ((fd = fileno(fs->f)) < 0) {
111 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for sln filestream %p: %s\n", fs, strerror(errno));
112 return -1;
113 }
114 if ((cur = ftello(fs->f)) < 0) {
115 ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
116 return -1;
117 }
118 /* Truncate file to current length */
119 return ftruncate(fd, cur);
120}
121
122static off_t slinear_tell(struct ast_filestream *fs)
123{
124 return ftello(fs->f) / 2;
125}
126
127static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 320);}
128static struct ast_format_def slin_f = {
129 .name = "sln",
130 .exts = "sln|slin|raw",
131 .write = slinear_write,
132 .seek = slinear_seek,
133 .trunc = slinear_trunc,
134 .tell = slinear_tell,
135 .read = slinear_read,
136 .buf_size = 320 + AST_FRIENDLY_OFFSET,
137};
138
139static struct ast_frame *slinear12_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 480);}
140static struct ast_format_def slin12_f = {
141 .name = "sln12",
142 .exts = "sln12",
143 .write = slinear_write,
144 .seek = slinear_seek,
145 .trunc = slinear_trunc,
146 .tell = slinear_tell,
147 .read = slinear12_read,
148 .buf_size = 480 + AST_FRIENDLY_OFFSET,
149};
150
151static struct ast_frame *slinear16_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 640);}
152static struct ast_format_def slin16_f = {
153 .name = "sln16",
154 .exts = "sln16",
155 .write = slinear_write,
156 .seek = slinear_seek,
157 .trunc = slinear_trunc,
158 .tell = slinear_tell,
159 .read = slinear16_read,
160 .buf_size = 640 + AST_FRIENDLY_OFFSET,
161};
162
163static struct ast_frame *slinear24_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 960);}
164static struct ast_format_def slin24_f = {
165 .name = "sln24",
166 .exts = "sln24",
167 .write = slinear_write,
168 .seek = slinear_seek,
169 .trunc = slinear_trunc,
170 .tell = slinear_tell,
171 .read = slinear24_read,
172 .buf_size = 960 + AST_FRIENDLY_OFFSET,
173};
174
175static struct ast_frame *slinear32_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1280);}
176static struct ast_format_def slin32_f = {
177 .name = "sln32",
178 .exts = "sln32",
179 .write = slinear_write,
180 .seek = slinear_seek,
181 .trunc = slinear_trunc,
182 .tell = slinear_tell,
183 .read = slinear32_read,
184 .buf_size = 1280 + AST_FRIENDLY_OFFSET,
185};
186
187static struct ast_frame *slinear44_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1764);}
188static struct ast_format_def slin44_f = {
189 .name = "sln44",
190 .exts = "sln44",
191 .write = slinear_write,
192 .seek = slinear_seek,
193 .trunc = slinear_trunc,
194 .tell = slinear_tell,
195 .read = slinear44_read,
196 .buf_size = 1764 + AST_FRIENDLY_OFFSET,
197};
198
199static struct ast_frame *slinear48_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1920);}
200static struct ast_format_def slin48_f = {
201 .name = "sln48",
202 .exts = "sln48",
203 .write = slinear_write,
204 .seek = slinear_seek,
205 .trunc = slinear_trunc,
206 .tell = slinear_tell,
207 .read = slinear48_read,
208 .buf_size = 1920 + AST_FRIENDLY_OFFSET,
209};
210
211static struct ast_frame *slinear96_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 3840);}
212static struct ast_format_def slin96_f = {
213 .name = "sln96",
214 .exts = "sln96",
215 .write = slinear_write,
216 .seek = slinear_seek,
217 .trunc = slinear_trunc,
218 .tell = slinear_tell,
219 .read = slinear96_read,
220 .buf_size = 3840 + AST_FRIENDLY_OFFSET,
221};
222
223static struct ast_frame *slinear192_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 7680);}
224static struct ast_format_def slin192_f = {
225 .name = "sln192",
226 .exts = "sln192",
227 .write = slinear_write,
228 .seek = slinear_seek,
229 .trunc = slinear_trunc,
230 .tell = slinear_tell,
231 .read = slinear192_read,
232 .buf_size = 7680 + AST_FRIENDLY_OFFSET,
233};
234
235static struct ast_format_def *slin_list[] = {
236 &slin_f,
237 &slin12_f,
238 &slin16_f,
239 &slin24_f,
240 &slin32_f,
241 &slin44_f,
242 &slin48_f,
243 &slin96_f,
244 &slin192_f,
245};
246
247static int unload_module(void)
248{
249 int res = 0;
250 int i = 0;
251
252 for (i = 0; i < ARRAY_LEN(slin_list); i++) {
254 res = -1;
255 }
256 }
257 return res;
258}
259
260static int load_module(void)
261{
262 int i;
263
273
274 for (i = 0; i < ARRAY_LEN(slin_list); i++) {
278 }
279 }
280
282}
283
284AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN) 8khz-192khz",
285 .support_level = AST_MODULE_SUPPORT_CORE,
286 .load = load_module,
287 .unload = unload_module,
288 .load_pri = AST_MODPRI_APP_DEPEND
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
Asterisk architecture endianess compatibility definitions.
#define min(a, b)
Definition: f2c.h:197
#define max(a, b)
Definition: f2c.h:198
#define SEEK_FORCECUR
Definition: file.h:51
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Media Format Cache API.
struct ast_format * ast_format_slin44
Built-in cached signed linear 44kHz format.
Definition: format_cache.c:66
struct ast_format * ast_format_slin24
Built-in cached signed linear 24kHz format.
Definition: format_cache.c:56
struct ast_format * ast_format_slin32
Built-in cached signed linear 32kHz format.
Definition: format_cache.c:61
struct ast_format * ast_format_slin192
Built-in cached signed linear 192kHz format.
Definition: format_cache.c:81
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
struct ast_format * ast_format_slin96
Built-in cached signed linear 96kHz format.
Definition: format_cache.c:76
struct ast_format * ast_format_slin48
Built-in cached signed linear 48kHz format.
Definition: format_cache.c:71
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_format_slin12
Built-in cached signed linear 12kHz format.
Definition: format_cache.c:46
static const char name[]
Definition: format_mp3.c:68
static struct ast_frame * generic_read(struct ast_filestream *s, int *whennext, unsigned int buf_size)
Definition: format_sln.c:35
static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_sln.c:70
static struct ast_format_def slin16_f
Definition: format_sln.c:152
static int slinear_trunc(struct ast_filestream *fs)
Definition: format_sln.c:105
static off_t slinear_tell(struct ast_filestream *fs)
Definition: format_sln.c:122
static struct ast_frame * slinear192_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:223
static struct ast_format_def slin_f
Definition: format_sln.c:128
static struct ast_format_def slin44_f
Definition: format_sln.c:188
static struct ast_frame * slinear24_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:163
static struct ast_frame * slinear44_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:187
static struct ast_frame * slinear96_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:211
static struct ast_frame * slinear16_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:151
static struct ast_format_def * slin_list[]
Definition: format_sln.c:235
static struct ast_format_def slin12_f
Definition: format_sln.c:140
static struct ast_frame * slinear12_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:139
static struct ast_frame * slinear32_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:175
static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
Definition: format_sln.c:54
static struct ast_frame * slinear48_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:199
static struct ast_format_def slin48_f
Definition: format_sln.c:200
static int load_module(void)
Definition: format_sln.c:260
static struct ast_format_def slin32_f
Definition: format_sln.c:176
static struct ast_format_def slin24_f
Definition: format_sln.c:164
static int unload_module(void)
Definition: format_sln.c:247
static struct ast_format_def slin192_f
Definition: format_sln.c:224
static struct ast_frame * slinear_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:127
static struct ast_format_def slin96_f
Definition: format_sln.c:212
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define AST_LOG_WARNING
#define LOG_WARNING
int errno
Header for providers of file and format handling routines. Clients of these routines should include "...
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
#define ast_format_def_register(f)
Definition: mod_format.h:136
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:331
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODPRI_APP_DEPEND
Definition: module.h:342
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define NULL
Definition: resample.c:96
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
Each supported file format is described by the following structure.
Definition: mod_format.h:43
char name[80]
Definition: mod_format.h:44
struct ast_format * format
Definition: mod_format.h:48
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
#define ARRAY_LEN(a)
Definition: utils.h:666