42 static char ulaw_silence[BUF_SIZE];
43 static char alaw_silence[BUF_SIZE];
49 unsigned long start_time;
53 static unsigned long get_time(
void)
60 ast_log( LOG_WARNING,
"Cannot get current time\n" );
63 return cur * 1000 / sysconf( _SC_CLK_TCK );
69 pd->starttime = get_time();
73 static int pcma_rewrite(
struct ast_filestream *s,
const char *comment)
87 ast_log(LOG_WARNING,
"Short read of %s data (expected %d bytes, read %zu): %s\n",
98 static int pcm_seek(
struct ast_filestream *fs, off_t sample_offset,
int whence)
100 off_t cur, max,
offset = 0;
103 if ((cur = ftello(fs->f)) < 0) {
104 ast_log(AST_LOG_WARNING,
"Unable to determine current position in pcm filestream %p: %s\n", fs, strerror(errno));
108 if (fseeko(fs->f, 0, SEEK_END) < 0) {
109 ast_log(AST_LOG_WARNING,
"Unable to seek to end of pcm filestream %p: %s\n", fs, strerror(errno));
113 if ((max = ftello(fs->f)) < 0) {
114 ast_log(AST_LOG_WARNING,
"Unable to determine max position in pcm filestream %p: %s\n", fs, strerror(errno));
120 offset = sample_offset;
123 offset = max - sample_offset;
127 offset = cur + sample_offset;
130 ast_log(LOG_WARNING,
"invalid whence %d, assuming SEEK_SET\n", whence);
131 offset = sample_offset;
134 ast_log(LOG_WARNING,
"negative offset %ld, resetting to 0\n", (
long) offset);
137 if (whence == SEEK_FORCECUR && offset > max) {
138 size_t left = offset - max;
142 size_t written = fwrite(src, 1, MIN(left, BUF_SIZE), fs->f);
143 if (written < MIN(left, BUF_SIZE)) {
151 ast_log(LOG_WARNING,
"offset too large %ld, truncating to %ld\n", (
long) offset, (
long) max);
154 ret = fseeko(fs->f, offset, SEEK_SET);
163 if ((fd = fileno(fs->f)) < 0) {
164 ast_log(AST_LOG_WARNING,
"Unable to determine file descriptor for pcm filestream %p: %s\n", fs, strerror(errno));
167 if ((cur = ftello(fs->f)) < 0) {
168 ast_log(AST_LOG_WARNING,
"Unable to determine current position in pcm filestream %p: %s\n", fs, strerror(errno));
172 return ftruncate(fd, cur);
177 return ftello(fs->f);
184 #ifdef REALTIME_WRITE
186 struct pcm_desc *pd = (
struct pcm_desc *)fs->
_private;
187 struct stat stat_buf;
188 unsigned long cur_time = get_time();
189 unsigned long fpos = ( cur_time - pd->start_time ) * 8;
194 fstat(fileno(fs->f), &stat_buf );
195 if (stat_buf.st_size > fpos )
198 if (stat_buf.st_size < fpos) {
201 unsigned long cur, to_write;
203 cur = stat_buf.st_size;
204 if (fseek(fs->f, cur, SEEK_SET) < 0) {
205 ast_log( LOG_WARNING,
"Cannot seek in file: %s\n", strerror(errno) );
208 memset(buf, 0x55, 512);
210 to_write = fpos - cur;
211 if (to_write >
sizeof(buf))
212 to_write =
sizeof(buf);
213 if (fwrite(buf, 1, to_write, fs->f) != to_write) {
214 ast_log(LOG_ERROR,
"Failed to write to file: %s\n", strerror(errno));
221 if (fseek(s->f, fpos, SEEK_SET) < 0) {
222 ast_log( LOG_WARNING,
"Cannot seek in file: %s\n", strerror(errno) );
229 ast_log(LOG_WARNING,
"Bad write (%d/%d): %s\n", res, f->
datalen, strerror(errno));
237 #define MIN_AU_HEADER_SIZE 24
238 #define AU_HEADER(var) uint32_t var[6]
240 #define AU_HDR_MAGIC_OFF 0
241 #define AU_HDR_HDR_SIZE_OFF 1
242 #define AU_HDR_DATA_SIZE_OFF 2
243 #define AU_HDR_ENCODING_OFF 3
244 #define AU_HDR_SAMPLE_RATE_OFF 4
245 #define AU_HDR_CHANNELS_OFF 5
247 #define AU_ENC_8BIT_ULAW 1
249 #define AU_MAGIC 0x2e736e64
250 #if __BYTE_ORDER == __BIG_ENDIAN
256 #if __BYTE_ORDER == __LITTLE_ENDIAN
258 (((((b) ) & 0xFF) << 24) | \
259 ((((b) >> 8) & 0xFF) << 16) | \
260 ((((b) >> 16) & 0xFF) << 8) | \
261 ((((b) >> 24) & 0xFF) ))
263 (((((b) ) & 0xFF) << 8) | \
264 ((((b) >> 8) & 0xFF) ))
265 #define ltohl(b) htoll(b)
266 #define ltohs(b) htols(b)
268 #error "Endianess not defined"
283 uint32_t sample_rate;
289 if (fread(
header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
290 ast_log(LOG_WARNING,
"Read failed (header)\n");
293 magic = ltohl(
header[AU_HDR_MAGIC_OFF]);
294 if (magic != (uint32_t) AU_MAGIC) {
295 ast_log(LOG_WARNING,
"Bad magic: 0x%x\n", magic);
297 hdr_size = ltohl(
header[AU_HDR_HDR_SIZE_OFF]);
298 if (hdr_size < MIN_AU_HEADER_SIZE) {
299 hdr_size = MIN_AU_HEADER_SIZE;
302 encoding = ltohl(
header[AU_HDR_ENCODING_OFF]);
303 if (encoding != AU_ENC_8BIT_ULAW) {
304 ast_log(LOG_WARNING,
"Unexpected format: %u. Only 8bit ULAW allowed (%d)\n", encoding, AU_ENC_8BIT_ULAW);
307 sample_rate = ltohl(
header[AU_HDR_SAMPLE_RATE_OFF]);
308 if (sample_rate != DEFAULT_SAMPLE_RATE) {
309 ast_log(LOG_WARNING,
"Sample rate can only be 8000 not %u\n", sample_rate);
312 channels = ltohl(
header[AU_HDR_CHANNELS_OFF]);
314 ast_log(LOG_WARNING,
"Not in mono: channels=%u\n", channels);
318 fseek(f, 0, SEEK_END);
319 data_size = ftell(f) - hdr_size;
320 if (fseek(f, hdr_size, SEEK_SET) == -1 ) {
321 ast_log(LOG_WARNING,
"Failed to skip to data: %u\n", hdr_size);
326 desc->hdr_size = hdr_size;
340 fseek(f, 0, SEEK_END);
343 bytes = end - desc->hdr_size;
344 datalen = htoll(bytes);
347 ast_log(LOG_WARNING,
"Unable to find our position\n");
350 if (fseek(f, AU_HDR_DATA_SIZE_OFF *
sizeof(uint32_t), SEEK_SET)) {
351 ast_log(LOG_WARNING,
"Unable to set our position\n");
354 if (fwrite(&datalen, 1,
sizeof(datalen), f) !=
sizeof(datalen)) {
355 ast_log(LOG_WARNING,
"Unable to set write file size\n");
358 if (fseek(f, cur, SEEK_SET)) {
359 ast_log(LOG_WARNING,
"Unable to return to position\n");
372 header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC);
373 header[AU_HDR_HDR_SIZE_OFF] = htoll(desc->hdr_size);
374 header[AU_HDR_DATA_SIZE_OFF] = 0;
375 header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW);
376 header[AU_HDR_SAMPLE_RATE_OFF] = htoll(DEFAULT_SAMPLE_RATE);
377 header[AU_HDR_CHANNELS_OFF] = htoll(1);
380 fseek(f, 0, SEEK_SET);
381 if (fwrite(
header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
382 ast_log(LOG_WARNING,
"Unable to write header\n");
390 if (check_header(s) < 0)
395 static int au_rewrite(
struct ast_filestream *s,
const char *comment)
399 desc->hdr_size = MIN_AU_HEADER_SIZE;
407 static int au_seek(
struct ast_filestream *fs, off_t sample_offset,
int whence)
413 min = desc->hdr_size;
415 if ((cur = ftello(fs->f)) < 0) {
416 ast_log(AST_LOG_WARNING,
"Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno));
420 if (fseeko(fs->f, 0, SEEK_END) < 0) {
421 ast_log(AST_LOG_WARNING,
"Unable to seek to end of au filestream %p: %s\n", fs, strerror(errno));
425 if ((max = ftello(fs->f)) < 0) {
426 ast_log(AST_LOG_WARNING,
"Unable to determine max position in au filestream %p: %s\n", fs, strerror(errno));
430 if (whence == SEEK_SET)
431 offset = sample_offset + min;
432 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
433 offset = sample_offset + cur;
434 else if (whence == SEEK_END)
435 offset = max - sample_offset;
437 if (whence != SEEK_FORCECUR) {
438 offset = (offset > max) ? max : offset;
442 offset = (offset < min) ? min : offset;
444 return fseeko(fs->f, offset, SEEK_SET);
452 if ((fd = fileno(fs->f)) < 0) {
453 ast_log(AST_LOG_WARNING,
"Unable to determine file descriptor for au filestream %p: %s\n", fs, strerror(errno));
456 if ((cur = ftello(fs->f)) < 0) {
457 ast_log(AST_LOG_WARNING,
"Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno));
461 if (ftruncate(fd, cur)) {
464 return update_header(fs);
470 off_t offset = ftello(fs->f);
471 return offset - desc->hdr_size;
476 struct ast_frame *f = pcm_read(s, whennext);
477 *whennext = s->
fr.
samples = (*whennext * 2);
481 static int g722_seek(
struct ast_filestream *fs, off_t sample_offset,
int whence)
483 return pcm_seek(fs, sample_offset / 2, whence);
488 return pcm_tell(fs) * 2;
493 .exts =
"alaw|al|alw",
500 #ifdef REALTIME_WRITE
502 .rewrite = pcma_rewrite,
503 .desc_size =
sizeof(
struct pcm_desc),
509 .exts =
"pcm|ulaw|ul|mu|ulw",
510 .mime_types =
"audio/basic",
527 .buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
534 .rewrite = au_rewrite,
541 .desc_size =
sizeof(
struct au_desc),
544 static int unload_module(
void)
552 static int load_module(
void)
557 for (i = 0; i < ARRAY_LEN(ulaw_silence); i++)
558 ulaw_silence[i] = AST_LIN2MU(0);
559 for (i = 0; i < ARRAY_LEN(alaw_silence); i++)
560 alaw_silence[i] = AST_LIN2A(0);
566 if ( ast_format_def_register(&pcm_f)
567 || ast_format_def_register(&alaw_f)
568 || ast_format_def_register(&au_f)
569 || ast_format_def_register(&g722_f) ) {
576 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
577 .support_level = AST_MODULE_SUPPORT_CORE,
579 .unload = unload_module,
A-Law to Signed linear conversion.
Asterisk main include file. File version handling, generic pbx functions.
struct ast_frame_subclass subclass
u-Law to Signed linear conversion
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
Asterisk architecture endianess compatibility definitions.
struct ast_format_def * fmt
struct ast_frame fr
frame produced by read, typically
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
union ast_frame::@224 data
Module has failed to load, may be in an inconsistent state.
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Data structure associated with a single frame of data.
struct ast_format * format
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.