Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


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 Format
21  * \arg File name extensions: sln, raw
22  * \ingroup formats
23  */
24 
25 /*** MODULEINFO
26  <support_level>core</support_level>
27  ***/
28 
29 #include "asterisk.h"
30 
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 364578 $")
32 
33 #include "asterisk/mod_format.h"
34 #include "asterisk/module.h"
35 #include "asterisk/endian.h"
36 
37 #define BUF_SIZE 320 /* 320 bytes, 160 samples */
38 #define SLIN_SAMPLES 160
39 
40 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
41 {
42  int res;
43  /* Send a frame from the file to the appropriate channel */
44 
47  s->fr.mallocd = 0;
49  if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
50  if (res)
51  ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
52  return NULL;
53  }
54  *whennext = s->fr.samples = res/2;
55  s->fr.datalen = res;
56  return &s->fr;
57 }
58 
59 static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
60 {
61  int res;
62  if (f->frametype != AST_FRAME_VOICE) {
63  ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
64  return -1;
65  }
66  if (f->subclass.codec != AST_FORMAT_SLINEAR) {
67  ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(f->subclass.codec));
68  return -1;
69  }
70  if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
71  ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
72  return -1;
73  }
74  return 0;
75 }
76 
77 static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
78 {
79  off_t offset=0, min = 0, cur, max;
80 
81  sample_offset <<= 1;
82 
83  if ((cur = ftello(fs->f)) < 0) {
84  ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
85  return -1;
86  }
87 
88  if (fseeko(fs->f, 0, SEEK_END) < 0) {
89  ast_log(AST_LOG_WARNING, "Unable to seek to end of sln filestream %p: %s\n", fs, strerror(errno));
90  return -1;
91  }
92 
93  if ((max = ftello(fs->f)) < 0) {
94  ast_log(AST_LOG_WARNING, "Unable to determine max position in sln filestream %p: %s\n", fs, strerror(errno));
95  return -1;
96  }
97 
98  if (whence == SEEK_SET)
99  offset = sample_offset;
100  else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
101  offset = sample_offset + cur;
102  else if (whence == SEEK_END)
103  offset = max - sample_offset;
104  if (whence != SEEK_FORCECUR) {
105  offset = (offset > max)?max:offset;
106  }
107  /* always protect against seeking past begining. */
108  offset = (offset < min)?min:offset;
109  return fseeko(fs->f, offset, SEEK_SET);
110 }
111 
112 static int slinear_trunc(struct ast_filestream *fs)
113 {
114  int fd;
115  off_t cur;
116 
117  if ((fd = fileno(fs->f)) < 0) {
118  ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for sln filestream %p: %s\n", fs, strerror(errno));
119  return -1;
120  }
121  if ((cur = ftello(fs->f)) < 0) {
122  ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
123  return -1;
124  }
125  /* Truncate file to current length */
126  return ftruncate(fd, cur);
127 }
128 
129 static off_t slinear_tell(struct ast_filestream *fs)
130 {
131  return ftello(fs->f) / 2;
132 }
133 
134 static const struct ast_format slin_f = {
135  .name = "sln",
136  .exts = "sln|raw",
137  .format = AST_FORMAT_SLINEAR,
138  .write = slinear_write,
139  .seek = slinear_seek,
140  .trunc = slinear_trunc,
141  .tell = slinear_tell,
142  .read = slinear_read,
143  .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
144 };
145 
146 static int load_module(void)
147 {
148  if (ast_format_register(&slin_f))
151 }
152 
153 static int unload_module(void)
154 {
155  return ast_format_unregister(slin_f.name);
156 }
157 
158 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN)",
159  .load = load_module,
160  .unload = unload_module,
161  .load_pri = AST_MODPRI_APP_DEPEND
162 );
union ast_frame_subclass subclass
Definition: frame.h:146
Asterisk main include file. File version handling, generic pbx functions.
#define ast_format_register(f)
Definition: mod_format.h:131
int offset
Definition: frame.h:156
static int load_module(void)
Definition: format_sln.c:146
void * ptr
Definition: frame.h:160
static struct ast_frame * slinear_read(struct ast_filestream *s, int *whennext)
Definition: format_sln.c:40
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
Each supported file format is described by the following structure.
Definition: mod_format.h:43
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
format_t codec
Definition: frame.h:137
static int unload_module(void)
Definition: format_sln.c:153
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
Definition: frame.h:183
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
Asterisk architecture endianess compatibility definitions.
int datalen
Definition: frame.h:148
struct ast_frame fr
Definition: mod_format.h:117
static off_t slinear_tell(struct ast_filestream *fs)
Definition: format_sln.c:129
int ast_format_unregister(const char *name)
Unregisters a file format.
Definition: file.c:104
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
char name[80]
Definition: mod_format.h:44
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define SEEK_FORCECUR
Definition: file.h:50
static struct ast_format f[]
Definition: format_g726.c:181
static struct ast_format slin_f
Definition: format_sln.c:134
int mallocd
Definition: frame.h:152
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:100
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
static int slinear_trunc(struct ast_filestream *fs)
Definition: format_sln.c:112
Data structure associated with a single frame of data.
Definition: frame.h:142
static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_sln.c:77
enum ast_frame_type frametype
Definition: frame.h:144
static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
Definition: format_sln.c:59
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
union ast_frame::@172 data
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
int samples
Definition: frame.h:150
#define BUF_SIZE
Definition: format_sln.c:37