#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.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/alaw.h"
Include dependency graph for format_pcm_alaw.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 | alaw_silence [BUF_SIZE] |
static char * | desc = "Raw aLaw 8khz PCM Audio support" |
static char * | exts = "alaw|al" |
static int | glistcnt = 0 |
static char * | name = "alaw" |
Definition in file format_pcm_alaw.c.
|
Definition at line 50 of file format_pcm_alaw.c. |
|
|
|
Provides a description of the module.
Definition at line 343 of file format_pcm_alaw.c. 00344 { 00345 return desc; 00346 }
|
|
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 349 of file format_pcm_alaw.c. References ASTERISK_GPL_KEY. 00350 { 00351 return ASTERISK_GPL_KEY; 00352 }
|
|
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 314 of file format_pcm_alaw.c. References AST_FORMAT_ALAW, ast_format_register(), AST_LIN2A, pcm_close(), pcm_getcomment(), pcm_open(), pcm_read(), pcm_rewrite(), pcm_seek(), pcm_tell(), pcm_trunc(), and pcm_write(). 00315 { 00316 int index; 00317 00318 for (index = 0; index < (sizeof(alaw_silence) / sizeof(alaw_silence[0])); index++) 00319 alaw_silence[index] = AST_LIN2A(0); 00320 00321 return ast_format_register(name, exts, AST_FORMAT_ALAW, 00322 pcm_open, 00323 pcm_rewrite, 00324 pcm_write, 00325 pcm_seek, 00326 pcm_trunc, 00327 pcm_tell, 00328 pcm_read, 00329 pcm_close, 00330 pcm_getcomment); 00331 }
|
|
Definition at line 152 of file format_pcm_alaw.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), free, LOG_WARNING, and s. 00153 { 00154 if (ast_mutex_lock(&pcm_lock)) { 00155 ast_log(LOG_WARNING, "Unable to lock pcm list\n"); 00156 return; 00157 } 00158 glistcnt--; 00159 ast_mutex_unlock(&pcm_lock); 00160 ast_update_use_count(); 00161 fclose(s->f); 00162 free(s); 00163 s = NULL; 00164 }
|
|
Definition at line 309 of file format_pcm_alaw.c.
|
|
Definition at line 97 of file format_pcm_alaw.c. References AST_FORMAT_ALAW, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), free, LOG_WARNING, and malloc. 00098 { 00099 /* We don't have any header to read or anything really, but 00100 if we did, it would go here. We also might want to check 00101 and be sure it's a valid file. */ 00102 struct ast_filestream *tmp; 00103 if ((tmp = malloc(sizeof(struct ast_filestream)))) { 00104 memset(tmp, 0, sizeof(struct ast_filestream)); 00105 if (ast_mutex_lock(&pcm_lock)) { 00106 ast_log(LOG_WARNING, "Unable to lock pcm list\n"); 00107 free(tmp); 00108 return NULL; 00109 } 00110 tmp->f = f; 00111 tmp->fr.data = tmp->buf; 00112 tmp->fr.frametype = AST_FRAME_VOICE; 00113 tmp->fr.subclass = AST_FORMAT_ALAW; 00114 /* datalen will vary for each frame */ 00115 tmp->fr.src = name; 00116 tmp->fr.mallocd = 0; 00117 #ifdef REALTIME_WRITE 00118 tmp->start_time = get_time(); 00119 #endif 00120 glistcnt++; 00121 ast_mutex_unlock(&pcm_lock); 00122 ast_update_use_count(); 00123 } 00124 return tmp; 00125 }
|
|
Definition at line 166 of file format_pcm_alaw.c. References AST_FORMAT_ALAW, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), BUF_SIZE, LOG_WARNING, and s. 00167 { 00168 int res; 00169 /* Send a frame from the file to the appropriate channel */ 00170 00171 s->fr.frametype = AST_FRAME_VOICE; 00172 s->fr.subclass = AST_FORMAT_ALAW; 00173 s->fr.offset = AST_FRIENDLY_OFFSET; 00174 s->fr.mallocd = 0; 00175 s->fr.data = s->buf; 00176 if ((res = fread(s->buf, 1, BUF_SIZE, s->f)) < 1) { 00177 if (res) 00178 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); 00179 return NULL; 00180 } 00181 s->fr.samples = res; 00182 s->fr.datalen = res; 00183 *whennext = s->fr.samples; 00184 return &s->fr; 00185 }
|
|
Definition at line 127 of file format_pcm_alaw.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), free, LOG_WARNING, and malloc. 00128 { 00129 /* We don't have any header to read or anything really, but 00130 if we did, it would go here. We also might want to check 00131 and be sure it's a valid file. */ 00132 struct ast_filestream *tmp; 00133 if ((tmp = malloc(sizeof(struct ast_filestream)))) { 00134 memset(tmp, 0, sizeof(struct ast_filestream)); 00135 if (ast_mutex_lock(&pcm_lock)) { 00136 ast_log(LOG_WARNING, "Unable to lock pcm list\n"); 00137 free(tmp); 00138 return NULL; 00139 } 00140 tmp->f = f; 00141 #ifdef REALTIME_WRITE 00142 tmp->start_time = get_time(); 00143 #endif 00144 glistcnt++; 00145 ast_mutex_unlock(&pcm_lock); 00146 ast_update_use_count(); 00147 } else 00148 ast_log(LOG_WARNING, "Out of memory\n"); 00149 return tmp; 00150 }
|
|
Definition at line 252 of file format_pcm_alaw.c. References BUF_SIZE, ast_filestream::f, offset, and SEEK_FORCECUR. 00253 { 00254 long cur, max, offset = 0; 00255 00256 cur = ftell(fs->f); 00257 fseek(fs->f, 0, SEEK_END); 00258 max = ftell(fs->f); 00259 00260 switch (whence) { 00261 case SEEK_SET: 00262 offset = sample_offset; 00263 break; 00264 case SEEK_END: 00265 offset = max - sample_offset; 00266 break; 00267 case SEEK_CUR: 00268 case SEEK_FORCECUR: 00269 offset = cur + sample_offset; 00270 break; 00271 } 00272 00273 switch (whence) { 00274 case SEEK_FORCECUR: 00275 if (offset > max) { 00276 size_t left = offset - max; 00277 size_t res; 00278 00279 while (left) { 00280 res = fwrite(alaw_silence, sizeof(alaw_silence[0]), 00281 (left > BUF_SIZE) ? BUF_SIZE : left, fs->f); 00282 if (res == -1) 00283 return res; 00284 left -= res * sizeof(alaw_silence[0]); 00285 } 00286 return offset; 00287 } 00288 /* fall through */ 00289 default: 00290 offset = (offset > max) ? max : offset; 00291 offset = (offset < 0) ? 0 : offset; 00292 return fseek(fs->f, offset, SEEK_SET); 00293 } 00294 }
|
|
Definition at line 301 of file format_pcm_alaw.c. References ast_filestream::f, and offset.
|
|
Definition at line 296 of file format_pcm_alaw.c. References ast_filestream::f.
|
|
Definition at line 187 of file format_pcm_alaw.c. References AST_FORMAT_ALAW, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_filestream::f, ast_frame::frametype, LOG_WARNING, s, and ast_frame::subclass. 00188 { 00189 int res; 00190 #ifdef REALTIME_WRITE 00191 unsigned long cur_time; 00192 unsigned long fpos; 00193 struct stat stat_buf; 00194 #endif 00195 00196 if (f->frametype != AST_FRAME_VOICE) { 00197 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); 00198 return -1; 00199 } 00200 if (f->subclass != AST_FORMAT_ALAW) { 00201 ast_log(LOG_WARNING, "Asked to write non-alaw frame (%d)!\n", f->subclass); 00202 return -1; 00203 } 00204 00205 #ifdef REALTIME_WRITE 00206 cur_time = get_time(); 00207 fpos = ( cur_time - fs->start_time ) * 8; /* 8 bytes per msec */ 00208 /* Check if we have written to this position yet. If we have, then increment pos by one frame 00209 * for some degree of protection against receiving packets in the same clock tick. 00210 */ 00211 00212 fstat(fileno(fs->f), &stat_buf ); 00213 if (stat_buf.st_size > fpos ) { 00214 fpos += f->datalen; /* Incrementing with the size of this current frame */ 00215 } 00216 00217 if (stat_buf.st_size < fpos) { 00218 /* fill the gap with 0x55 rather than 0. */ 00219 char buf[ 512 ]; 00220 unsigned long cur, to_write; 00221 00222 cur = stat_buf.st_size; 00223 if (fseek(fs->f, cur, SEEK_SET) < 0) { 00224 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); 00225 return -1; 00226 } 00227 memset(buf, 0x55, 512); 00228 while (cur < fpos) { 00229 to_write = fpos - cur; 00230 if (to_write > 512) { 00231 to_write = 512; 00232 } 00233 fwrite(buf, 1, to_write, fs->f); 00234 cur += to_write; 00235 } 00236 } 00237 00238 00239 if (fseek(s->f, fpos, SEEK_SET) < 0) { 00240 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); 00241 return -1; 00242 } 00243 #endif /* REALTIME_WRITE */ 00244 00245 if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) { 00246 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno)); 00247 return -1; 00248 } 00249 return 0; 00250 }
|
|
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 333 of file format_pcm_alaw.c. References ast_format_unregister(). 00334 { 00335 return ast_format_unregister(name); 00336 }
|
|
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 338 of file format_pcm_alaw.c. 00339 { 00340 return glistcnt; 00341 }
|
|
Definition at line 77 of file format_pcm_alaw.c. |
|
Definition at line 74 of file format_pcm_alaw.c. |
|
Definition at line 75 of file format_pcm_alaw.c. |
|
Definition at line 71 of file format_pcm_alaw.c. |
|
Definition at line 73 of file format_pcm_alaw.c. |