#include "asterisk.h"
#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/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 "msgsm.h"
Go to the source code of this file.
Data Structures | |
struct | wavg_desc |
Defines | |
#define | GSM_FRAME_SIZE 33 |
#define | GSM_SAMPLES 160 |
#define | htoll(b) (b) |
#define | htols(b) (b) |
#define | ltohl(b) (b) |
#define | ltohs(b) (b) |
#define | MSGSM_DATA_OFFSET 60 |
#define | MSGSM_FRAME_SIZE 65 |
#define | MSGSM_SAMPLES (2*GSM_SAMPLES) |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | check_header (FILE *f) |
static int | load_module (void) |
static int | unload_module (void) |
static int | update_header (FILE *f) |
static int | wav_open (struct ast_filestream *s) |
static struct ast_frame * | wav_read (struct ast_filestream *s, int *whennext) |
static int | wav_rewrite (struct ast_filestream *s, const char *comment) |
static int | wav_seek (struct ast_filestream *fs, off_t sample_offset, int whence) |
static off_t | wav_tell (struct ast_filestream *fs) |
static int | wav_trunc (struct ast_filestream *fs) |
static int | wav_write (struct ast_filestream *s, struct ast_frame *f) |
static int | write_header (FILE *f) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_FIRST | AST_MODFLAG_BUILDSUM, .description = "Microsoft WAV format (Proprietary GSM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
char | msgsm_silence [] |
static struct ast_format | wav49_f |
Microsoft WAV format (Proprietary GSM)
Definition in file format_wav_gsm.c.
#define GSM_FRAME_SIZE 33 |
Definition at line 57 of file format_wav_gsm.c.
#define GSM_SAMPLES 160 |
Definition at line 60 of file format_wav_gsm.c.
#define htoll | ( | b | ) | (b) |
Definition at line 79 of file format_wav_gsm.c.
#define htols | ( | b | ) | (b) |
Definition at line 80 of file format_wav_gsm.c.
#define ltohl | ( | b | ) | (b) |
Definition at line 81 of file format_wav_gsm.c.
#define ltohs | ( | b | ) | (b) |
Definition at line 82 of file format_wav_gsm.c.
#define MSGSM_DATA_OFFSET 60 |
Definition at line 59 of file format_wav_gsm.c.
Referenced by update_header(), wav_seek(), and wav_tell().
#define MSGSM_FRAME_SIZE 65 |
Definition at line 58 of file format_wav_gsm.c.
Referenced by update_header(), wav_read(), wav_seek(), wav_tell(), wav_write(), and write_header().
#define MSGSM_SAMPLES (2*GSM_SAMPLES) |
Definition at line 61 of file format_wav_gsm.c.
Referenced by update_header(), wav_seek(), wav_tell(), and write_header().
static void __reg_module | ( | void | ) | [static] |
Definition at line 565 of file format_wav_gsm.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 565 of file format_wav_gsm.c.
static int check_header | ( | FILE * | f | ) | [static] |
Definition at line 101 of file format_wav_gsm.c.
References ast_log(), DEFAULT_SAMPLE_RATE, format, LOG_WARNING, ltohl, ltohs, and type.
00102 { 00103 int type, size, formtype; 00104 int fmt, hsize, fact; 00105 short format, chans; 00106 int freq; 00107 int data; 00108 if (fread(&type, 1, 4, f) != 4) { 00109 ast_log(LOG_WARNING, "Read failed (type)\n"); 00110 return -1; 00111 } 00112 if (fread(&size, 1, 4, f) != 4) { 00113 ast_log(LOG_WARNING, "Read failed (size)\n"); 00114 return -1; 00115 } 00116 size = ltohl(size); 00117 if (fread(&formtype, 1, 4, f) != 4) { 00118 ast_log(LOG_WARNING, "Read failed (formtype)\n"); 00119 return -1; 00120 } 00121 if (memcmp(&type, "RIFF", 4)) { 00122 ast_log(LOG_WARNING, "Does not begin with RIFF\n"); 00123 return -1; 00124 } 00125 if (memcmp(&formtype, "WAVE", 4)) { 00126 ast_log(LOG_WARNING, "Does not contain WAVE\n"); 00127 return -1; 00128 } 00129 if (fread(&fmt, 1, 4, f) != 4) { 00130 ast_log(LOG_WARNING, "Read failed (fmt)\n"); 00131 return -1; 00132 } 00133 if (memcmp(&fmt, "fmt ", 4)) { 00134 ast_log(LOG_WARNING, "Does not say fmt\n"); 00135 return -1; 00136 } 00137 if (fread(&hsize, 1, 4, f) != 4) { 00138 ast_log(LOG_WARNING, "Read failed (formtype)\n"); 00139 return -1; 00140 } 00141 if (ltohl(hsize) != 20) { 00142 ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize)); 00143 return -1; 00144 } 00145 if (fread(&format, 1, 2, f) != 2) { 00146 ast_log(LOG_WARNING, "Read failed (format)\n"); 00147 return -1; 00148 } 00149 if (ltohs(format) != 49) { 00150 ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format)); 00151 return -1; 00152 } 00153 if (fread(&chans, 1, 2, f) != 2) { 00154 ast_log(LOG_WARNING, "Read failed (format)\n"); 00155 return -1; 00156 } 00157 if (ltohs(chans) != 1) { 00158 ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans)); 00159 return -1; 00160 } 00161 if (fread(&freq, 1, 4, f) != 4) { 00162 ast_log(LOG_WARNING, "Read failed (freq)\n"); 00163 return -1; 00164 } 00165 if (ltohl(freq) != DEFAULT_SAMPLE_RATE) { 00166 ast_log(LOG_WARNING, "Unexpected frequency %d\n", ltohl(freq)); 00167 return -1; 00168 } 00169 /* Ignore the byte frequency */ 00170 if (fread(&freq, 1, 4, f) != 4) { 00171 ast_log(LOG_WARNING, "Read failed (X_1)\n"); 00172 return -1; 00173 } 00174 /* Ignore the two weird fields */ 00175 if (fread(&freq, 1, 4, f) != 4) { 00176 ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n"); 00177 return -1; 00178 } 00179 /* Ignore the byte frequency */ 00180 if (fread(&freq, 1, 4, f) != 4) { 00181 ast_log(LOG_WARNING, "Read failed (Y_1)\n"); 00182 return -1; 00183 } 00184 /* Check for the word fact */ 00185 if (fread(&fact, 1, 4, f) != 4) { 00186 ast_log(LOG_WARNING, "Read failed (fact)\n"); 00187 return -1; 00188 } 00189 if (memcmp(&fact, "fact", 4)) { 00190 ast_log(LOG_WARNING, "Does not say fact\n"); 00191 return -1; 00192 } 00193 /* Ignore the "fact value" */ 00194 if (fread(&fact, 1, 4, f) != 4) { 00195 ast_log(LOG_WARNING, "Read failed (fact header)\n"); 00196 return -1; 00197 } 00198 if (fread(&fact, 1, 4, f) != 4) { 00199 ast_log(LOG_WARNING, "Read failed (fact value)\n"); 00200 return -1; 00201 } 00202 /* Check for the word data */ 00203 if (fread(&data, 1, 4, f) != 4) { 00204 ast_log(LOG_WARNING, "Read failed (data)\n"); 00205 return -1; 00206 } 00207 if (memcmp(&data, "data", 4)) { 00208 ast_log(LOG_WARNING, "Does not say data\n"); 00209 return -1; 00210 } 00211 /* Ignore the data length */ 00212 if (fread(&data, 1, 4, f) != 4) { 00213 ast_log(LOG_WARNING, "Read failed (data)\n"); 00214 return -1; 00215 } 00216 return 0; 00217 }
static int load_module | ( | void | ) | [static] |
Definition at line 552 of file format_wav_gsm.c.
References ast_format_register, and wav49_f.
00553 { 00554 return ast_format_register(&wav49_f); 00555 }
static int unload_module | ( | void | ) | [static] |
Definition at line 557 of file format_wav_gsm.c.
References ast_format_unregister(), ast_format::name, and wav49_f.
00558 { 00559 return ast_format_unregister(wav49_f.name); 00560 }
static int update_header | ( | FILE * | f | ) | [static] |
Definition at line 219 of file format_wav_gsm.c.
References ast_log(), htoll, LOG_WARNING, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.
00220 { 00221 off_t cur,end,bytes; 00222 int datalen, filelen, samples; 00223 00224 cur = ftello(f); 00225 fseek(f, 0, SEEK_END); 00226 end = ftello(f); 00227 /* in a gsm WAV, data starts 60 bytes in */ 00228 bytes = end - MSGSM_DATA_OFFSET; 00229 samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES); 00230 datalen = htoll(bytes); 00231 filelen = htoll(MSGSM_DATA_OFFSET - 8 + bytes); 00232 if (cur < 0) { 00233 ast_log(LOG_WARNING, "Unable to find our position\n"); 00234 return -1; 00235 } 00236 if (fseek(f, 4, SEEK_SET)) { 00237 ast_log(LOG_WARNING, "Unable to set our position\n"); 00238 return -1; 00239 } 00240 if (fwrite(&filelen, 1, 4, f) != 4) { 00241 ast_log(LOG_WARNING, "Unable to write file size\n"); 00242 return -1; 00243 } 00244 if (fseek(f, 48, SEEK_SET)) { 00245 ast_log(LOG_WARNING, "Unable to set our position\n"); 00246 return -1; 00247 } 00248 if (fwrite(&samples, 1, 4, f) != 4) { 00249 ast_log(LOG_WARNING, "Unable to write samples\n"); 00250 return -1; 00251 } 00252 if (fseek(f, 56, SEEK_SET)) { 00253 ast_log(LOG_WARNING, "Unable to set our position\n"); 00254 return -1; 00255 } 00256 if (fwrite(&datalen, 1, 4, f) != 4) { 00257 ast_log(LOG_WARNING, "Unable to write datalen\n"); 00258 return -1; 00259 } 00260 if (fseeko(f, cur, SEEK_SET)) { 00261 ast_log(LOG_WARNING, "Unable to return to position\n"); 00262 return -1; 00263 } 00264 return 0; 00265 }
static int wav_open | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 381 of file format_wav_gsm.c.
References check_header(), s, and wavg_desc::secondhalf.
00382 { 00383 /* We don't have any header to read or anything really, but 00384 if we did, it would go here. We also might want to check 00385 and be sure it's a valid file. */ 00386 struct wavg_desc *fs = (struct wavg_desc *)s->_private; 00387 00388 if (check_header(s->f)) 00389 return -1; 00390 fs->secondhalf = 0; /* not strictly necessary */ 00391 return 0; 00392 }
static struct ast_frame* wav_read | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 405 of file format_wav_gsm.c.
References AST_FORMAT_GSM, AST_FRAME_SET_BUFFER, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), conv65(), errno, GSM_FRAME_SIZE, GSM_SAMPLES, LOG_WARNING, MSGSM_FRAME_SIZE, s, and wavg_desc::secondhalf.
00406 { 00407 /* Send a frame from the file to the appropriate channel */ 00408 struct wavg_desc *fs = (struct wavg_desc *)s->_private; 00409 00410 s->fr.frametype = AST_FRAME_VOICE; 00411 s->fr.subclass = AST_FORMAT_GSM; 00412 s->fr.offset = AST_FRIENDLY_OFFSET; 00413 s->fr.samples = GSM_SAMPLES; 00414 s->fr.mallocd = 0; 00415 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE); 00416 if (fs->secondhalf) { 00417 /* Just return a frame based on the second GSM frame */ 00418 s->fr.data = (char *)s->fr.data + GSM_FRAME_SIZE; 00419 s->fr.offset += GSM_FRAME_SIZE; 00420 } else { 00421 /* read and convert */ 00422 unsigned char msdata[MSGSM_FRAME_SIZE]; 00423 int res; 00424 00425 if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) { 00426 if (res && (res != 1)) 00427 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); 00428 return NULL; 00429 } 00430 /* Convert from MS format to two real GSM frames */ 00431 conv65(msdata, s->fr.data); 00432 } 00433 fs->secondhalf = !fs->secondhalf; 00434 *whennext = GSM_SAMPLES; 00435 return &s->fr; 00436 }
static int wav_rewrite | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 394 of file format_wav_gsm.c.
References s, and write_header().
00395 { 00396 /* We don't have any header to read or anything really, but 00397 if we did, it would go here. We also might want to check 00398 and be sure it's a valid file. */ 00399 00400 if (write_header(s->f)) 00401 return -1; 00402 return 0; 00403 }
static int wav_seek | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) | [static] |
Definition at line 485 of file format_wav_gsm.c.
References ast_filestream::_private, ast_log(), errno, ast_filestream::f, LOG_WARNING, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, MSGSM_SAMPLES, msgsm_silence, offset, s, and SEEK_FORCECUR.
00486 { 00487 off_t offset=0, distance, max; 00488 struct wavg_desc *s = (struct wavg_desc *)fs->_private; 00489 00490 off_t min = MSGSM_DATA_OFFSET; 00491 off_t cur = ftello(fs->f); 00492 fseek(fs->f, 0, SEEK_END); 00493 max = ftello(fs->f); /* XXX ideally, should round correctly */ 00494 /* Compute the distance in bytes, rounded to the block size */ 00495 distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE; 00496 if (whence == SEEK_SET) 00497 offset = distance + min; 00498 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) 00499 offset = distance + cur; 00500 else if (whence == SEEK_END) 00501 offset = max - distance; 00502 /* always protect against seeking past end of header */ 00503 if (offset < min) 00504 offset = min; 00505 if (whence != SEEK_FORCECUR) { 00506 if (offset > max) 00507 offset = max; 00508 } else if (offset > max) { 00509 int i; 00510 fseek(fs->f, 0, SEEK_END); 00511 for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) { 00512 if (!fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f)) { 00513 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno)); 00514 } 00515 } 00516 } 00517 s->secondhalf = 0; 00518 return fseeko(fs->f, offset, SEEK_SET); 00519 }
static off_t wav_tell | ( | struct ast_filestream * | fs | ) | [static] |
Definition at line 528 of file format_wav_gsm.c.
References ast_filestream::f, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, MSGSM_SAMPLES, and offset.
00529 { 00530 off_t offset; 00531 offset = ftello(fs->f); 00532 /* since this will most likely be used later in play or record, lets stick 00533 * to that level of resolution, just even frames boundaries */ 00534 return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES; 00535 }
static int wav_trunc | ( | struct ast_filestream * | fs | ) | [static] |
Definition at line 521 of file format_wav_gsm.c.
References ast_filestream::f, and update_header().
00522 { 00523 if (ftruncate(fileno(fs->f), ftello(fs->f))) 00524 return -1; 00525 return update_header(fs->f); 00526 }
static int wav_write | ( | struct ast_filestream * | s, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 438 of file format_wav_gsm.c.
References AST_FORMAT_GSM, AST_FRAME_VOICE, ast_log(), conv66(), errno, f, GSM_FRAME_SIZE, len(), LOG_WARNING, MSGSM_FRAME_SIZE, s, and wavg_desc::secondhalf.
00439 { 00440 int len; 00441 int size; 00442 struct wavg_desc *fs = (struct wavg_desc *)s->_private; 00443 00444 if (f->frametype != AST_FRAME_VOICE) { 00445 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); 00446 return -1; 00447 } 00448 if (f->subclass != AST_FORMAT_GSM) { 00449 ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass); 00450 return -1; 00451 } 00452 /* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE 00453 * we assume it is already in the correct format. 00454 */ 00455 if (!(f->datalen % MSGSM_FRAME_SIZE)) { 00456 size = MSGSM_FRAME_SIZE; 00457 fs->secondhalf = 0; 00458 } else { 00459 size = GSM_FRAME_SIZE; 00460 } 00461 for (len = 0; len < f->datalen ; len += size) { 00462 int res; 00463 unsigned char *src, msdata[MSGSM_FRAME_SIZE]; 00464 if (fs->secondhalf) { /* second half of raw gsm to be converted */ 00465 memcpy(s->buf + GSM_FRAME_SIZE, f->data + len, GSM_FRAME_SIZE); 00466 conv66((unsigned char *) s->buf, msdata); 00467 src = msdata; 00468 fs->secondhalf = 0; 00469 } else if (size == GSM_FRAME_SIZE) { /* first half of raw gsm */ 00470 memcpy(s->buf, f->data + len, GSM_FRAME_SIZE); 00471 src = NULL; /* nothing to write */ 00472 fs->secondhalf = 1; 00473 } else { /* raw msgsm data */ 00474 src = f->data + len; 00475 } 00476 if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) { 00477 ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno)); 00478 return -1; 00479 } 00480 update_header(s->f); /* XXX inefficient! */ 00481 } 00482 return 0; 00483 }
static int write_header | ( | FILE * | f | ) | [static] |
Definition at line 267 of file format_wav_gsm.c.
References ast_log(), htoll, htols, LOG_WARNING, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.
00268 { 00269 /* Samples per second (always 8000 for this format). */ 00270 unsigned int sample_rate = htoll(8000); 00271 /* Bytes per second (always 1625 for this format). */ 00272 unsigned int byte_sample_rate = htoll(1625); 00273 /* This is the size of the "fmt " subchunk */ 00274 unsigned int fmtsize = htoll(20); 00275 /* WAV #49 */ 00276 unsigned short fmt = htols(49); 00277 /* Mono = 1 channel */ 00278 unsigned short chans = htols(1); 00279 /* Each block of data is exactly 65 bytes in size. */ 00280 unsigned int block_align = htoll(MSGSM_FRAME_SIZE); 00281 /* Not actually 2, but rounded up to the nearest bit */ 00282 unsigned short bits_per_sample = htols(2); 00283 /* Needed for compressed formats */ 00284 unsigned short extra_format = htols(MSGSM_SAMPLES); 00285 /* This is the size of the "fact" subchunk */ 00286 unsigned int factsize = htoll(4); 00287 /* Number of samples in the data chunk */ 00288 unsigned int num_samples = htoll(0); 00289 /* Number of bytes in the data chunk */ 00290 unsigned int size = htoll(0); 00291 /* Write a GSM header, ignoring sizes which will be filled in later */ 00292 00293 /* 0: Chunk ID */ 00294 if (fwrite("RIFF", 1, 4, f) != 4) { 00295 ast_log(LOG_WARNING, "Unable to write header\n"); 00296 return -1; 00297 } 00298 /* 4: Chunk Size */ 00299 if (fwrite(&size, 1, 4, f) != 4) { 00300 ast_log(LOG_WARNING, "Unable to write header\n"); 00301 return -1; 00302 } 00303 /* 8: Chunk Format */ 00304 if (fwrite("WAVE", 1, 4, f) != 4) { 00305 ast_log(LOG_WARNING, "Unable to write header\n"); 00306 return -1; 00307 } 00308 /* 12: Subchunk 1: ID */ 00309 if (fwrite("fmt ", 1, 4, f) != 4) { 00310 ast_log(LOG_WARNING, "Unable to write header\n"); 00311 return -1; 00312 } 00313 /* 16: Subchunk 1: Size (minus 8) */ 00314 if (fwrite(&fmtsize, 1, 4, f) != 4) { 00315 ast_log(LOG_WARNING, "Unable to write header\n"); 00316 return -1; 00317 } 00318 /* 20: Subchunk 1: Audio format (49) */ 00319 if (fwrite(&fmt, 1, 2, f) != 2) { 00320 ast_log(LOG_WARNING, "Unable to write header\n"); 00321 return -1; 00322 } 00323 /* 22: Subchunk 1: Number of channels */ 00324 if (fwrite(&chans, 1, 2, f) != 2) { 00325 ast_log(LOG_WARNING, "Unable to write header\n"); 00326 return -1; 00327 } 00328 /* 24: Subchunk 1: Sample rate */ 00329 if (fwrite(&sample_rate, 1, 4, f) != 4) { 00330 ast_log(LOG_WARNING, "Unable to write header\n"); 00331 return -1; 00332 } 00333 /* 28: Subchunk 1: Byte rate */ 00334 if (fwrite(&byte_sample_rate, 1, 4, f) != 4) { 00335 ast_log(LOG_WARNING, "Unable to write header\n"); 00336 return -1; 00337 } 00338 /* 32: Subchunk 1: Block align */ 00339 if (fwrite(&block_align, 1, 4, f) != 4) { 00340 ast_log(LOG_WARNING, "Unable to write header\n"); 00341 return -1; 00342 } 00343 /* 36: Subchunk 1: Bits per sample */ 00344 if (fwrite(&bits_per_sample, 1, 2, f) != 2) { 00345 ast_log(LOG_WARNING, "Unable to write header\n"); 00346 return -1; 00347 } 00348 /* 38: Subchunk 1: Extra format bytes */ 00349 if (fwrite(&extra_format, 1, 2, f) != 2) { 00350 ast_log(LOG_WARNING, "Unable to write header\n"); 00351 return -1; 00352 } 00353 /* 40: Subchunk 2: ID */ 00354 if (fwrite("fact", 1, 4, f) != 4) { 00355 ast_log(LOG_WARNING, "Unable to write header\n"); 00356 return -1; 00357 } 00358 /* 44: Subchunk 2: Size (minus 8) */ 00359 if (fwrite(&factsize, 1, 4, f) != 4) { 00360 ast_log(LOG_WARNING, "Unable to write header\n"); 00361 return -1; 00362 } 00363 /* 48: Subchunk 2: Number of samples */ 00364 if (fwrite(&num_samples, 1, 4, f) != 4) { 00365 ast_log(LOG_WARNING, "Unable to write header\n"); 00366 return -1; 00367 } 00368 /* 52: Subchunk 3: ID */ 00369 if (fwrite("data", 1, 4, f) != 4) { 00370 ast_log(LOG_WARNING, "Unable to write header\n"); 00371 return -1; 00372 } 00373 /* 56: Subchunk 3: Size */ 00374 if (fwrite(&size, 1, 4, f) != 4) { 00375 ast_log(LOG_WARNING, "Unable to write header\n"); 00376 return -1; 00377 } 00378 return 0; 00379 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_FIRST | AST_MODFLAG_BUILDSUM, .description = "Microsoft WAV format (Proprietary GSM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 565 of file format_wav_gsm.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 565 of file format_wav_gsm.c.
char msgsm_silence[] |
struct ast_format wav49_f [static] |