Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:53 2009

## Asterisk developer's documentation

# format_pcm.c File Reference

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

`#include <unistd.h>`
`#include <netinet/in.h>`
`#include <arpa/inet.h>`
`#include <stdlib.h>`
`#include <sys/time.h>`
`#include <stdio.h>`
`#include <errno.h>`
`#include <string.h>`
`#include "asterisk.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 "asterisk/endian.h"`
`#include "asterisk/ulaw.h"`

Include dependency graph for format_pcm.c:

Go to the source code of this file.

## Data Structures

struct | ast_filestream

## Defines

#define | BUF_SIZE 160

## Functions

| AST_MUTEX_DEFINE_STATIC (pcm_lock)
char * | description ()
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module ()
| Initialize the module.
static void | pcm_close (struct ast_filestream *s)
static char * | pcm_getcomment (struct ast_filestream *s)
static struct ast_filestream * | pcm_open (FILE *f)
static struct ast_frame * | pcm_read (struct ast_filestream *s, int *whennext)
static struct ast_filestream * | pcm_rewrite (FILE *f, const char *comment)
static int | pcm_seek (struct ast_filestream *fs, long sample_offset, int whence)
static long | 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)
int | unload_module ()
| Cleanup all module structures, sockets, etc.
int | usecount ()
| Provides a usecount.

## Variables

static char * | desc = "Raw uLaw 8khz Audio support (PCM)"
static char * | exts = "pcm|ulaw|ul|mu"
static int | glistcnt = 0
static char * | name = "pcm"
static char | ulaw_silence [BUF_SIZE]

## Detailed Description

Flat, binary, ulaw PCM file format.

- File name extension: pcm, ulaw, ul, mu

Definition in file format_pcm.c.

## Define Documentation

#define BUF_SIZE 160

Definition at line 49 of file format_pcm.c.

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | pcm_lock |  | ) |

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 267 of file format_pcm.c.

    00268 {
    00269    return desc;
    00270 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 273 of file format_pcm.c.

References ASTERISK_GPL_KEY.

    00274 {
    00275    return ASTERISK_GPL_KEY;
    00276 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 238 of file format_pcm.c.

References ast_format_register(), AST_FORMAT_ULAW, AST_LIN2MU, pcm_close(), pcm_getcomment(), pcm_open(), pcm_read(), pcm_rewrite(), pcm_seek(), pcm_tell(), pcm_trunc(), and pcm_write().

    00239 {
    00240    int index;
    00241
    00242    for (index = 0; index < (sizeof(ulaw_silence) / sizeof(ulaw_silence[0])); index++)
    00243       ulaw_silence[index] = AST_LIN2MU(0);
    00244
    00245    return ast_format_register(name, exts, AST_FORMAT_ULAW,
    00246                pcm_open,
    00247                pcm_rewrite,
    00248                pcm_write,
    00249                pcm_seek,
    00250                pcm_trunc,
    00251                pcm_tell,
    00252                pcm_read,
    00253                pcm_close,
    00254                pcm_getcomment);
    00255 }

static void pcm_close | ( | struct ast_filestream * | s | ) | `[static]`

Definition at line 122 of file format_pcm.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), ast_filestream::f, free, and LOG_WARNING.

Referenced by load_module().

    00123 {
    00124    if (ast_mutex_lock(&pcm_lock)) {
    00125       ast_log(LOG_WARNING, "Unable to lock pcm list\n");
    00126       return;
    00127    }
    00128    glistcnt--;
    00129    ast_mutex_unlock(&pcm_lock);
    00130    ast_update_use_count();
    00131    fclose(s->f);
    00132    free(s);
    00133    s = NULL;
    00134 }

static char* pcm_getcomment | ( | struct ast_filestream * | s | ) | `[static]`

Definition at line 233 of file format_pcm.c.

Referenced by load_module().

    00234 {
    00235    return NULL;
    00236 }

static struct ast_filestream* pcm_open | ( | FILE * | f | ) | `[static, read]`

Definition at line 73 of file format_pcm.c.

References AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), ast_filestream::buf, ast_frame::data, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, free, LOG_WARNING, malloc, ast_frame::mallocd, ast_frame::src, and ast_frame::subclass.

Referenced by load_module().

    00074 {
    00075    /* We don't have any header to read or anything really, but
    00076       if we did, it would go here.  We also might want to check
    00077       and be sure it's a valid file.  */
    00078    struct ast_filestream *tmp;
    00079    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
    00080       memset(tmp, 0, sizeof(struct ast_filestream));
    00081       if (ast_mutex_lock(&pcm_lock)) {
    00082          ast_log(LOG_WARNING, "Unable to lock pcm list\n");
    00083          free(tmp);
    00084          return NULL;
    00085       }
    00086       tmp->f = f;
    00087       tmp->fr.data = tmp->buf;
    00088       tmp->fr.frametype = AST_FRAME_VOICE;
    00089       tmp->fr.subclass = AST_FORMAT_ULAW;
    00090       /* datalen will vary for each frame */
    00091       tmp->fr.src = name;
    00092       tmp->fr.mallocd = 0;
    00093       glistcnt++;
    00094       ast_mutex_unlock(&pcm_lock);
    00095       ast_update_use_count();
    00096    }
    00097    return tmp;
    00098 }

static struct ast_frame* pcm_read | ( | struct ast_filestream * | s,
|  | int * | whennext |
| ) |  |  | `[static, read]`

Definition at line 136 of file format_pcm.c.

References AST_FORMAT_ULAW, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_filestream::buf, BUF_SIZE, ast_frame::data, ast_frame::datalen, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, LOG_WARNING, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, and ast_frame::subclass.

Referenced by load_module().

    00137 {
    00138    int res;
    00139    int delay;
    00140    /* Send a frame from the file to the appropriate channel */
    00141
    00142    s->fr.frametype = AST_FRAME_VOICE;
    00143    s->fr.subclass = AST_FORMAT_ULAW;
    00144    s->fr.offset = AST_FRIENDLY_OFFSET;
    00145    s->fr.mallocd = 0;
    00146    s->fr.data = s->buf;
    00147    if ((res = fread(s->buf, 1, BUF_SIZE, s->f)) < 1) {
    00148       if (res)
    00149          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
    00150       return NULL;
    00151    }
    00152    s->fr.samples = res;
    00153    s->fr.datalen = res;
    00154    delay = s->fr.samples;
    00155    *whennext = delay;
    00156    return &s->fr;
    00157 }

static struct ast_filestream* pcm_rewrite | ( | FILE * | f,
|  | const char * | comment |
| ) |  |  | `[static, read]`

Definition at line 100 of file format_pcm.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), ast_filestream::f, free, LOG_WARNING, and malloc.

Referenced by load_module().

    00101 {
    00102    /* We don't have any header to read or anything really, but
    00103       if we did, it would go here.  We also might want to check
    00104       and be sure it's a valid file.  */
    00105    struct ast_filestream *tmp;
    00106    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
    00107       memset(tmp, 0, sizeof(struct ast_filestream));
    00108       if (ast_mutex_lock(&pcm_lock)) {
    00109          ast_log(LOG_WARNING, "Unable to lock pcm list\n");
    00110          free(tmp);
    00111          return NULL;
    00112       }
    00113       tmp->f = f;
    00114       glistcnt++;
    00115       ast_mutex_unlock(&pcm_lock);
    00116       ast_update_use_count();
    00117    } else
    00118       ast_log(LOG_WARNING, "Out of memory\n");
    00119    return tmp;
    00120 }

static int pcm_seek | ( | struct ast_filestream * | fs,
|  | long | sample_offset,
|  | int | whence |
| ) |  |  | `[static]`

Definition at line 177 of file format_pcm.c.

References BUF_SIZE, ast_filestream::f, offset, and SEEK_FORCECUR.

Referenced by load_module().

    00178 {
    00179    long cur, max, offset = 0;
    00180
    00181    cur = ftell(fs->f);
    00182    fseek(fs->f, 0, SEEK_END);
    00183    max = ftell(fs->f);
    00184
    00185    switch (whence) {
    00186    case SEEK_SET:
    00187       offset = sample_offset;
    00188       break;
    00189    case SEEK_END:
    00190       offset = max - sample_offset;
    00191       break;
    00192    case SEEK_CUR:
    00193    case SEEK_FORCECUR:
    00194       offset = cur + sample_offset;
    00195       break;
    00196    }
    00197
    00198    switch (whence) {
    00199    case SEEK_FORCECUR:
    00200       if (offset > max) {
    00201          size_t left = offset - max;
    00202          size_t res;
    00203
    00204          while (left) {
    00205             res = fwrite(ulaw_silence, sizeof(ulaw_silence[0]),
    00206                     (left > BUF_SIZE) ? BUF_SIZE : left, fs->f);
    00207             if (res == -1)
    00208                return res;
    00209             left -= res * sizeof(ulaw_silence[0]);
    00210          }
    00211          return offset;
    00212       }
    00213       /* fall through */
    00214    default:
    00215       offset = (offset > max) ? max : offset;
    00216       offset = (offset < 0) ? 0 : offset;
    00217       return fseek(fs->f, offset, SEEK_SET);
    00218    }
    00219 }

static long pcm_tell | ( | struct ast_filestream * | fs | ) | `[static]`

Definition at line 226 of file format_pcm.c.

References ast_filestream::f, and offset.

Referenced by load_module().

    00227 {
    00228    off_t offset;
    00229    offset = ftell(fs->f);
    00230    return offset;
    00231 }

static int pcm_trunc | ( | struct ast_filestream * | fs | ) | `[static]`

Definition at line 221 of file format_pcm.c.

References ast_filestream::f.

Referenced by load_module().

    00222 {
    00223    return ftruncate(fileno(fs->f), ftell(fs->f));
    00224 }

static int pcm_write | ( | struct ast_filestream * | fs,
|  | struct ast_frame * | f |
| ) |  |  | `[static]`

Definition at line 159 of file format_pcm.c.

References AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_filestream::f, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.

Referenced by load_module().

    00160 {
    00161    int res;
    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 != AST_FORMAT_ULAW) {
    00167       ast_log(LOG_WARNING, "Asked to write non-ulaw frame (%d)!\n", f->subclass);
    00168       return -1;
    00169    }
    00170    if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
    00171          ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
    00172          return -1;
    00173    }
    00174    return 0;
    00175 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 257 of file format_pcm.c.

References ast_format_unregister().

    00258 {
    00259    return ast_format_unregister(name);
    00260 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 262 of file format_pcm.c.

    00263 {
    00264    return glistcnt;
    00265 }

## Variable Documentation

char* desc = "Raw uLaw 8khz Audio support (PCM)"`[static]`

Definition at line 68 of file format_pcm.c.

char* exts = "pcm|ulaw|ul|mu"`[static]`

Definition at line 69 of file format_pcm.c.

int glistcnt = 0`[static]`

Definition at line 65 of file format_pcm.c.

char* name = "pcm"`[static]`

Definition at line 67 of file format_pcm.c.

char ulaw_silence[BUF_SIZE]`[static]`

Definition at line 71 of file format_pcm.c.