Lines 42-50
Link Here
|
42 |
|
42 |
|
43 |
/* Portions of the conversion code are by guido@sienanet.it */ |
43 |
/* Portions of the conversion code are by guido@sienanet.it */ |
44 |
|
44 |
|
45 |
#define BUF_SIZE 20 /* two G729 frames */ |
45 |
#define G729A_FRAME_SIZE 10 |
|
|
46 |
#define BUF_SIZE (G729A_FRAME_SIZE * 2) /* two G729 frames */ |
47 |
#define G729A_CNG_SIZE 2 |
46 |
#define G729A_SAMPLES 160 |
48 |
#define G729A_SAMPLES 160 |
47 |
|
49 |
|
|
|
50 |
struct ast_g729_pvt |
51 |
{ |
52 |
int detected_vad; /* simple flag indicating whether or not we detected and reported on VAD on this stream yet or not */ |
53 |
}; |
54 |
|
48 |
static struct ast_frame *g729_read(struct ast_filestream *s, int *whennext) |
55 |
static struct ast_frame *g729_read(struct ast_filestream *s, int *whennext) |
49 |
{ |
56 |
{ |
50 |
int res; |
57 |
int res; |
Lines 55-61
Link Here
|
55 |
s->fr.samples = G729A_SAMPLES; |
62 |
s->fr.samples = G729A_SAMPLES; |
56 |
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE); |
63 |
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE); |
57 |
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) { |
64 |
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) { |
58 |
if (res && (res != 10)) /* XXX what for ? */ |
65 |
if (res && (res != G729A_FRAME_SIZE)) /* XXX what for ? */ |
59 |
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); |
66 |
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); |
60 |
return NULL; |
67 |
return NULL; |
61 |
} |
68 |
} |
Lines 65-71
Link Here
|
65 |
|
72 |
|
66 |
static int g729_write(struct ast_filestream *fs, struct ast_frame *f) |
73 |
static int g729_write(struct ast_filestream *fs, struct ast_frame *f) |
67 |
{ |
74 |
{ |
68 |
int res; |
75 |
struct ast_g729_pvt* pvt = fs->_private; |
|
|
76 |
int res, writelen = f->datalen; |
69 |
if (f->frametype != AST_FRAME_VOICE) { |
77 |
if (f->frametype != AST_FRAME_VOICE) { |
70 |
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); |
78 |
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); |
71 |
return -1; |
79 |
return -1; |
Lines 74-85
Link Here
|
74 |
ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(&f->subclass.format)); |
82 |
ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(&f->subclass.format)); |
75 |
return -1; |
83 |
return -1; |
76 |
} |
84 |
} |
77 |
if (f->datalen % 10) { |
85 |
if (f->datalen % G729A_FRAME_SIZE) { |
78 |
ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 10\n", f->datalen); |
86 |
if (f->datalen % G729A_FRAME_SIZE == G729A_CNG_SIZE) { |
|
|
87 |
writelen -= G729A_CNG_SIZE; |
88 |
if (!pvt->detected_vad) { |
89 |
ast_log(LOG_WARNING, "Probable CNG parameter update detected, this is a bug in the sender who should not be sending CNG updates - try and switch off Voice Activity Detected (VAD) or Silence Supression on the sender."); |
90 |
pvt->detected_vad = 1; |
91 |
} |
92 |
} else { |
93 |
ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of %d\n", f->datalen, G729A_FRAME_SIZE); |
79 |
return -1; |
94 |
return -1; |
80 |
} |
95 |
} |
81 |
if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) { |
96 |
} |
82 |
ast_log(LOG_WARNING, "Bad write (%d/10): %s\n", res, strerror(errno)); |
97 |
if ((res = fwrite(f->data.ptr, 1, writelen, fs->f)) != writelen) { |
|
|
98 |
ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, writelen, strerror(errno)); |
83 |
return -1; |
99 |
return -1; |
84 |
} |
100 |
} |
85 |
return 0; |
101 |
return 0; |
Lines 143-148
Link Here
|
143 |
.tell = g729_tell, |
159 |
.tell = g729_tell, |
144 |
.read = g729_read, |
160 |
.read = g729_read, |
145 |
.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET, |
161 |
.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET, |
|
|
162 |
.desc_size = sizeof(struct ast_g729_pvt), |
146 |
}; |
163 |
}; |
147 |
|
164 |
|
148 |
static int load_module(void) |
165 |
static int load_module(void) |