Mon Mar 20 08:25:59 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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"

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)
void au_close (struct ast_filestream *s)
char * au_getcomment (struct ast_filestream *s)
ast_filestreamau_open (FILE *f)
ast_frameau_read (struct ast_filestream *s, int *whennext)
ast_filestreamau_rewrite (FILE *f, const char *comment)
int au_seek (struct ast_filestream *fs, long sample_offset, int whence)
long au_tell (struct ast_filestream *fs)
int au_trunc (struct ast_filestream *fs)
int au_write (struct ast_filestream *fs, struct ast_frame *f)
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.
int update_header (FILE *f)
int usecount ()
 Provides a usecount.
int write_header (FILE *f)

Variables

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


Detailed Description

Work with Sun Microsystems AU format.

signed linear

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().

#define AU_HDR_DATA_SIZE_OFF   2
 

Definition at line 54 of file format_au.c.

Referenced by update_header().

#define AU_HDR_ENCODING_OFF   3
 

Definition at line 55 of file format_au.c.

Referenced by check_header().

#define AU_HDR_HDR_SIZE_OFF   1
 

Definition at line 53 of file format_au.c.

#define AU_HDR_MAGIC_OFF   0
 

Definition at line 52 of file format_au.c.

Referenced by check_header().

#define AU_HDR_SAMPLE_RATE_OFF   4
 

Definition at line 56 of file format_au.c.

Referenced by check_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 check_header(), and write_header().

#define AU_MAGIC   0x2e736e64
 

Definition at line 81 of file format_au.c.

Referenced by 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)
 

Definition at line 83 of file format_au.c.

Referenced by update_header(), and write_header().

#define htols  )     (b)
 

Definition at line 84 of file format_au.c.

Referenced by write_header().

#define ltohl  )     (b)
 

Definition at line 85 of file format_au.c.

Referenced by check_header().

#define ltohs  )     (b)
 

Definition at line 86 of file format_au.c.

Referenced by check_header().


Function Documentation

AST_MUTEX_DEFINE_STATIC au_lock   ) 
 

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, localusecnt, LOG_WARNING, and s.

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 }

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 }

struct ast_filestream* au_open FILE *  f  )  [static]
 

Definition at line 204 of file format_au.c.

References 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, localusecnt, 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 }

struct ast_frame* au_read struct ast_filestream s,
int *  whennext
[static]
 

Definition at line 275 of file format_au.c.

References 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, s, 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 }

struct ast_filestream* au_rewrite FILE *  f,
const char *  comment
[static]
 

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, localusecnt, 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 }

int au_seek struct ast_filestream fs,
long  sample_offset,
int  whence
[static]
 

Definition at line 318 of file format_au.c.

References ast_filestream::f.

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 }

long au_tell struct ast_filestream fs  )  [static]
 

Definition at line 349 of file format_au.c.

References ast_filestream::f.

Referenced by load_module().

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

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 }

int au_write struct ast_filestream fs,
struct ast_frame f
[static]
 

Definition at line 298 of file format_au.c.

References 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 }

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, LOG_WARNING, and ltohl.

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.

00392 {
00393    return ASTERISK_GPL_KEY;
00394 }

int load_module void   ) 
 

Initialize the module.

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.

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(), au_write(), exts, and name.

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(), and name.

00377 {
00378    return ast_format_unregister(name);
00379 }

int update_header FILE *  f  )  [static]
 

Definition at line 152 of file format_au.c.

References ast_log(), AU_HDR_DATA_SIZE_OFF, htoll, and LOG_WARNING.

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 }

int write_header FILE *  f  )  [static]
 

Definition at line 184 of file format_au.c.

References ast_log(), AU_ENC_8BIT_ULAW, AU_HEADER, AU_HEADER_SIZE, AU_MAGIC, htoll, and LOG_WARNING.

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.

Referenced by load_module().

int localusecnt = 0 [static]
 

Definition at line 74 of file format_au.c.

Referenced by au_close(), au_open(), and au_rewrite().

char* name = "au" [static]
 

Definition at line 76 of file format_au.c.


Generated on Mon Mar 20 08:25:59 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1