Mon Mar 20 08:25:42 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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 <unistd.h>
00026 #include <netinet/in.h>
00027 #include <arpa/inet.h>
00028 #include <stdlib.h>
00029 #include <sys/time.h>
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #include <string.h>
00033 
00034 #include "asterisk.h"
00035 
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 10487 $")
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 samples */
00047 
00048 struct ast_filestream {
00049    void *reserved[AST_RESERVED_POINTERS];
00050    /* This is what a filestream means to us */
00051    FILE *f; /* Descriptor */
00052    struct ast_channel *owner;
00053    struct ast_frame fr;          /* Frame information */
00054    char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
00055    char empty;                   /* Empty character */
00056    unsigned char buf[BUF_SIZE];           /* Output Buffer */
00057    struct timeval last;
00058 };
00059 
00060 
00061 AST_MUTEX_DEFINE_STATIC(slinear_lock);
00062 static int glistcnt = 0;
00063 
00064 static char *name = "sln";
00065 static char *desc = "Raw Signed Linear Audio support (SLN)";
00066 static char *exts = "sln|raw";
00067 
00068 static struct ast_filestream *slinear_open(FILE *f)
00069 {
00070    /* We don't have any header to read or anything really, but
00071       if we did, it would go here.  We also might want to check
00072       and be sure it's a valid file.  */
00073    struct ast_filestream *tmp;
00074    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00075       memset(tmp, 0, sizeof(struct ast_filestream));
00076       if (ast_mutex_lock(&slinear_lock)) {
00077          ast_log(LOG_WARNING, "Unable to lock slinear list\n");
00078          free(tmp);
00079          return NULL;
00080       }
00081       tmp->f = f;
00082       tmp->fr.data = tmp->buf;
00083       tmp->fr.frametype = AST_FRAME_VOICE;
00084       tmp->fr.subclass = AST_FORMAT_SLINEAR;
00085       /* datalen will vary for each frame */
00086       tmp->fr.src = name;
00087       tmp->fr.mallocd = 0;
00088       glistcnt++;
00089       ast_mutex_unlock(&slinear_lock);
00090       ast_update_use_count();
00091    }
00092    return tmp;
00093 }
00094 
00095 static struct ast_filestream *slinear_rewrite(FILE *f, const char *comment)
00096 {
00097    /* We don't have any header to read or anything really, but
00098       if we did, it would go here.  We also might want to check
00099       and be sure it's a valid file.  */
00100    struct ast_filestream *tmp;
00101    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00102       memset(tmp, 0, sizeof(struct ast_filestream));
00103       if (ast_mutex_lock(&slinear_lock)) {
00104          ast_log(LOG_WARNING, "Unable to lock slinear list\n");
00105          free(tmp);
00106          return NULL;
00107       }
00108       tmp->f = f;
00109       glistcnt++;
00110       ast_mutex_unlock(&slinear_lock);
00111       ast_update_use_count();
00112    } else
00113       ast_log(LOG_WARNING, "Out of memory\n");
00114    return tmp;
00115 }
00116 
00117 static void slinear_close(struct ast_filestream *s)
00118 {
00119    if (ast_mutex_lock(&slinear_lock)) {
00120       ast_log(LOG_WARNING, "Unable to lock slinear list\n");
00121       return;
00122    }
00123    glistcnt--;
00124    ast_mutex_unlock(&slinear_lock);
00125    ast_update_use_count();
00126    fclose(s->f);
00127    free(s);
00128    s = NULL;
00129 }
00130 
00131 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
00132 {
00133    int res;
00134    int delay;
00135    /* Send a frame from the file to the appropriate channel */
00136 
00137    s->fr.frametype = AST_FRAME_VOICE;
00138    s->fr.subclass = AST_FORMAT_SLINEAR;
00139    s->fr.offset = AST_FRIENDLY_OFFSET;
00140    s->fr.mallocd = 0;
00141    s->fr.data = s->buf;
00142    if ((res = fread(s->buf, 1, BUF_SIZE, s->f)) < 1) {
00143       if (res)
00144          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00145       return NULL;
00146    }
00147    s->fr.samples = res/2;
00148    s->fr.datalen = res;
00149    delay = s->fr.samples;
00150    *whennext = delay;
00151    return &s->fr;
00152 }
00153 
00154 static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
00155 {
00156    int res;
00157    if (f->frametype != AST_FRAME_VOICE) {
00158       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00159       return -1;
00160    }
00161    if (f->subclass != AST_FORMAT_SLINEAR) {
00162       ast_log(LOG_WARNING, "Asked to write non-slinear frame (%d)!\n", f->subclass);
00163       return -1;
00164    }
00165    if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
00166          ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00167          return -1;
00168    }
00169    return 0;
00170 }
00171 
00172 static int slinear_seek(struct ast_filestream *fs, long sample_offset, int whence)
00173 {
00174    off_t offset=0,min,cur,max;
00175 
00176    min = 0;
00177    sample_offset <<= 1;
00178    cur = ftell(fs->f);
00179    fseek(fs->f, 0, SEEK_END);
00180    max = ftell(fs->f);
00181    if (whence == SEEK_SET)
00182       offset = sample_offset;
00183    else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
00184       offset = sample_offset + cur;
00185    else if (whence == SEEK_END)
00186       offset = max - sample_offset;
00187    if (whence != SEEK_FORCECUR) {
00188       offset = (offset > max)?max:offset;
00189    }
00190    /* always protect against seeking past begining. */
00191    offset = (offset < min)?min:offset;
00192    return fseek(fs->f, offset, SEEK_SET);
00193 }
00194 
00195 static int slinear_trunc(struct ast_filestream *fs)
00196 {
00197    return ftruncate(fileno(fs->f), ftell(fs->f));
00198 }
00199 
00200 static long slinear_tell(struct ast_filestream *fs)
00201 {
00202    off_t offset;
00203    offset = ftell(fs->f);
00204    return offset / 2;
00205 }
00206 
00207 static char *slinear_getcomment(struct ast_filestream *s)
00208 {
00209    return NULL;
00210 }
00211 
00212 int load_module()
00213 {
00214    return ast_format_register(name, exts, AST_FORMAT_SLINEAR,
00215                         slinear_open,
00216                         slinear_rewrite,
00217                         slinear_write,
00218                         slinear_seek,
00219                         slinear_trunc,
00220                         slinear_tell,
00221                         slinear_read,
00222                         slinear_close,
00223                         slinear_getcomment);
00224                         
00225                         
00226 }
00227 
00228 int unload_module()
00229 {
00230    return ast_format_unregister(name);
00231 }  
00232 
00233 int usecount()
00234 {
00235    return glistcnt;
00236 }
00237 
00238 char *description()
00239 {
00240    return desc;
00241 }
00242 
00243 
00244 char *key()
00245 {
00246    return ASTERISK_GPL_KEY;
00247 }

Generated on Mon Mar 20 08:25:42 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1