Sat Aug 6 00:39:28 2011

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 Format
00021  * \arg File name extensions: sln, raw
00022  * \ingroup formats
00023  */
00024  
00025 #include "asterisk.h"
00026 
00027 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 233782 $")
00028 
00029 #include <unistd.h>
00030 #include <netinet/in.h>
00031 #include <arpa/inet.h>
00032 #include <stdlib.h>
00033 #include <sys/time.h>
00034 #include <stdio.h>
00035 #include <errno.h>
00036 #include <string.h>
00037 
00038 #include "asterisk/lock.h"
00039 #include "asterisk/channel.h"
00040 #include "asterisk/file.h"
00041 #include "asterisk/logger.h"
00042 #include "asterisk/sched.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/endian.h"
00045 
00046 #define BUF_SIZE  320      /* 320 bytes, 160 samples */
00047 #define  SLIN_SAMPLES   160
00048 
00049 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
00050 {
00051    int res;
00052    /* Send a frame from the file to the appropriate channel */
00053 
00054    s->fr.frametype = AST_FRAME_VOICE;
00055    s->fr.subclass = AST_FORMAT_SLINEAR;
00056    s->fr.mallocd = 0;
00057    AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
00058    if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) {
00059       if (res)
00060          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00061       return NULL;
00062    }
00063    *whennext = s->fr.samples = res/2;
00064    s->fr.datalen = res;
00065    return &s->fr;
00066 }
00067 
00068 static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
00069 {
00070    int res;
00071    if (f->frametype != AST_FRAME_VOICE) {
00072       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00073       return -1;
00074    }
00075    if (f->subclass != AST_FORMAT_SLINEAR) {
00076       ast_log(LOG_WARNING, "Asked to write non-slinear frame (%d)!\n", f->subclass);
00077       return -1;
00078    }
00079    if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
00080          ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00081          return -1;
00082    }
00083    return 0;
00084 }
00085 
00086 static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00087 {
00088    off_t offset=0,min,cur,max;
00089 
00090    min = 0;
00091    sample_offset <<= 1;
00092    cur = ftello(fs->f);
00093    fseeko(fs->f, 0, SEEK_END);
00094    max = ftello(fs->f);
00095    if (whence == SEEK_SET)
00096       offset = sample_offset;
00097    else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
00098       offset = sample_offset + cur;
00099    else if (whence == SEEK_END)
00100       offset = max - sample_offset;
00101    if (whence != SEEK_FORCECUR) {
00102       offset = (offset > max)?max:offset;
00103    }
00104    /* always protect against seeking past begining. */
00105    offset = (offset < min)?min:offset;
00106    return fseeko(fs->f, offset, SEEK_SET);
00107 }
00108 
00109 static int slinear_trunc(struct ast_filestream *fs)
00110 {
00111    return ftruncate(fileno(fs->f), ftello(fs->f));
00112 }
00113 
00114 static off_t slinear_tell(struct ast_filestream *fs)
00115 {
00116    return ftello(fs->f) / 2;
00117 }
00118 
00119 static const struct ast_format slin_f = {
00120    .name = "sln",
00121    .exts = "sln|raw",
00122    .format = AST_FORMAT_SLINEAR,
00123    .write = slinear_write,
00124    .seek = slinear_seek,
00125    .trunc = slinear_trunc,
00126    .tell = slinear_tell,
00127    .read = slinear_read,
00128    .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
00129 };
00130 
00131 static int load_module(void)
00132 {
00133    return ast_format_register(&slin_f);
00134 }
00135 
00136 static int unload_module(void)
00137 {
00138    return ast_format_unregister(slin_f.name);
00139 }  
00140 
00141 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_FIRST, "Raw Signed Linear Audio support (SLN)",
00142    .load = load_module,
00143    .unload = unload_module,
00144 );

Generated on Sat Aug 6 00:39:28 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7