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 #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
00047 #define SLIN_SAMPLES 160
00048
00049 static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
00050 {
00051 int res;
00052
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
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 );