#include "asterisk.h"
#include "asterisk/mod_format.h"
#include "asterisk/module.h"
#include "asterisk/endian.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
Go to the source code of this file.
Defines | |
#define | AU_ENC_8BIT_ULAW 1 |
#define | AU_HDR_CHANNELS_OFF 5 |
#define | AU_HDR_DATA_SIZE_OFF 2 |
#define | AU_HDR_ENCODING_OFF 3 |
#define | AU_HDR_HDR_SIZE_OFF 1 |
#define | AU_HDR_MAGIC_OFF 0 |
#define | AU_HDR_SAMPLE_RATE_OFF 4 |
#define | AU_HEADER(var) uint32_t var[6] |
#define | AU_HEADER_SIZE 24 |
#define | AU_MAGIC 0x2e736e64 |
#define | BUF_SIZE 160 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | au_open (struct ast_filestream *s) |
static int | au_rewrite (struct ast_filestream *s, const char *comment) |
static int | au_seek (struct ast_filestream *fs, off_t sample_offset, int whence) |
static off_t | au_tell (struct ast_filestream *fs) |
static int | au_trunc (struct ast_filestream *fs) |
static int | check_header (FILE *f) |
static int | load_module (void) |
static struct ast_frame * | pcm_read (struct ast_filestream *s, int *whennext) |
static int | pcm_seek (struct ast_filestream *fs, off_t sample_offset, int whence) |
static off_t | pcm_tell (struct ast_filestream *fs) |
static int | pcm_trunc (struct ast_filestream *fs) |
static int | pcm_write (struct ast_filestream *fs, struct ast_frame *f) |
static int | unload_module (void) |
static int | update_header (FILE *f) |
static int | write_header (FILE *f) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static struct ast_format | alaw_f |
static char | alaw_silence [BUF_SIZE] |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_format | au_f |
static struct ast_format | g722_f |
static struct ast_format | pcm_f |
static char | ulaw_silence [BUF_SIZE] |
Definition in file format_pcm.c.
#define AU_ENC_8BIT_ULAW 1 |
#define AU_HDR_CHANNELS_OFF 5 |
#define AU_HDR_DATA_SIZE_OFF 2 |
#define AU_HDR_ENCODING_OFF 3 |
#define AU_HDR_HDR_SIZE_OFF 1 |
#define AU_HDR_MAGIC_OFF 0 |
#define AU_HDR_SAMPLE_RATE_OFF 4 |
#define AU_HEADER | ( | var | ) | uint32_t var[6] |
#define AU_HEADER_SIZE 24 |
Definition at line 221 of file format_pcm.c.
Referenced by au_seek(), au_tell(), check_header(), update_header(), and write_header().
#define AU_MAGIC 0x2e736e64 |
#define BUF_SIZE 160 |
Definition at line 37 of file format_pcm.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 497 of file format_pcm.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 497 of file format_pcm.c.
static int au_open | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 356 of file format_pcm.c.
References check_header(), and s.
00357 { 00358 if (check_header(s->f) < 0) 00359 return -1; 00360 return 0; 00361 }
static int au_rewrite | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 363 of file format_pcm.c.
References s, and write_header().
00364 { 00365 if (write_header(s->f)) 00366 return -1; 00367 return 0; 00368 }
static int au_seek | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) | [static] |
Definition at line 371 of file format_pcm.c.
References AST_FORMAT_G722, AU_HEADER_SIZE, ast_filestream::f, ast_filestream::fmt, ast_format::format, and SEEK_FORCECUR.
00372 { 00373 off_t min, max, cur; 00374 long offset = 0, bytes; 00375 00376 if (fs->fmt->format == AST_FORMAT_G722) 00377 bytes = sample_offset / 2; 00378 else 00379 bytes = sample_offset; 00380 00381 min = AU_HEADER_SIZE; 00382 cur = ftello(fs->f); 00383 fseek(fs->f, 0, SEEK_END); 00384 max = ftello(fs->f); 00385 00386 if (whence == SEEK_SET) 00387 offset = bytes + min; 00388 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) 00389 offset = bytes + cur; 00390 else if (whence == SEEK_END) 00391 offset = max - bytes; 00392 00393 if (whence != SEEK_FORCECUR) { 00394 offset = (offset > max) ? max : offset; 00395 } 00396 00397 /* always protect the header space. */ 00398 offset = (offset < min) ? min : offset; 00399 00400 return fseeko(fs->f, offset, SEEK_SET); 00401 }
static off_t au_tell | ( | struct ast_filestream * | fs | ) | [static] |
Definition at line 410 of file format_pcm.c.
References AU_HEADER_SIZE, and ast_filestream::f.
00411 { 00412 off_t offset = ftello(fs->f); 00413 return offset - AU_HEADER_SIZE; 00414 }
static int au_trunc | ( | struct ast_filestream * | fs | ) | [static] |
Definition at line 403 of file format_pcm.c.
References ast_filestream::f, and update_header().
00404 { 00405 if (ftruncate(fileno(fs->f), ftell(fs->f))) 00406 return -1; 00407 return update_header(fs->f); 00408 }
static int check_header | ( | FILE * | f | ) | [static] |
Definition at line 256 of file format_pcm.c.
References ast_log(), AU_ENC_8BIT_ULAW, AU_HDR_CHANNELS_OFF, AU_HDR_ENCODING_OFF, AU_HDR_HDR_SIZE_OFF, AU_HDR_MAGIC_OFF, AU_HDR_SAMPLE_RATE_OFF, AU_HEADER, AU_HEADER_SIZE, AU_MAGIC, DEFAULT_SAMPLE_RATE, and LOG_WARNING.
Referenced by au_open(), and wav_open().
00257 { 00258 AU_HEADER(header); 00259 uint32_t magic; 00260 uint32_t hdr_size; 00261 uint32_t data_size; 00262 uint32_t encoding; 00263 uint32_t sample_rate; 00264 uint32_t channels; 00265 00266 if (fread(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) { 00267 ast_log(LOG_WARNING, "Read failed (header)\n"); 00268 return -1; 00269 } 00270 magic = ltohl(header[AU_HDR_MAGIC_OFF]); 00271 if (magic != (uint32_t) AU_MAGIC) { 00272 ast_log(LOG_WARNING, "Bad magic: 0x%x\n", magic); 00273 } 00274 hdr_size = ltohl(header[AU_HDR_HDR_SIZE_OFF]); 00275 if (hdr_size < AU_HEADER_SIZE) { 00276 hdr_size = AU_HEADER_SIZE; 00277 } 00278 /* data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */ 00279 encoding = ltohl(header[AU_HDR_ENCODING_OFF]); 00280 if (encoding != AU_ENC_8BIT_ULAW) { 00281 ast_log(LOG_WARNING, "Unexpected format: %d. Only 8bit ULAW allowed (%d)\n", encoding, AU_ENC_8BIT_ULAW); 00282 return -1; 00283 } 00284 sample_rate = ltohl(header[AU_HDR_SAMPLE_RATE_OFF]); 00285 if (sample_rate != DEFAULT_SAMPLE_RATE) { 00286 ast_log(LOG_WARNING, "Sample rate can only be 8000 not %d\n", sample_rate); 00287 return -1; 00288 } 00289 channels = ltohl(header[AU_HDR_CHANNELS_OFF]); 00290 if (channels != 1) { 00291 ast_log(LOG_WARNING, "Not in mono: channels=%d\n", channels); 00292 return -1; 00293 } 00294 /* Skip to data */ 00295 fseek(f, 0, SEEK_END); 00296 data_size = ftell(f) - hdr_size; 00297 if (fseek(f, hdr_size, SEEK_SET) == -1 ) { 00298 ast_log(LOG_WARNING, "Failed to skip to data: %d\n", hdr_size); 00299 return -1; 00300 } 00301 return data_size; 00302 }
static int load_module | ( | void | ) | [static] |
Definition at line 471 of file format_pcm.c.
References alaw_f, ARRAY_LEN, ast_format_register, AST_LIN2A, AST_LIN2MU, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, au_f, g722_f, and pcm_f.
00472 { 00473 int index; 00474 00475 /* XXX better init ? */ 00476 for (index = 0; index < ARRAY_LEN(ulaw_silence); index++) 00477 ulaw_silence[index] = AST_LIN2MU(0); 00478 for (index = 0; index < ARRAY_LEN(alaw_silence); index++) 00479 alaw_silence[index] = AST_LIN2A(0); 00480 00481 if ( ast_format_register(&pcm_f) 00482 || ast_format_register(&alaw_f) 00483 || ast_format_register(&au_f) 00484 || ast_format_register(&g722_f) ) 00485 return AST_MODULE_LOAD_FAILURE; 00486 return AST_MODULE_LOAD_SUCCESS; 00487 }
static struct ast_frame* pcm_read | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 76 of file format_pcm.c.
References AST_FORMAT_G722, AST_FRAME_SET_BUFFER, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), BUF_SIZE, errno, LOG_WARNING, and s.
00077 { 00078 int res; 00079 00080 /* Send a frame from the file to the appropriate channel */ 00081 00082 s->fr.frametype = AST_FRAME_VOICE; 00083 s->fr.subclass = s->fmt->format; 00084 s->fr.mallocd = 0; 00085 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE); 00086 if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) { 00087 if (res) 00088 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); 00089 return NULL; 00090 } 00091 s->fr.datalen = res; 00092 if (s->fmt->format == AST_FORMAT_G722) 00093 *whennext = s->fr.samples = res * 2; 00094 else 00095 *whennext = s->fr.samples = res; 00096 return &s->fr; 00097 }
static int pcm_seek | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) | [static] |
Definition at line 99 of file format_pcm.c.
References AST_FORMAT_ALAW, ast_log(), BUF_SIZE, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_frame::offset, SEEK_FORCECUR, and ast_frame::src.
00100 { 00101 off_t cur, max, offset = 0; 00102 int ret = -1; /* assume error */ 00103 00104 cur = ftello(fs->f); 00105 fseeko(fs->f, 0, SEEK_END); 00106 max = ftello(fs->f); 00107 00108 switch (whence) { 00109 case SEEK_SET: 00110 offset = sample_offset; 00111 break; 00112 case SEEK_END: 00113 offset = max - sample_offset; 00114 break; 00115 case SEEK_CUR: 00116 case SEEK_FORCECUR: 00117 offset = cur + sample_offset; 00118 break; 00119 default: 00120 ast_log(LOG_WARNING, "invalid whence %d, assuming SEEK_SET\n", whence); 00121 offset = sample_offset; 00122 } 00123 if (offset < 0) { 00124 ast_log(LOG_WARNING, "negative offset %ld, resetting to 0\n", (long) offset); 00125 offset = 0; 00126 } 00127 if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */ 00128 size_t left = offset - max; 00129 const char *src = (fs->fmt->format == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence; 00130 00131 while (left) { 00132 size_t written = fwrite(src, 1, (left > BUF_SIZE) ? BUF_SIZE : left, fs->f); 00133 if (written == -1) 00134 break; /* error */ 00135 left -= written; 00136 } 00137 ret = 0; /* successful */ 00138 } else { 00139 if (offset > max) { 00140 ast_log(LOG_WARNING, "offset too large %ld, truncating to %ld\n", (long) offset, (long) max); 00141 offset = max; 00142 } 00143 ret = fseeko(fs->f, offset, SEEK_SET); 00144 } 00145 return ret; 00146 }
static off_t pcm_tell | ( | struct ast_filestream * | fs | ) | [static] |
Definition at line 153 of file format_pcm.c.
References ast_filestream::f.
00154 { 00155 return ftello(fs->f); 00156 }
static int pcm_trunc | ( | struct ast_filestream * | fs | ) | [static] |
static int pcm_write | ( | struct ast_filestream * | fs, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 158 of file format_pcm.c.
References ast_filestream::_private, AST_FORMAT_ALAW, AST_FRAME_VOICE, ast_log(), errno, ast_filestream::f, f, ast_filestream::fmt, ast_format::format, LOG_WARNING, pd, and s.
00159 { 00160 int res; 00161 00162 if (f->frametype != AST_FRAME_VOICE) { 00163 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); 00164 return -1; 00165 } 00166 if (f->subclass != fs->fmt->format) { 00167 ast_log(LOG_WARNING, "Asked to write incompatible format frame (%d)!\n", f->subclass); 00168 return -1; 00169 } 00170 00171 #ifdef REALTIME_WRITE 00172 if (s->fmt->format == AST_FORMAT_ALAW) { 00173 struct pcm_desc *pd = (struct pcm_desc *)fs->_private; 00174 struct stat stat_buf; 00175 unsigned long cur_time = get_time(); 00176 unsigned long fpos = ( cur_time - pd->start_time ) * 8; /* 8 bytes per msec */ 00177 /* Check if we have written to this position yet. If we have, then increment pos by one frame 00178 * for some degree of protection against receiving packets in the same clock tick. 00179 */ 00180 00181 fstat(fileno(fs->f), &stat_buf ); 00182 if (stat_buf.st_size > fpos ) 00183 fpos += f->datalen; /* Incrementing with the size of this current frame */ 00184 00185 if (stat_buf.st_size < fpos) { 00186 /* fill the gap with 0x55 rather than 0. */ 00187 char buf[1024]; 00188 unsigned long cur, to_write; 00189 00190 cur = stat_buf.st_size; 00191 if (fseek(fs->f, cur, SEEK_SET) < 0) { 00192 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); 00193 return -1; 00194 } 00195 memset(buf, 0x55, 512); 00196 while (cur < fpos) { 00197 to_write = fpos - cur; 00198 if (to_write > sizeof(buf)) 00199 to_write = sizeof(buf); 00200 fwrite(buf, 1, to_write, fs->f); 00201 cur += to_write; 00202 } 00203 } 00204 00205 if (fseek(s->f, fpos, SEEK_SET) < 0) { 00206 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); 00207 return -1; 00208 } 00209 } 00210 #endif /* REALTIME_WRITE */ 00211 00212 if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) { 00213 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno)); 00214 return -1; 00215 } 00216 return 0; 00217 }
static int unload_module | ( | void | ) | [static] |
Definition at line 489 of file format_pcm.c.
References alaw_f, ast_format_unregister(), au_f, g722_f, ast_format::name, and pcm_f.
00490 { 00491 return ast_format_unregister(pcm_f.name) 00492 || ast_format_unregister(alaw_f.name) 00493 || ast_format_unregister(au_f.name) 00494 || ast_format_unregister(g722_f.name); 00495 }
static int update_header | ( | FILE * | f | ) | [static] |
Definition at line 304 of file format_pcm.c.
References ast_log(), AU_HDR_DATA_SIZE_OFF, AU_HEADER_SIZE, and LOG_WARNING.
Referenced by au_trunc(), and wav_trunc().
00305 { 00306 off_t cur, end; 00307 uint32_t datalen; 00308 int bytes; 00309 00310 cur = ftell(f); 00311 fseek(f, 0, SEEK_END); 00312 end = ftell(f); 00313 /* data starts 24 bytes in */ 00314 bytes = end - AU_HEADER_SIZE; 00315 datalen = htoll(bytes); 00316 00317 if (cur < 0) { 00318 ast_log(LOG_WARNING, "Unable to find our position\n"); 00319 return -1; 00320 } 00321 if (fseek(f, AU_HDR_DATA_SIZE_OFF * sizeof(uint32_t), SEEK_SET)) { 00322 ast_log(LOG_WARNING, "Unable to set our position\n"); 00323 return -1; 00324 } 00325 if (fwrite(&datalen, 1, sizeof(datalen), f) != sizeof(datalen)) { 00326 ast_log(LOG_WARNING, "Unable to set write file size\n"); 00327 return -1; 00328 } 00329 if (fseek(f, cur, SEEK_SET)) { 00330 ast_log(LOG_WARNING, "Unable to return to position\n"); 00331 return -1; 00332 } 00333 return 0; 00334 }
static int write_header | ( | FILE * | f | ) | [static] |
Definition at line 336 of file format_pcm.c.
References ast_log(), AU_ENC_8BIT_ULAW, AU_HDR_CHANNELS_OFF, AU_HDR_DATA_SIZE_OFF, AU_HDR_ENCODING_OFF, AU_HDR_HDR_SIZE_OFF, AU_HDR_MAGIC_OFF, AU_HDR_SAMPLE_RATE_OFF, AU_HEADER, AU_HEADER_SIZE, AU_MAGIC, DEFAULT_SAMPLE_RATE, and LOG_WARNING.
Referenced by au_rewrite(), and wav_rewrite().
00337 { 00338 AU_HEADER(header); 00339 00340 header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC); 00341 header[AU_HDR_HDR_SIZE_OFF] = htoll(AU_HEADER_SIZE); 00342 header[AU_HDR_DATA_SIZE_OFF] = 0; 00343 header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW); 00344 header[AU_HDR_SAMPLE_RATE_OFF] = htoll(DEFAULT_SAMPLE_RATE); 00345 header[AU_HDR_CHANNELS_OFF] = htoll(1); 00346 00347 /* Write an au header, ignoring sizes which will be filled in later */ 00348 fseek(f, 0, SEEK_SET); 00349 if (fwrite(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) { 00350 ast_log(LOG_WARNING, "Unable to write header\n"); 00351 return -1; 00352 } 00353 return 0; 00354 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 497 of file format_pcm.c.
struct ast_format alaw_f [static] |
char alaw_silence[BUF_SIZE] [static] |
Definition at line 40 of file format_pcm.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 497 of file format_pcm.c.
struct ast_format au_f [static] |
struct ast_format g722_f [static] |
struct ast_format pcm_f [static] |
char ulaw_silence[BUF_SIZE] [static] |
Definition at line 39 of file format_pcm.c.