#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" |
signed linear
Definition in file format_au.c.
#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 |
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 |
#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) |
#define htols | ( | b | ) | (b) |
#define ltohl | ( | b | ) | (b) |
#define ltohs | ( | b | ) | (b) |
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(), free, 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 }
static char* au_getcomment | ( | struct ast_filestream * | s | ) | [static] |
static struct ast_filestream* au_open | ( | FILE * | f | ) | [static] |
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] |
Definition at line 275 of file format_au.c.
References AST_FORMAT_ULAW, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), BUF_SIZE, LOG_WARNING, and s.
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] |
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.
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; }
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.
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.
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).
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.
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 }
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.