Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:51 2009

## Asterisk developer's documentation

# format_au.c File Reference

Work with Sun Microsystems AU format. More...

`#include <stdlib.h>`
`#include <sys/time.h>`
`#include <stdio.h>`
`#include <unistd.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 dependency graph for format_au.c:

Go to the source code of this file.

## Data Structures

struct | ast_filestream

## 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) u_int32_t var[6]
#define | AU_HEADER_SIZE 24
#define | AU_MAGIC 0x2e736e64
#define | BUF_SIZE 160
#define | htoll(b) (b)
#define | htols(b) (b)
#define | ltohl(b) (b)
#define | ltohs(b) (b)

## Functions

| AST_MUTEX_DEFINE_STATIC (au_lock)
static void | au_close (struct ast_filestream *s)
static char * | au_getcomment (struct ast_filestream *s)
static struct ast_filestream * | au_open (FILE *f)
static struct ast_frame * | au_read (struct ast_filestream *s, int *whennext)
static struct ast_filestream * | au_rewrite (FILE *f, const char *comment)
static int | au_seek (struct ast_filestream *fs, long sample_offset, int whence)
static long | au_tell (struct ast_filestream *fs)
static int | au_trunc (struct ast_filestream *fs)
static int | au_write (struct ast_filestream *fs, struct ast_frame *f)
static int | check_header (FILE *f)
char * | description ()
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module ()
| Initialize the module.
int | unload_module ()
| Cleanup all module structures, sockets, etc.
static int | update_header (FILE *f)
int | usecount ()
| Provides a usecount.
static int | write_header (FILE *f)

## Variables

static char * | desc = "Sun Microsystems AU format (signed linear)"
static char * | exts = "au"
static int | localusecnt = 0
static char * | name = "au"

## Detailed Description

Work with Sun Microsystems AU format.

signed linear

- File extension: au

Definition in file format_au.c.

## Define Documentation

#define AU_ENC_8BIT_ULAW 1

Definition at line 59 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HDR_CHANNELS_OFF 5

Definition at line 57 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HDR_DATA_SIZE_OFF 2

Definition at line 54 of file format_au.c.

Referenced by update_header(), and write_header().

#define AU_HDR_ENCODING_OFF 3

Definition at line 55 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HDR_HDR_SIZE_OFF 1

Definition at line 53 of file format_au.c.

Referenced by write_header().

#define AU_HDR_MAGIC_OFF 0

Definition at line 52 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HDR_SAMPLE_RATE_OFF 4

Definition at line 56 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HEADER | ( | var |  | ) | u_int32_t var[6]

Definition at line 50 of file format_au.c.

Referenced by check_header(), and write_header().

#define AU_HEADER_SIZE 24

Definition at line 49 of file format_au.c.

Referenced by au_seek(), au_tell(), check_header(), update_header(), and write_header().

#define AU_MAGIC 0x2e736e64

Definition at line 81 of file format_au.c.

Referenced by check_header(), and write_header().

#define BUF_SIZE 160

Definition at line 47 of file format_au.c.

Referenced by au_read(), pcm_read(), pcm_seek(), slinear_read(), and vox_read().

#define htoll | ( | b |  | ) | (b)

Definition at line 83 of file format_au.c.

Referenced by update_header(), and write_header().

#define htols | ( | b |  | ) | (b)

Definition at line 84 of file format_au.c.

Referenced by write_header().

#define ltohl | ( | b |  | ) | (b)

Definition at line 85 of file format_au.c.

Referenced by check_header().

#define ltohs | ( | b |  | ) | (b)

Definition at line 86 of file format_au.c.

Referenced by check_header().

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | au_lock |  | ) |

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

Definition at line 262 of file format_au.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().

    00263 {
    00264    if (ast_mutex_lock(&au_lock)) {
    00265       ast_log(LOG_WARNING, "Unable to lock au count\n");
    00266       return;
    00267    }
    00268    localusecnt--;
    00269    ast_mutex_unlock(&au_lock);
    00270    ast_update_use_count();
    00271    fclose(s->f);
    00272    free(s);
    00273 }

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

Definition at line 357 of file format_au.c.

Referenced by load_module().

    00358 {
    00359    return NULL;
    00360 }

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

Definition at line 204 of file format_au.c.

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

Referenced by load_module().

    00205 {
    00206    struct ast_filestream *tmp;
    00207
    00208    if (!(tmp = malloc(sizeof(struct ast_filestream)))) {
    00209       ast_log(LOG_ERROR, "Out of memory\n");
    00210       return NULL;
    00211    }
    00212
    00213    memset(tmp, 0, sizeof(struct ast_filestream));
    00214    if (check_header(f) < 0) {
    00215       free(tmp);
    00216       return NULL;
    00217    }
    00218    if (ast_mutex_lock(&au_lock)) {
    00219       ast_log(LOG_WARNING, "Unable to lock au count\n");
    00220       free(tmp);
    00221       return NULL;
    00222    }
    00223    tmp->f = f;
    00224    tmp->fr.data = tmp->buf;
    00225    tmp->fr.frametype = AST_FRAME_VOICE;
    00226    tmp->fr.subclass = AST_FORMAT_ULAW;
    00227    /* datalen will vary for each frame */
    00228    tmp->fr.src = name;
    00229    tmp->fr.mallocd = 0;
    00230    localusecnt++;
    00231    ast_mutex_unlock(&au_lock);
    00232    ast_update_use_count();
    00233    return tmp;
    00234 }

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

Definition at line 275 of file format_au.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().

    00276 {
    00277    int res;
    00278    int delay;
    00279    /* Send a frame from the file to the appropriate channel */
    00280
    00281    s->fr.frametype = AST_FRAME_VOICE;
    00282    s->fr.subclass = AST_FORMAT_ULAW;
    00283    s->fr.offset = AST_FRIENDLY_OFFSET;
    00284    s->fr.mallocd = 0;
    00285    s->fr.data = s->buf;
    00286    if ((res = fread(s->buf, 1, BUF_SIZE, s->f)) < 1) {
    00287       if (res)
    00288          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
    00289       return NULL;
    00290    }
    00291    s->fr.samples = res;
    00292    s->fr.datalen = res;
    00293    delay = s->fr.samples;
    00294    *whennext = delay;
    00295    return &s->fr;
    00296 }

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

Definition at line 236 of file format_au.c.

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

Referenced by load_module().

    00237 {
    00238    struct ast_filestream *tmp;
    00239
    00240    if ((tmp = malloc(sizeof(struct ast_filestream))) == NULL) {
    00241       ast_log(LOG_ERROR, "Out of memory\n");
    00242       return NULL;
    00243    }
    00244
    00245    memset(tmp, 0, sizeof(struct ast_filestream));
    00246    if (write_header(f)) {
    00247       free(tmp);
    00248       return NULL;
    00249    }
    00250    if (ast_mutex_lock(&au_lock)) {
    00251       ast_log(LOG_WARNING, "Unable to lock au count\n");
    00252       free(tmp);
    00253       return NULL;
    00254    }
    00255    tmp->f = f;
    00256    localusecnt++;
    00257    ast_mutex_unlock(&au_lock);
    00258    ast_update_use_count();
    00259    return tmp;
    00260 }

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

Definition at line 318 of file format_au.c.

References AU_HEADER_SIZE, ast_filestream::f, offset, ast_frame::samples, and SEEK_FORCECUR.

Referenced by load_module().

    00319 {
    00320    off_t min, max, cur;
    00321    long offset = 0, samples;
    00322
    00323    samples = sample_offset;
    00324    min = AU_HEADER_SIZE;
    00325    cur = ftell(fs->f);
    00326    fseek(fs->f, 0, SEEK_END);
    00327    max = ftell(fs->f);
    00328    if (whence == SEEK_SET)
    00329       offset = samples + min;
    00330    else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
    00331       offset = samples + cur;
    00332    else if (whence == SEEK_END)
    00333       offset = max - samples;
    00334         if (whence != SEEK_FORCECUR) {
    00335       offset = (offset > max) ? max : offset;
    00336    }
    00337    /* always protect the header space. */
    00338    offset = (offset < min) ? min : offset;
    00339    return fseek(fs->f, offset, SEEK_SET);
    00340 }

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

Definition at line 349 of file format_au.c.

References AU_HEADER_SIZE, ast_filestream::f, and offset.

Referenced by load_module().

    00350 {
    00351    off_t offset;
    00352
    00353    offset = ftell(fs->f);
    00354    return offset - AU_HEADER_SIZE;
    00355 }

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

Definition at line 342 of file format_au.c.

References ast_filestream::f, and update_header().

Referenced by load_module().

    00343 {
    00344    if (ftruncate(fileno(fs->f), ftell(fs->f)))
    00345       return -1;
    00346    return update_header(fs->f);
    00347 }

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

Definition at line 298 of file format_au.c.

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

Referenced by load_module().

    00299 {
    00300    int res;
    00301
    00302    if (f->frametype != AST_FRAME_VOICE) {
    00303       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
    00304       return -1;
    00305    }
    00306    if (f->subclass != AST_FORMAT_ULAW) {
    00307       ast_log(LOG_WARNING, "Asked to write non-ulaw frame (%d)!\n", f->subclass);
    00308       return -1;
    00309    }
    00310    if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
    00311          ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
    00312          return -1;
    00313    }
    00314    update_header(fs->f);
    00315    return 0;
    00316 }

static int check_header | ( | FILE * | f | ) | `[static]`

Definition at line 105 of file format_au.c.

References ast_log(), AU_ENC_8BIT_ULAW, AU_HDR_CHANNELS_OFF, AU_HDR_ENCODING_OFF, AU_HDR_MAGIC_OFF, AU_HDR_SAMPLE_RATE_OFF, AU_HEADER, AU_HEADER_SIZE, AU_MAGIC, channels, LOG_WARNING, and ltohl.

Referenced by au_open(), and wav_open().

    00106 {
    00107    AU_HEADER(header);
    00108    u_int32_t magic;
    00109    u_int32_t hdr_size;
    00110    u_int32_t data_size;
    00111    u_int32_t encoding;
    00112    u_int32_t sample_rate;
    00113    u_int32_t channels;
    00114
    00115    if (fread(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
    00116       ast_log(LOG_WARNING, "Read failed (header)\n");
    00117       return -1;
    00118    }
    00119    magic = ltohl(header[AU_HDR_MAGIC_OFF]);
    00120    if (magic != (u_int32_t) AU_MAGIC) {
    00121       ast_log(LOG_WARNING, "Bad magic: 0x%x\n", magic);
    00122    }
    00123 /* hdr_size = ltohl(header[AU_HDR_HDR_SIZE_OFF]);
    00124    if (hdr_size < AU_HEADER_SIZE)*/
    00125    hdr_size = AU_HEADER_SIZE;
    00126 /* data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */
    00127    encoding = ltohl(header[AU_HDR_ENCODING_OFF]);
    00128    if (encoding != AU_ENC_8BIT_ULAW) {
    00129       ast_log(LOG_WARNING, "Unexpected format: %d. Only 8bit ULAW allowed (%d)\n", encoding, AU_ENC_8BIT_ULAW);
    00130       return -1;
    00131    }
    00132    sample_rate = ltohl(header[AU_HDR_SAMPLE_RATE_OFF]);
    00133    if (sample_rate != 8000) {
    00134       ast_log(LOG_WARNING, "Sample rate can only be 8000 not %d\n", sample_rate);
    00135       return -1;
    00136    }
    00137    channels = ltohl(header[AU_HDR_CHANNELS_OFF]);
    00138    if (channels != 1) {
    00139       ast_log(LOG_WARNING, "Not in mono: channels=%d\n", channels);
    00140       return -1;
    00141    }
    00142    /* Skip to data */
    00143    fseek(f, 0, SEEK_END);
    00144    data_size = ftell(f) - hdr_size;
    00145    if (fseek(f, hdr_size, SEEK_SET) == -1 ) {
    00146       ast_log(LOG_WARNING, "Failed to skip to data: %d\n", hdr_size);
    00147       return -1;
    00148    }
    00149    return data_size;
    00150 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 386 of file format_au.c.

    00387 {
    00388    return desc;
    00389 }

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 391 of file format_au.c.

References ASTERISK_GPL_KEY.

    00392 {
    00393    return ASTERISK_GPL_KEY;
    00394 }

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 362 of file format_au.c.

References ast_format_register(), AST_FORMAT_ULAW, au_close(), au_getcomment(), au_open(), au_read(), au_rewrite(), au_seek(), au_tell(), au_trunc(), and au_write().

    00363 {
    00364    return ast_format_register(name, exts, AST_FORMAT_ULAW,
    00365                au_open,
    00366                au_rewrite,
    00367                au_write,
    00368                au_seek,
    00369                au_trunc,
    00370                au_tell,
    00371                au_read,
    00372                au_close,
    00373                au_getcomment);
    00374 }

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 376 of file format_au.c.

References ast_format_unregister().

    00377 {
    00378    return ast_format_unregister(name);
    00379 }

static int update_header | ( | FILE * | f | ) | `[static]`

Definition at line 152 of file format_au.c.

References ast_log(), AU_HDR_DATA_SIZE_OFF, AU_HEADER_SIZE, ast_frame::datalen, htoll, and LOG_WARNING.

Referenced by au_trunc(), au_write(), wav_trunc(), and wav_write().

    00153 {
    00154    off_t cur, end;
    00155    u_int32_t datalen;
    00156    int bytes;
    00157
    00158    cur = ftell(f);
    00159    fseek(f, 0, SEEK_END);
    00160    end = ftell(f);
    00161    /* data starts 24 bytes in */
    00162    bytes = end - AU_HEADER_SIZE;
    00163    datalen = htoll(bytes);
    00164
    00165    if (cur < 0) {
    00166       ast_log(LOG_WARNING, "Unable to find our position\n");
    00167       return -1;
    00168    }
    00169    if (fseek(f, AU_HDR_DATA_SIZE_OFF * sizeof(u_int32_t), SEEK_SET)) {
    00170       ast_log(LOG_WARNING, "Unable to set our position\n");
    00171       return -1;
    00172    }
    00173    if (fwrite(&datalen, 1, sizeof(datalen), f) != sizeof(datalen)) {
    00174       ast_log(LOG_WARNING, "Unable to set write file size\n");
    00175       return -1;
    00176    }
    00177    if (fseek(f, cur, SEEK_SET)) {
    00178       ast_log(LOG_WARNING, "Unable to return to position\n");
    00179       return -1;
    00180    }
    00181    return 0;
    00182 }

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 381 of file format_au.c.

    00382 {
    00383    return localusecnt;
    00384 }

static int write_header | ( | FILE * | f | ) | `[static]`

Definition at line 184 of file format_au.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, htoll, and LOG_WARNING.

Referenced by au_rewrite(), and wav_rewrite().

    00185 {
    00186    AU_HEADER(header);
    00187
    00188    header[AU_HDR_MAGIC_OFF] = htoll((u_int32_t) AU_MAGIC);
    00189    header[AU_HDR_HDR_SIZE_OFF] = htoll(AU_HEADER_SIZE);
    00190    header[AU_HDR_DATA_SIZE_OFF] = 0;
    00191    header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW);
    00192    header[AU_HDR_SAMPLE_RATE_OFF] = htoll(8000);
    00193    header[AU_HDR_CHANNELS_OFF] = htoll(1);
    00194
    00195    /* Write an au header, ignoring sizes which will be filled in later */
    00196    fseek(f, 0, SEEK_SET);
    00197    if (fwrite(header, 1, AU_HEADER_SIZE, f) != AU_HEADER_SIZE) {
    00198       ast_log(LOG_WARNING, "Unable to write header\n");
    00199       return -1;
    00200    }
    00201    return 0;
    00202 }

## Variable Documentation

char* desc = "Sun Microsystems AU format (signed linear)"`[static]`

Definition at line 77 of file format_au.c.

char* exts = "au"`[static]`

Definition at line 78 of file format_au.c.

int localusecnt = 0`[static]`

Definition at line 74 of file format_au.c.

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

Definition at line 76 of file format_au.c.