#include <asterisk.h>
#include "mpg123.h"
#include "mpglib.h"
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/sched.h>
#include <asterisk/module.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <machine/endian.h>
Include dependency graph for format_mp3.c:
Go to the source code of this file.
Data Structures | |
struct | mp3_private |
Defines | |
#define | AST_MODULE "format_mp3" |
#define | BLOCKSIZE 160 |
#define | GAIN -4 |
#define | htoll(b) (b) |
#define | htols(b) (b) |
#define | ltohl(b) (b) |
#define | ltohs(b) (b) |
#define | MP3_BUFLEN 320 |
#define | MP3_DCACHE 8192 |
#define | MP3_SCACHE 16384 |
#define | OUTSCALE 4096 |
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"MP3 format [Any rate but 8000hz mono is optimal]") | |
static int | load_module (void) |
static void | mp3_close (struct ast_filestream *s) |
static int | mp3_dqueue (struct ast_filestream *s) |
static char * | mp3_getcomment (struct ast_filestream *s) |
static int | mp3_open (struct ast_filestream *s) |
static int | mp3_queue (struct ast_filestream *s) |
static struct ast_frame * | mp3_read (struct ast_filestream *s, int *whennext) |
static int | mp3_rewrite (struct ast_filestream *s, const char *comment) |
static int | mp3_seek (struct ast_filestream *s, off_t sample_offset, int whence) |
static int | mp3_squeue (struct ast_filestream *s) |
static off_t | mp3_tell (struct ast_filestream *s) |
static int | mp3_trunc (struct ast_filestream *s) |
static int | mp3_write (struct ast_filestream *fs, struct ast_frame *f) |
static int | unload_module (void) |
Variables | |
static struct ast_format | mp3_f |
static char * | name = "mp3" |
#define AST_MODULE "format_mp3" |
Definition at line 42 of file format_mp3.c.
#define BLOCKSIZE 160 |
Definition at line 71 of file format_mp3.c.
#define GAIN -4 |
Definition at line 74 of file format_mp3.c.
#define htoll | ( | b | ) | (b) |
#define htols | ( | b | ) | (b) |
#define ltohl | ( | b | ) | (b) |
#define ltohs | ( | b | ) | (b) |
#define MP3_BUFLEN 320 |
#define MP3_DCACHE 8192 |
#define MP3_SCACHE 16384 |
#define OUTSCALE 4096 |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"MP3 format " | [Any rate but 8000hz mono is optimal] | |||
) |
static int load_module | ( | void | ) | [static] |
Definition at line 326 of file format_mp3.c.
References ast_format_register, and mp3_f.
00327 { 00328 InitMP3Constants(); 00329 return ast_format_register(&mp3_f); 00330 }
static void mp3_close | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 116 of file format_mp3.c.
References mp3_private::mp, and s.
00117 { 00118 struct mp3_private *p = s->_private; 00119 00120 ExitMP3(&p->mp); 00121 return; 00122 }
static int mp3_dqueue | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 143 of file format_mp3.c.
References mp3_private::dbuf, mp3_private::dbuflen, mp3_private::dbufoffset, mp3_private::mp, MP3_DCACHE, s, and mp3_private::sbuflen.
Referenced by mp3_queue().
00144 { 00145 struct mp3_private *p = s->_private; 00146 int res=0; 00147 00148 if((res = decodeMP3(&p->mp,NULL,0,p->dbuf,MP3_DCACHE,&p->dbuflen)) == MP3_OK) { 00149 p->sbuflen -= p->dbuflen; 00150 p->dbufoffset = 0; 00151 } 00152 return res; 00153 }
static char* mp3_getcomment | ( | struct ast_filestream * | s | ) | [static] |
static int mp3_open | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 99 of file format_mp3.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, mp3_private::dbuflen, mp3_private::mp, name, mp3_private::offset, OUTSCALE, and s.
00100 { 00101 struct mp3_private *p = s->_private; 00102 00103 InitMP3(&p->mp, OUTSCALE); 00104 p->dbuflen = 0; 00105 s->fr.data = s->buf; 00106 s->fr.frametype = AST_FRAME_VOICE; 00107 s->fr.subclass = AST_FORMAT_SLINEAR; 00108 /* datalen will vary for each frame */ 00109 s->fr.src = name; 00110 s->fr.mallocd = 0; 00111 p->offset = 0; 00112 return 0; 00113 }
static int mp3_queue | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 155 of file format_mp3.c.
References mp3_private::dbuflen, mp3_private::dbufoffset, mp3_private::mp, mp3_dqueue(), mp3_squeue(), mp3_private::offset, OUTSCALE, s, mp3_private::sbuflen, and mp3_private::seek.
Referenced by mp3_read().
00156 { 00157 struct mp3_private *p = s->_private; 00158 int res = 0, bytes = 0; 00159 00160 if(p->seek) { 00161 ExitMP3(&p->mp); 00162 InitMP3(&p->mp, OUTSCALE); 00163 fseek(s->f, 0, SEEK_SET); 00164 p->sbuflen = p->dbuflen = p->offset = 0; 00165 while(p->offset < p->seek) { 00166 if(mp3_squeue(s)) 00167 return -1; 00168 while(p->offset < p->seek && ((res = mp3_dqueue(s))) == MP3_OK) { 00169 for(bytes = 0 ; bytes < p->dbuflen ; bytes++) { 00170 p->dbufoffset++; 00171 p->offset++; 00172 if(p->offset >= p->seek) 00173 break; 00174 } 00175 } 00176 if(res == MP3_ERR) 00177 return -1; 00178 } 00179 00180 p->seek = 0; 00181 return 0; 00182 } 00183 if(p->dbuflen == 0) { 00184 if(p->sbuflen) { 00185 res = mp3_dqueue(s); 00186 if(res == MP3_ERR) 00187 return -1; 00188 } 00189 if(! p->sbuflen || res != MP3_OK) { 00190 if(mp3_squeue(s)) 00191 return -1; 00192 } 00193 00194 } 00195 00196 return 0; 00197 }
static struct ast_frame* mp3_read | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 199 of file format_mp3.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, mp3_private::buflen, mp3_private::dbuf, mp3_private::dbuflen, mp3_private::dbufoffset, MP3_BUFLEN, mp3_queue(), mp3_private::offset, s, and mp3_private::sbufoffset.
00200 { 00201 00202 struct mp3_private *p = s->_private; 00203 int delay =0; 00204 int save=0; 00205 00206 /* Send a frame from the file to the appropriate channel */ 00207 00208 if(mp3_queue(s)) 00209 return NULL; 00210 00211 if(p->dbuflen) { 00212 for(p->buflen=0; p->buflen < MP3_BUFLEN && p->buflen < p->dbuflen; p->buflen++) { 00213 s->buf[p->buflen] = p->dbuf[p->buflen+p->dbufoffset]; 00214 p->sbufoffset++; 00215 } 00216 p->dbufoffset += p->buflen; 00217 p->dbuflen -= p->buflen; 00218 00219 if(p->buflen < MP3_BUFLEN) { 00220 if(mp3_queue(s)) 00221 return NULL; 00222 00223 for(save = p->buflen; p->buflen < MP3_BUFLEN; p->buflen++) { 00224 s->buf[p->buflen] = p->dbuf[(p->buflen-save)+p->dbufoffset]; 00225 p->sbufoffset++; 00226 } 00227 p->dbufoffset += (MP3_BUFLEN - save); 00228 p->dbuflen -= (MP3_BUFLEN - save); 00229 00230 } 00231 00232 } 00233 00234 p->offset += p->buflen; 00235 delay = p->buflen/2; 00236 s->fr.frametype = AST_FRAME_VOICE; 00237 s->fr.subclass = AST_FORMAT_SLINEAR; 00238 s->fr.offset = AST_FRIENDLY_OFFSET; 00239 s->fr.datalen = p->buflen; 00240 s->fr.data = s->buf; 00241 s->fr.mallocd = 0; 00242 s->fr.samples = delay; 00243 *whennext = delay; 00244 return &s->fr; 00245 }
static int mp3_rewrite | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
static int mp3_seek | ( | struct ast_filestream * | s, | |
off_t | sample_offset, | |||
int | whence | |||
) | [static] |
Definition at line 256 of file format_mp3.c.
References mp3_private::offset, offset, s, mp3_private::seek, and SEEK_FORCECUR.
00257 { 00258 struct mp3_private *p = s->_private; 00259 off_t min,max,cur; 00260 long offset=0,samples; 00261 samples = sample_offset * 2; 00262 00263 min = 0; 00264 fseek(s->f, 0, SEEK_END); 00265 max = ftell(s->f) * 100; 00266 cur = p->offset; 00267 00268 if (whence == SEEK_SET) 00269 offset = samples + min; 00270 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) 00271 offset = samples + cur; 00272 else if (whence == SEEK_END) 00273 offset = max - samples; 00274 if (whence != SEEK_FORCECUR) { 00275 offset = (offset > max)?max:offset; 00276 } 00277 00278 p->seek = offset; 00279 return p->seek; 00280 00281 }
static int mp3_squeue | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 124 of file format_mp3.c.
References ast_log(), mp3_private::dbuf, mp3_private::dbuflen, mp3_private::dbufoffset, errno, mp3_private::lastseek, LOG_WARNING, mp3_private::mp, MP3_DCACHE, MP3_SCACHE, s, mp3_private::sbuf, and mp3_private::sbuflen.
Referenced by mp3_queue().
00125 { 00126 struct mp3_private *p = s->_private; 00127 int res=0; 00128 00129 p->lastseek = ftell(s->f); 00130 p->sbuflen = fread(p->sbuf, 1, MP3_SCACHE, s->f); 00131 if(p->sbuflen < 0) { 00132 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", p->sbuflen, strerror(errno)); 00133 return -1; 00134 } 00135 res = decodeMP3(&p->mp,p->sbuf,p->sbuflen,p->dbuf,MP3_DCACHE,&p->dbuflen); 00136 if(res != MP3_OK) 00137 return -1; 00138 p->sbuflen -= p->dbuflen; 00139 p->dbufoffset = 0; 00140 return 0; 00141 }
static off_t mp3_tell | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 296 of file format_mp3.c.
References mp3_private::offset, and s.
00297 { 00298 struct mp3_private *p = s->_private; 00299 00300 return p->offset/2; 00301 }
static int mp3_trunc | ( | struct ast_filestream * | s | ) | [static] |
static int mp3_write | ( | struct ast_filestream * | fs, | |
struct ast_frame * | f | |||
) | [static] |
static int unload_module | ( | void | ) | [static] |
Definition at line 332 of file format_mp3.c.
References ast_format_unregister(), and name.
00333 { 00334 return ast_format_unregister(name); 00335 }
struct ast_format mp3_f [static] |
char* name = "mp3" [static] |
Definition at line 69 of file format_mp3.c.