00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328259 $")
00031
00032 #include "asterisk/mod_format.h"
00033 #include "asterisk/module.h"
00034 #include "asterisk/endian.h"
00035
00036 static struct ast_frame *generic_read(struct ast_filestream *s, int *whennext, unsigned int buf_size, enum ast_format_id id)
00037 {
00038 int res;
00039
00040
00041 s->fr.frametype = AST_FRAME_VOICE;
00042 ast_format_set(&s->fr.subclass.format, id, 0);
00043 s->fr.mallocd = 0;
00044 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, buf_size);
00045 if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
00046 if (res)
00047 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00048 return NULL;
00049 }
00050 *whennext = s->fr.samples = res/2;
00051 s->fr.datalen = res;
00052 return &s->fr;
00053 }
00054
00055 static int generic_write(struct ast_filestream *fs, struct ast_frame *f, enum ast_format_id id)
00056 {
00057 int res;
00058 if (f->frametype != AST_FRAME_VOICE) {
00059 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00060 return -1;
00061 }
00062 if (f->subclass.format.id != id) {
00063 ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(&f->subclass.format));
00064 return -1;
00065 }
00066 if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
00067 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00068 return -1;
00069 }
00070 return 0;
00071 }
00072
00073 static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00074 {
00075 off_t offset=0,min,cur,max;
00076
00077 min = 0;
00078 sample_offset <<= 1;
00079 cur = ftello(fs->f);
00080 fseeko(fs->f, 0, SEEK_END);
00081 max = ftello(fs->f);
00082 if (whence == SEEK_SET)
00083 offset = sample_offset;
00084 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
00085 offset = sample_offset + cur;
00086 else if (whence == SEEK_END)
00087 offset = max - sample_offset;
00088 if (whence != SEEK_FORCECUR) {
00089 offset = (offset > max)?max:offset;
00090 }
00091
00092 offset = (offset < min)?min:offset;
00093 return fseeko(fs->f, offset, SEEK_SET);
00094 }
00095
00096 static int slinear_trunc(struct ast_filestream *fs)
00097 {
00098 return ftruncate(fileno(fs->f), ftello(fs->f));
00099 }
00100
00101 static off_t slinear_tell(struct ast_filestream *fs)
00102 {
00103 return ftello(fs->f) / 2;
00104 }
00105
00106 static int slinear_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR);}
00107 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 320, AST_FORMAT_SLINEAR);}
00108 static struct ast_format_def slin_f = {
00109 .name = "sln",
00110 .exts = "sln|raw",
00111 .write = slinear_write,
00112 .seek = slinear_seek,
00113 .trunc = slinear_trunc,
00114 .tell = slinear_tell,
00115 .read = slinear_read,
00116 .buf_size = 320 + AST_FRIENDLY_OFFSET,
00117 };
00118
00119 static int slinear12_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR12);}
00120 static struct ast_frame *slinear12_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 480, AST_FORMAT_SLINEAR12);}
00121 static struct ast_format_def slin12_f = {
00122 .name = "sln12",
00123 .exts = "sln12",
00124 .write = slinear12_write,
00125 .seek = slinear_seek,
00126 .trunc = slinear_trunc,
00127 .tell = slinear_tell,
00128 .read = slinear12_read,
00129 .buf_size = 480 + AST_FRIENDLY_OFFSET,
00130 };
00131
00132 static int slinear16_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR16);}
00133 static struct ast_frame *slinear16_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 640, AST_FORMAT_SLINEAR16);}
00134 static struct ast_format_def slin16_f = {
00135 .name = "sln16",
00136 .exts = "sln16",
00137 .write = slinear16_write,
00138 .seek = slinear_seek,
00139 .trunc = slinear_trunc,
00140 .tell = slinear_tell,
00141 .read = slinear16_read,
00142 .buf_size = 640 + AST_FRIENDLY_OFFSET,
00143 };
00144
00145 static int slinear24_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR24);}
00146 static struct ast_frame *slinear24_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 960, AST_FORMAT_SLINEAR24);}
00147 static struct ast_format_def slin24_f = {
00148 .name = "sln24",
00149 .exts = "sln24",
00150 .write = slinear24_write,
00151 .seek = slinear_seek,
00152 .trunc = slinear_trunc,
00153 .tell = slinear_tell,
00154 .read = slinear24_read,
00155 .buf_size = 960 + AST_FRIENDLY_OFFSET,
00156 };
00157
00158 static int slinear32_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR32);}
00159 static struct ast_frame *slinear32_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1280, AST_FORMAT_SLINEAR32);}
00160 static struct ast_format_def slin32_f = {
00161 .name = "sln32",
00162 .exts = "sln32",
00163 .write = slinear32_write,
00164 .seek = slinear_seek,
00165 .trunc = slinear_trunc,
00166 .tell = slinear_tell,
00167 .read = slinear32_read,
00168 .buf_size = 1280 + AST_FRIENDLY_OFFSET,
00169 };
00170
00171 static int slinear44_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR44);}
00172 static struct ast_frame *slinear44_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1764, AST_FORMAT_SLINEAR44);}
00173 static struct ast_format_def slin44_f = {
00174 .name = "sln44",
00175 .exts = "sln44",
00176 .write = slinear44_write,
00177 .seek = slinear_seek,
00178 .trunc = slinear_trunc,
00179 .tell = slinear_tell,
00180 .read = slinear44_read,
00181 .buf_size = 1764 + AST_FRIENDLY_OFFSET,
00182 };
00183
00184 static int slinear48_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR48);}
00185 static struct ast_frame *slinear48_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1920, AST_FORMAT_SLINEAR48);}
00186 static struct ast_format_def slin48_f = {
00187 .name = "sln48",
00188 .exts = "sln48",
00189 .write = slinear48_write,
00190 .seek = slinear_seek,
00191 .trunc = slinear_trunc,
00192 .tell = slinear_tell,
00193 .read = slinear48_read,
00194 .buf_size = 1920 + AST_FRIENDLY_OFFSET,
00195 };
00196
00197 static int slinear96_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR96);}
00198 static struct ast_frame *slinear96_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 3840, AST_FORMAT_SLINEAR96);}
00199 static struct ast_format_def slin96_f = {
00200 .name = "sln96",
00201 .exts = "sln96",
00202 .write = slinear96_write,
00203 .seek = slinear_seek,
00204 .trunc = slinear_trunc,
00205 .tell = slinear_tell,
00206 .read = slinear96_read,
00207 .buf_size = 3840 + AST_FRIENDLY_OFFSET,
00208 };
00209
00210 static int slinear192_write(struct ast_filestream *fs, struct ast_frame *f){return generic_write(fs, f, AST_FORMAT_SLINEAR192);}
00211 static struct ast_frame *slinear192_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 7680, AST_FORMAT_SLINEAR192);}
00212 static struct ast_format_def slin192_f = {
00213 .name = "sln192",
00214 .exts = "sln192",
00215 .write = slinear192_write,
00216 .seek = slinear_seek,
00217 .trunc = slinear_trunc,
00218 .tell = slinear_tell,
00219 .read = slinear192_read,
00220 .buf_size = 7680 + AST_FRIENDLY_OFFSET,
00221 };
00222
00223 static struct ast_format_def *slin_list[] = {
00224 &slin_f,
00225 &slin12_f,
00226 &slin16_f,
00227 &slin24_f,
00228 &slin32_f,
00229 &slin44_f,
00230 &slin48_f,
00231 &slin96_f,
00232 &slin192_f,
00233 };
00234
00235 static int load_module(void)
00236 {
00237 int i;
00238 ast_format_set(&slin_f.format, AST_FORMAT_SLINEAR, 0);
00239 ast_format_set(&slin12_f.format, AST_FORMAT_SLINEAR12, 0);
00240 ast_format_set(&slin16_f.format, AST_FORMAT_SLINEAR16, 0);
00241 ast_format_set(&slin24_f.format, AST_FORMAT_SLINEAR24, 0);
00242 ast_format_set(&slin32_f.format, AST_FORMAT_SLINEAR32, 0);
00243 ast_format_set(&slin44_f.format, AST_FORMAT_SLINEAR44, 0);
00244 ast_format_set(&slin48_f.format, AST_FORMAT_SLINEAR48, 0);
00245 ast_format_set(&slin96_f.format, AST_FORMAT_SLINEAR96, 0);
00246 ast_format_set(&slin192_f.format, AST_FORMAT_SLINEAR192, 0);
00247
00248 for (i = 0; i < ARRAY_LEN(slin_list); i++) {
00249 if (ast_format_def_register(slin_list[i])) {
00250 return AST_MODULE_LOAD_FAILURE;
00251 }
00252 }
00253
00254 return AST_MODULE_LOAD_SUCCESS;
00255 }
00256
00257 static int unload_module(void)
00258 {
00259 int res = 0;
00260 int i = 0;
00261
00262 for (i = 0; i < ARRAY_LEN(slin_list); i++) {
00263 if (ast_format_def_unregister(slin_list[i]->name)) {
00264 res |= AST_MODULE_LOAD_FAILURE;
00265 }
00266 }
00267 return res;
00268 }
00269
00270 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN) 8khz-192khz",
00271 .load = load_module,
00272 .unload = unload_module,
00273 .load_pri = AST_MODPRI_APP_DEPEND
00274 );