Sat Feb 11 06:33:15 2012

Asterisk developer's documentation


format_sln.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Anthony Minessale
00005  * Anthony Minessale (anthmct@yahoo.com)
00006  *
00007  * See http://www.asterisk.org for more information about
00008  * the Asterisk project. Please do not directly contact
00009  * any of the maintainers of this project for assistance;
00010  * the project provides a web site, mailing lists and IRC
00011  * channels for your use.
00012  *
00013  * This program is free software, distributed under the terms of
00014  * the GNU General Public License Version 2. See the LICENSE file
00015  * at the top of the source tree.
00016  */
00017 
00018 /*! \file
00019  *
00020  * \brief RAW SLINEAR Formats
00021  * \ingroup formats
00022  */
00023 
00024 /*** MODULEINFO
00025    <support_level>core</support_level>
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    /* Send a frame from the file to the appropriate channel */
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    /* always protect against seeking past begining. */
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 );

Generated on Sat Feb 11 06:33:15 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6