Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
format_pcm.c File Reference

Flat, binary, ulaw PCM file format. More...

#include "asterisk.h"
#include "asterisk/mod_format.h"
#include "asterisk/module.h"
#include "asterisk/endian.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/format_cache.h"
Include dependency graph for format_pcm.c:

Go to the source code of this file.

Data Structures

struct  au_desc
 

Macros

#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_MAGIC   0x2e736e64
 
#define BUF_SIZE   160 /* 160 bytes, and same number of samples */
 
#define MIN_AU_HEADER_SIZE   24
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (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 (struct ast_filestream *fs)
 
static struct ast_frameg722_read (struct ast_filestream *s, int *whennext)
 
static int g722_seek (struct ast_filestream *fs, off_t sample_offset, int whence)
 
static off_t g722_tell (struct ast_filestream *fs)
 
static int load_module (void)
 
static struct ast_framepcm_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 (struct ast_filestream *fs)
 
static int write_header (struct ast_filestream *fs)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
 
static struct ast_format_def alaw_f
 
static char alaw_silence [BUF_SIZE]
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_format_def au_f
 
static struct ast_format_def g722_f
 
static struct ast_format_def pcm_f
 
static char ulaw_silence [BUF_SIZE]
 

Detailed Description

Flat, binary, ulaw PCM file format.

Definition in file format_pcm.c.

Macro Definition Documentation

◆ AU_ENC_8BIT_ULAW

#define AU_ENC_8BIT_ULAW   1

Definition at line 247 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HDR_CHANNELS_OFF

#define AU_HDR_CHANNELS_OFF   5

Definition at line 245 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HDR_DATA_SIZE_OFF

#define AU_HDR_DATA_SIZE_OFF   2

Definition at line 242 of file format_pcm.c.

Referenced by update_header(), and write_header().

◆ AU_HDR_ENCODING_OFF

#define AU_HDR_ENCODING_OFF   3

Definition at line 243 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HDR_HDR_SIZE_OFF

#define AU_HDR_HDR_SIZE_OFF   1

Definition at line 241 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HDR_MAGIC_OFF

#define AU_HDR_MAGIC_OFF   0

Definition at line 240 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HDR_SAMPLE_RATE_OFF

#define AU_HDR_SAMPLE_RATE_OFF   4

Definition at line 244 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_HEADER

#define AU_HEADER (   var)    uint32_t var[6]

Definition at line 238 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ AU_MAGIC

#define AU_MAGIC   0x2e736e64

Definition at line 249 of file format_pcm.c.

Referenced by check_header(), and write_header().

◆ BUF_SIZE

#define BUF_SIZE   160 /* 160 bytes, and same number of samples */

Definition at line 40 of file format_pcm.c.

Referenced by pcm_read(), and pcm_seek().

◆ MIN_AU_HEADER_SIZE

#define MIN_AU_HEADER_SIZE   24

Definition at line 237 of file format_pcm.c.

Referenced by au_rewrite(), check_header(), and write_header().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 581 of file format_pcm.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 581 of file format_pcm.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 581 of file format_pcm.c.

◆ au_open()

static int au_open ( struct ast_filestream s)
static

Definition at line 388 of file format_pcm.c.

References check_header().

389 {
390  if (check_header(s) < 0)
391  return -1;
392  return 0;
393 }
static int check_header(struct ast_filestream *fs)
Definition: format_pcm.c:276

◆ au_rewrite()

static int au_rewrite ( struct ast_filestream s,
const char *  comment 
)
static

Definition at line 395 of file format_pcm.c.

References ast_filestream::_private, desc, au_desc::hdr_size, MIN_AU_HEADER_SIZE, and write_header().

396 {
397  struct au_desc *desc = s->_private;
398 
400 
401  if (write_header(s))
402  return -1;
403  return 0;
404 }
static const char desc[]
Definition: cdr_mysql.c:73
static int write_header(struct ast_filestream *fs)
Definition: format_pcm.c:365
#define MIN_AU_HEADER_SIZE
Definition: format_pcm.c:237
void * _private
Definition: mod_format.h:124
uint32_t hdr_size
Definition: format_pcm.c:273

◆ au_seek()

static int au_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Definition at line 407 of file format_pcm.c.

References ast_filestream::_private, ast_log, AST_LOG_WARNING, desc, errno, ast_filestream::f, au_desc::hdr_size, max, min, and SEEK_FORCECUR.

408 {
409  off_t min, max, cur;
410  long offset = 0;
411  struct au_desc *desc = fs->_private;
412 
413  min = desc->hdr_size;
414 
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));
417  return -1;
418  }
419 
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));
422  return -1;
423  }
424 
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));
427  return -1;
428  }
429 
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;
436 
437  if (whence != SEEK_FORCECUR) {
438  offset = (offset > max) ? max : offset;
439  }
440 
441  /* always protect the header space. */
442  offset = (offset < min) ? min : offset;
443 
444  return fseeko(fs->f, offset, SEEK_SET);
445 }
#define AST_LOG_WARNING
Definition: logger.h:279
static const char desc[]
Definition: cdr_mysql.c:73
#define ast_log
Definition: astobj2.c:42
void * _private
Definition: mod_format.h:124
int errno
#define SEEK_FORCECUR
Definition: file.h:51
#define min(a, b)
Definition: f2c.h:197
uint32_t hdr_size
Definition: format_pcm.c:273
#define max(a, b)
Definition: f2c.h:198

◆ au_tell()

static off_t au_tell ( struct ast_filestream fs)
static

Definition at line 467 of file format_pcm.c.

References ast_filestream::_private, desc, ast_filestream::f, and au_desc::hdr_size.

468 {
469  struct au_desc *desc = fs->_private;
470  off_t offset = ftello(fs->f);
471  return offset - desc->hdr_size;
472 }
static const char desc[]
Definition: cdr_mysql.c:73
void * _private
Definition: mod_format.h:124
uint32_t hdr_size
Definition: format_pcm.c:273

◆ au_trunc()

static int au_trunc ( struct ast_filestream fs)
static

Definition at line 447 of file format_pcm.c.

References ast_log, AST_LOG_WARNING, errno, ast_filestream::f, and update_header().

448 {
449  int fd;
450  off_t cur;
451 
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));
454  return -1;
455  }
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));
458  return -1;
459  }
460  /* Truncate file to current length */
461  if (ftruncate(fd, cur)) {
462  return -1;
463  }
464  return update_header(fs);
465 }
#define AST_LOG_WARNING
Definition: logger.h:279
#define ast_log
Definition: astobj2.c:42
int errno
static int update_header(struct ast_filestream *fs)
Definition: format_pcm.c:331

◆ check_header()

static int check_header ( struct ast_filestream fs)
static

Definition at line 276 of file format_pcm.c.

References ast_filestream::_private, 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_MAGIC, channels, DEFAULT_SAMPLE_RATE, desc, encoding, ast_filestream::f, au_desc::hdr_size, LOG_WARNING, and MIN_AU_HEADER_SIZE.

Referenced by au_open().

277 {
278  AU_HEADER(header);
279  uint32_t magic;
280  uint32_t hdr_size;
281  uint32_t data_size;
282  uint32_t encoding;
283  uint32_t sample_rate;
284  uint32_t channels;
285 
286  struct au_desc *desc = fs->_private;
287  FILE *f = fs->f;
288 
289  if (fread(header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
290  ast_log(LOG_WARNING, "Read failed (header)\n");
291  return -1;
292  }
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);
296  }
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;
300  }
301 /* data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */
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);
305  return -1;
306  }
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);
310  return -1;
311  }
312  channels = ltohl(header[AU_HDR_CHANNELS_OFF]);
313  if (channels != 1) {
314  ast_log(LOG_WARNING, "Not in mono: channels=%u\n", channels);
315  return -1;
316  }
317  /* Skip to data */
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);
322  return -1;
323  }
324 
325  /* We'll need this later */
326  desc->hdr_size = hdr_size;
327 
328  return data_size;
329 }
#define AU_HDR_SAMPLE_RATE_OFF
Definition: format_pcm.c:244
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:46
#define AU_HDR_HDR_SIZE_OFF
Definition: format_pcm.c:241
#define LOG_WARNING
Definition: logger.h:274
#define AU_HDR_ENCODING_OFF
Definition: format_pcm.c:243
static const char desc[]
Definition: cdr_mysql.c:73
#define AU_ENC_8BIT_ULAW
Definition: format_pcm.c:247
#define AU_HEADER(var)
Definition: format_pcm.c:238
#define ast_log
Definition: astobj2.c:42
#define AU_HDR_MAGIC_OFF
Definition: format_pcm.c:240
#define MIN_AU_HEADER_SIZE
Definition: format_pcm.c:237
#define AU_MAGIC
Definition: format_pcm.c:249
static struct channel_usage channels
void * _private
Definition: mod_format.h:124
#define AU_HDR_CHANNELS_OFF
Definition: format_pcm.c:245
static char * encoding
Definition: cdr_pgsql.c:74
uint32_t hdr_size
Definition: format_pcm.c:273

◆ g722_read()

static struct ast_frame* g722_read ( struct ast_filestream s,
int *  whennext 
)
static

Definition at line 474 of file format_pcm.c.

References ast_filestream::fr, pcm_read(), and ast_frame::samples.

475 {
476  struct ast_frame *f = pcm_read(s, whennext);
477  *whennext = s->fr.samples = (*whennext * 2);
478  return f;
479 }
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
Data structure associated with a single frame of data.
static struct ast_frame * pcm_read(struct ast_filestream *s, int *whennext)
Definition: format_pcm.c:79

◆ g722_seek()

static int g722_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Definition at line 481 of file format_pcm.c.

References pcm_seek().

482 {
483  return pcm_seek(fs, sample_offset / 2, whence);
484 }
static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_pcm.c:98

◆ g722_tell()

static off_t g722_tell ( struct ast_filestream fs)
static

Definition at line 486 of file format_pcm.c.

References pcm_tell().

487 {
488  return pcm_tell(fs) * 2;
489 }
static off_t pcm_tell(struct ast_filestream *fs)
Definition: format_pcm.c:175

◆ load_module()

static int load_module ( void  )
static

Definition at line 552 of file format_pcm.c.

References alaw_silence, ARRAY_LEN, ast_format_alaw, ast_format_def_register, ast_format_g722, ast_format_ulaw, AST_LIN2A, AST_LIN2MU, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, ast_format_def::format, ulaw_silence, and unload_module().

553 {
554  int i;
555 
556  /* XXX better init ? */
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);
561 
570  unload_module();
572  }
574 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static char ulaw_silence[BUF_SIZE]
Definition: format_pcm.c:42
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
static struct ast_format_def pcm_f
Definition: format_pcm.c:507
static struct ast_format_def au_f
Definition: format_pcm.c:530
static char alaw_silence[BUF_SIZE]
Definition: format_pcm.c:43
static struct ast_format_def g722_f
Definition: format_pcm.c:519
struct ast_format * ast_format_g722
Built-in cached g722 format.
Definition: format_cache.c:111
#define ast_format_def_register(f)
Definition: mod_format.h:136
struct ast_format * format
Definition: mod_format.h:48
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
#define AST_LIN2MU(a)
Definition: ulaw.h:49
static int unload_module(void)
Definition: format_pcm.c:544
#define AST_LIN2A(a)
Definition: alaw.h:50
static struct ast_format_def alaw_f
Definition: format_pcm.c:491

◆ pcm_read()

static struct ast_frame* pcm_read ( struct ast_filestream s,
int *  whennext 
)
static

Definition at line 79 of file format_pcm.c.

References ast_format_get_name(), AST_FRAME_SET_BUFFER, AST_FRIENDLY_OFFSET, ast_log, ast_filestream::buf, BUF_SIZE, ast_frame::data, ast_frame::datalen, errno, ast_filestream::f, ast_frame_subclass::format, ast_filestream::fr, LOG_WARNING, NULL, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by g722_read().

80 {
81  size_t res;
82 
83  /* Send a frame from the file to the appropriate channel */
85  if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
86  if (res) {
87  ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
89  strerror(errno));
90  }
91  return NULL;
92  }
93  s->fr.datalen = res;
94  *whennext = s->fr.samples = res;
95  return &s->fr;
96 }
#define LOG_WARNING
Definition: logger.h:274
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
int errno
union ast_frame::@263 data
#define BUF_SIZE
Definition: format_pcm.c:40
struct ast_format * format

◆ pcm_seek()

static int pcm_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Definition at line 98 of file format_pcm.c.

References alaw_silence, ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_log, AST_LOG_WARNING, BUF_SIZE, errno, ast_filestream::f, ast_filestream::fmt, ast_format_def::format, LOG_WARNING, max, MIN, ast_frame::offset, SEEK_FORCECUR, ast_frame::src, and ulaw_silence.

Referenced by g722_seek().

99 {
100  off_t cur, max, offset = 0;
101  int ret = -1; /* assume error */
102 
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));
105  return -1;
106  }
107 
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));
110  return -1;
111  }
112 
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));
115  return -1;
116  }
117 
118  switch (whence) {
119  case SEEK_SET:
120  offset = sample_offset;
121  break;
122  case SEEK_END:
123  offset = max - sample_offset;
124  break;
125  case SEEK_CUR:
126  case SEEK_FORCECUR:
127  offset = cur + sample_offset;
128  break;
129  default:
130  ast_log(LOG_WARNING, "invalid whence %d, assuming SEEK_SET\n", whence);
131  offset = sample_offset;
132  }
133  if (offset < 0) {
134  ast_log(LOG_WARNING, "negative offset %ld, resetting to 0\n", (long) offset);
135  offset = 0;
136  }
137  if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */
138  size_t left = offset - max;
140 
141  while (left) {
142  size_t written = fwrite(src, 1, MIN(left, BUF_SIZE), fs->f);
143  if (written < MIN(left, BUF_SIZE)) {
144  break; /* error */
145  }
146  left -= written;
147  }
148  ret = 0; /* successful */
149  } else {
150  if (offset > max) {
151  ast_log(LOG_WARNING, "offset too large %ld, truncating to %ld\n", (long) offset, (long) max);
152  offset = max;
153  }
154  ret = fseeko(fs->f, offset, SEEK_SET);
155  }
156  return ret;
157 }
static char ulaw_silence[BUF_SIZE]
Definition: format_pcm.c:42
#define LOG_WARNING
Definition: logger.h:274
#define AST_LOG_WARNING
Definition: logger.h:279
static char alaw_silence[BUF_SIZE]
Definition: format_pcm.c:43
#define MIN(a, b)
Definition: utils.h:226
#define ast_log
Definition: astobj2.c:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
const char * src
struct ast_format_def * fmt
Definition: mod_format.h:103
struct ast_format * format
Definition: mod_format.h:48
int errno
#define SEEK_FORCECUR
Definition: file.h:51
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
#define BUF_SIZE
Definition: format_pcm.c:40
#define max(a, b)
Definition: f2c.h:198

◆ pcm_tell()

static off_t pcm_tell ( struct ast_filestream fs)
static

Definition at line 175 of file format_pcm.c.

References ast_filestream::f.

Referenced by g722_tell().

176 {
177  return ftello(fs->f);
178 }

◆ pcm_trunc()

static int pcm_trunc ( struct ast_filestream fs)
static

Definition at line 159 of file format_pcm.c.

References ast_log, AST_LOG_WARNING, errno, and ast_filestream::f.

160 {
161  int cur, fd;
162 
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));
165  return -1;
166  }
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));
169  return -1;
170  }
171  /* Truncate file to current length */
172  return ftruncate(fd, cur);
173 }
#define AST_LOG_WARNING
Definition: logger.h:279
#define ast_log
Definition: astobj2.c:42
int errno

◆ pcm_write()

static int pcm_write ( struct ast_filestream fs,
struct ast_frame f 
)
static

Definition at line 180 of file format_pcm.c.

References ast_filestream::_private, ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_log, buf, ast_frame::data, ast_frame::datalen, errno, ast_filestream::f, ast_filestream::fmt, ast_format_def::format, LOG_ERROR, LOG_WARNING, and ast_frame::ptr.

181 {
182  int res;
183 
184 #ifdef REALTIME_WRITE
185  if (ast_format_cmp(s->fmt->format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
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; /* 8 bytes per msec */
190  /* Check if we have written to this position yet. If we have, then increment pos by one frame
191  * for some degree of protection against receiving packets in the same clock tick.
192  */
193 
194  fstat(fileno(fs->f), &stat_buf );
195  if (stat_buf.st_size > fpos )
196  fpos += f->datalen; /* Incrementing with the size of this current frame */
197 
198  if (stat_buf.st_size < fpos) {
199  /* fill the gap with 0x55 rather than 0. */
200  char buf[1024];
201  unsigned long cur, to_write;
202 
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) );
206  return -1;
207  }
208  memset(buf, 0x55, 512);
209  while (cur < fpos) {
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));
215  return -1;
216  }
217  cur += to_write;
218  }
219  }
220 
221  if (fseek(s->f, fpos, SEEK_SET) < 0) {
222  ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) );
223  return -1;
224  }
225  }
226 #endif /* REALTIME_WRITE */
227 
228  if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
229  ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
230  return -1;
231  }
232  return 0;
233 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
void * _private
Definition: mod_format.h:124
#define LOG_ERROR
Definition: logger.h:285
int errno
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
union ast_frame::@263 data

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 544 of file format_pcm.c.

References ast_format_def_unregister(), and ast_format_def::name.

Referenced by load_module().

545 {
550 }
static struct ast_format_def pcm_f
Definition: format_pcm.c:507
static struct ast_format_def au_f
Definition: format_pcm.c:530
static struct ast_format_def g722_f
Definition: format_pcm.c:519
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
char name[80]
Definition: mod_format.h:44
static struct ast_format_def alaw_f
Definition: format_pcm.c:491

◆ update_header()

static int update_header ( struct ast_filestream fs)
static

Definition at line 331 of file format_pcm.c.

References ast_filestream::_private, ast_log, AU_HDR_DATA_SIZE_OFF, desc, end, ast_filestream::f, au_desc::hdr_size, and LOG_WARNING.

Referenced by au_trunc().

332 {
333  off_t cur, end;
334  uint32_t datalen;
335  int bytes;
336  struct au_desc *desc = fs->_private;
337  FILE *f = fs->f;
338 
339  cur = ftell(f);
340  fseek(f, 0, SEEK_END);
341  end = ftell(f);
342  /* data starts 24 bytes in */
343  bytes = end - desc->hdr_size;
344  datalen = htoll(bytes);
345 
346  if (cur < 0) {
347  ast_log(LOG_WARNING, "Unable to find our position\n");
348  return -1;
349  }
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");
352  return -1;
353  }
354  if (fwrite(&datalen, 1, sizeof(datalen), f) != sizeof(datalen)) {
355  ast_log(LOG_WARNING, "Unable to set write file size\n");
356  return -1;
357  }
358  if (fseek(f, cur, SEEK_SET)) {
359  ast_log(LOG_WARNING, "Unable to return to position\n");
360  return -1;
361  }
362  return 0;
363 }
#define LOG_WARNING
Definition: logger.h:274
#define AU_HDR_DATA_SIZE_OFF
Definition: format_pcm.c:242
static const char desc[]
Definition: cdr_mysql.c:73
char * end
Definition: eagi_proxy.c:73
#define ast_log
Definition: astobj2.c:42
void * _private
Definition: mod_format.h:124
uint32_t hdr_size
Definition: format_pcm.c:273

◆ write_header()

static int write_header ( struct ast_filestream fs)
static

Definition at line 365 of file format_pcm.c.

References ast_filestream::_private, 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_MAGIC, DEFAULT_SAMPLE_RATE, desc, ast_filestream::f, au_desc::hdr_size, LOG_WARNING, and MIN_AU_HEADER_SIZE.

Referenced by au_rewrite().

366 {
367  struct au_desc *desc = fs->_private;
368  FILE *f = fs->f;
369 
370  AU_HEADER(header);
371 
372  header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC);
373  header[AU_HDR_HDR_SIZE_OFF] = htoll(desc->hdr_size);
377  header[AU_HDR_CHANNELS_OFF] = htoll(1);
378 
379  /* Write an au header, ignoring sizes which will be filled in later */
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");
383  return -1;
384  }
385  return 0;
386 }
#define AU_HDR_SAMPLE_RATE_OFF
Definition: format_pcm.c:244
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:46
#define AU_HDR_HDR_SIZE_OFF
Definition: format_pcm.c:241
#define LOG_WARNING
Definition: logger.h:274
#define AU_HDR_DATA_SIZE_OFF
Definition: format_pcm.c:242
#define AU_HDR_ENCODING_OFF
Definition: format_pcm.c:243
static const char desc[]
Definition: cdr_mysql.c:73
#define AU_ENC_8BIT_ULAW
Definition: format_pcm.c:247
#define AU_HEADER(var)
Definition: format_pcm.c:238
#define ast_log
Definition: astobj2.c:42
#define AU_HDR_MAGIC_OFF
Definition: format_pcm.c:240
#define MIN_AU_HEADER_SIZE
Definition: format_pcm.c:237
#define AU_MAGIC
Definition: format_pcm.c:249
void * _private
Definition: mod_format.h:124
#define AU_HDR_CHANNELS_OFF
Definition: format_pcm.c:245
uint32_t hdr_size
Definition: format_pcm.c:273

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 581 of file format_pcm.c.

◆ alaw_f

struct ast_format_def alaw_f
static

Definition at line 491 of file format_pcm.c.

◆ alaw_silence

char alaw_silence[BUF_SIZE]
static

Definition at line 43 of file format_pcm.c.

Referenced by load_module(), and pcm_seek().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 581 of file format_pcm.c.

◆ au_f

struct ast_format_def au_f
static

Definition at line 530 of file format_pcm.c.

◆ g722_f

struct ast_format_def g722_f
static

Definition at line 519 of file format_pcm.c.

◆ pcm_f

struct ast_format_def pcm_f
static

Definition at line 507 of file format_pcm.c.

◆ ulaw_silence

char ulaw_silence[BUF_SIZE]
static

Definition at line 42 of file format_pcm.c.

Referenced by load_module(), and pcm_seek().