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: 419592 $")
00031 
00032 #include "asterisk/mod_format.h"
00033 #include "asterisk/module.h"
00034 #include "asterisk/endian.h"
00035 #include "asterisk/format_cache.h"
00036 
00037 static struct ast_frame *generic_read(struct ast_filestream *s, int *whennext, unsigned int buf_size)
00038 {
00039    int res;
00040    /* Send a frame from the file to the appropriate channel */
00041 
00042    AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, buf_size);
00043    if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
00044       if (res)
00045          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00046       return NULL;
00047    }
00048    *whennext = s->fr.samples = res/2;
00049    s->fr.datalen = res;
00050    return &s->fr;
00051 }
00052 
00053 static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
00054 {
00055    int res;
00056    if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
00057          ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00058          return -1;
00059    }
00060    return 0;
00061 }
00062 
00063 static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00064 {
00065    off_t offset=0, min = 0, cur, max;
00066 
00067    sample_offset <<= 1;
00068 
00069    if ((cur = ftello(fs->f)) < 0) {
00070       ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
00071       return -1;
00072    }
00073 
00074    if (fseeko(fs->f, 0, SEEK_END) < 0) {
00075       ast_log(AST_LOG_WARNING, "Unable to seek to end of sln filestream %p: %s\n", fs, strerror(errno));
00076       return -1;
00077    }
00078 
00079    if ((max = ftello(fs->f)) < 0) {
00080       ast_log(AST_LOG_WARNING, "Unable to determine max position in sln filestream %p: %s\n", fs, strerror(errno));
00081       return -1;
00082    }
00083 
00084    if (whence == SEEK_SET)
00085       offset = sample_offset;
00086    else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
00087       offset = sample_offset + cur;
00088    else if (whence == SEEK_END)
00089       offset = max - sample_offset;
00090    if (whence != SEEK_FORCECUR) {
00091       offset = (offset > max)?max:offset;
00092    }
00093    /* always protect against seeking past begining. */
00094    offset = (offset < min)?min:offset;
00095    return fseeko(fs->f, offset, SEEK_SET);
00096 }
00097 
00098 static int slinear_trunc(struct ast_filestream *fs)
00099 {
00100    int fd;
00101    off_t cur;
00102 
00103    if ((fd = fileno(fs->f)) < 0) {
00104       ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for sln filestream %p: %s\n", fs, strerror(errno));
00105       return -1;
00106    }
00107    if ((cur = ftello(fs->f)) < 0) {
00108       ast_log(AST_LOG_WARNING, "Unable to determine current position in sln filestream %p: %s\n", fs, strerror(errno));
00109       return -1;
00110    }
00111    /* Truncate file to current length */
00112    return ftruncate(fd, cur);
00113 }
00114 
00115 static off_t slinear_tell(struct ast_filestream *fs)
00116 {
00117    return ftello(fs->f) / 2;
00118 }
00119 
00120 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 320);}
00121 static struct ast_format_def slin_f = {
00122    .name = "sln",
00123    .exts = "sln|raw",
00124    .write = slinear_write,
00125    .seek = slinear_seek,
00126    .trunc = slinear_trunc,
00127    .tell = slinear_tell,
00128    .read = slinear_read,
00129    .buf_size = 320 + AST_FRIENDLY_OFFSET,
00130 };
00131 
00132 static struct ast_frame *slinear12_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 480);}
00133 static struct ast_format_def slin12_f = {
00134    .name = "sln12",
00135    .exts = "sln12",
00136    .write = slinear_write,
00137    .seek = slinear_seek,
00138    .trunc = slinear_trunc,
00139    .tell = slinear_tell,
00140    .read = slinear12_read,
00141    .buf_size = 480 + AST_FRIENDLY_OFFSET,
00142 };
00143 
00144 static struct ast_frame *slinear16_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 640);}
00145 static struct ast_format_def slin16_f = {
00146    .name = "sln16",
00147    .exts = "sln16",
00148    .write = slinear_write,
00149    .seek = slinear_seek,
00150    .trunc = slinear_trunc,
00151    .tell = slinear_tell,
00152    .read = slinear16_read,
00153    .buf_size = 640 + AST_FRIENDLY_OFFSET,
00154 };
00155 
00156 static struct ast_frame *slinear24_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 960);}
00157 static struct ast_format_def slin24_f = {
00158    .name = "sln24",
00159    .exts = "sln24",
00160    .write = slinear_write,
00161    .seek = slinear_seek,
00162    .trunc = slinear_trunc,
00163    .tell = slinear_tell,
00164    .read = slinear24_read,
00165    .buf_size = 960 + AST_FRIENDLY_OFFSET,
00166 };
00167 
00168 static struct ast_frame *slinear32_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1280);}
00169 static struct ast_format_def slin32_f = {
00170    .name = "sln32",
00171    .exts = "sln32",
00172    .write = slinear_write,
00173    .seek = slinear_seek,
00174    .trunc = slinear_trunc,
00175    .tell = slinear_tell,
00176    .read = slinear32_read,
00177    .buf_size = 1280 + AST_FRIENDLY_OFFSET,
00178 };
00179 
00180 static struct ast_frame *slinear44_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1764);}
00181 static struct ast_format_def slin44_f = {
00182    .name = "sln44",
00183    .exts = "sln44",
00184    .write = slinear_write,
00185    .seek = slinear_seek,
00186    .trunc = slinear_trunc,
00187    .tell = slinear_tell,
00188    .read = slinear44_read,
00189    .buf_size = 1764 + AST_FRIENDLY_OFFSET,
00190 };
00191 
00192 static struct ast_frame *slinear48_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 1920);}
00193 static struct ast_format_def slin48_f = {
00194    .name = "sln48",
00195    .exts = "sln48",
00196    .write = slinear_write,
00197    .seek = slinear_seek,
00198    .trunc = slinear_trunc,
00199    .tell = slinear_tell,
00200    .read = slinear48_read,
00201    .buf_size = 1920 + AST_FRIENDLY_OFFSET,
00202 };
00203 
00204 static struct ast_frame *slinear96_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 3840);}
00205 static struct ast_format_def slin96_f = {
00206    .name = "sln96",
00207    .exts = "sln96",
00208    .write = slinear_write,
00209    .seek = slinear_seek,
00210    .trunc = slinear_trunc,
00211    .tell = slinear_tell,
00212    .read = slinear96_read,
00213    .buf_size = 3840 + AST_FRIENDLY_OFFSET,
00214 };
00215 
00216 static struct ast_frame *slinear192_read(struct ast_filestream *s, int *whennext){return generic_read(s, whennext, 7680);}
00217 static struct ast_format_def slin192_f = {
00218    .name = "sln192",
00219    .exts = "sln192",
00220    .write = slinear_write,
00221    .seek = slinear_seek,
00222    .trunc = slinear_trunc,
00223    .tell = slinear_tell,
00224    .read = slinear192_read,
00225    .buf_size = 7680 + AST_FRIENDLY_OFFSET,
00226 };
00227 
00228 static struct ast_format_def *slin_list[] = {
00229    &slin_f,
00230    &slin12_f,
00231    &slin16_f,
00232    &slin24_f,
00233    &slin32_f,
00234    &slin44_f,
00235    &slin48_f,
00236    &slin96_f,
00237    &slin192_f,
00238 };
00239 
00240 static int load_module(void)
00241 {
00242    int i;
00243 
00244    slin_f.format = ast_format_slin;
00245    slin12_f.format = ast_format_slin12;
00246    slin16_f.format = ast_format_slin16;
00247    slin24_f.format = ast_format_slin24;
00248    slin32_f.format = ast_format_slin32;
00249    slin44_f.format = ast_format_slin44;
00250    slin48_f.format = ast_format_slin48;
00251    slin96_f.format = ast_format_slin96;
00252    slin192_f.format = ast_format_slin192;
00253 
00254    for (i = 0; i < ARRAY_LEN(slin_list); i++) {
00255       if (ast_format_def_register(slin_list[i])) {
00256          return AST_MODULE_LOAD_FAILURE;
00257       }
00258    }
00259 
00260    return AST_MODULE_LOAD_SUCCESS;
00261 }
00262 
00263 static int unload_module(void)
00264 {
00265    int res = 0;
00266    int i = 0;
00267 
00268    for (i = 0; i < ARRAY_LEN(slin_list); i++) {
00269       if (ast_format_def_unregister(slin_list[i]->name)) {
00270          res |= AST_MODULE_LOAD_FAILURE;
00271       }
00272    }
00273    return res;
00274 }
00275 
00276 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN) 8khz-192khz",
00277    .support_level = AST_MODULE_SUPPORT_CORE,
00278    .load = load_module,
00279    .unload = unload_module,
00280    .load_pri = AST_MODPRI_APP_DEPEND
00281 );

Generated on Thu Apr 16 06:27:35 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6