Add HD voice using G.722, Siren7, Siren14 and Slinear16. Add Slinear.
This commit is contained in:
parent
fc27be9222
commit
1d1fca7181
2
CHANGES
2
CHANGES
|
@ -17,6 +17,8 @@ HEAD
|
|||
- Use Diva streaming for NULL PLCI and for resource PLCI
|
||||
- Resolved http://www.ipphoneforum.eu/showthread.php?t=220051
|
||||
- Use Diva QSIG CAPI extensions for processing of Calling Party Name
|
||||
- Add Slinear
|
||||
- Add HD voice using G.722, Siren7, Siren14 and Slinear16
|
||||
|
||||
chan_capi-1.1.5
|
||||
------------------
|
||||
|
|
112
chan_capi.c
112
chan_capi.c
|
@ -1416,7 +1416,7 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
char calledsubaddress[AST_MAX_EXTENSION];
|
||||
int doqsig;
|
||||
char *sending_complete;
|
||||
unsigned char *facilityarray = NULL;
|
||||
unsigned char *facilityarray = NULL, *bc_s = NULL, *llc_s = 0, *hlc_s = 0;
|
||||
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
|
@ -1541,6 +1541,33 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
cip = tcap2cip(i->transfercapability);
|
||||
}
|
||||
|
||||
#if defined(AST_FORMAT_G722) || defined(AST_FORMAT_SIREN7) || defined(AST_FORMAT_SIREN14)
|
||||
if (capi_tcap_is_digital(i->transfercapability) == 0 && i->bproto == CC_BPROTO_VOCODER) {
|
||||
static unsigned char llc_s_template[] = { 0x04, 0x00, 0xc0, 0x90, 0xa5 };
|
||||
static unsigned char hlc_s_template[] = { 0x02, 0x91, 0x81 };
|
||||
switch(i->codec) {
|
||||
#if defined(AST_FORMAT_G722)
|
||||
case AST_FORMAT_G722:
|
||||
llc_s = llc_s_template;
|
||||
hlc_s = hlc_s_template;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN7)
|
||||
case AST_FORMAT_SIREN7:
|
||||
llc_s = llc_s_template;
|
||||
hlc_s = hlc_s_template;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN14)
|
||||
case AST_FORMAT_SIREN14:
|
||||
llc_s = llc_s_template;
|
||||
hlc_s = hlc_s_template;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (capi_tcap_is_digital(i->transfercapability)) {
|
||||
i->bproto = CC_BPROTO_TRANSPARENT;
|
||||
cc_verbose(4, 0, VERBOSE_PREFIX_2 "%s: is digital call, set proto to TRANSPARENT\n",
|
||||
|
@ -1585,7 +1612,7 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
#endif
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_CONNECT_REQ, i->controller, i->MessageNumber,
|
||||
"wssss(wwwsss())()()()((w)()()ss)",
|
||||
"wssss(wwwsss())sss((w)()()ss)",
|
||||
cip, /* CIP value */
|
||||
called, /* called party number */
|
||||
calling, /* calling party number */
|
||||
|
@ -1598,9 +1625,9 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
diva_get_b1_conf(i),
|
||||
b_protocol_table[i->bproto].b2configuration,
|
||||
b_protocol_table[i->bproto].b3configuration,
|
||||
/* BC */
|
||||
/* LLC */
|
||||
/* HLC */
|
||||
bc_s, /* BC */
|
||||
llc_s, /* LLC */
|
||||
hlc_s, /* HLC */
|
||||
/* Additional Info */
|
||||
0x0000, /* B channel info */
|
||||
/* Keypad facility */
|
||||
|
@ -1645,6 +1672,32 @@ static _cstruct diva_get_b1_conf (struct capi_pvt *i) {
|
|||
case AST_FORMAT_G729A:
|
||||
b1conf = (_cstruct)"\x06\x12\x04\x0f\x00\xa0\x00";
|
||||
break;
|
||||
#ifdef AST_FORMAT_G722
|
||||
case AST_FORMAT_G722:
|
||||
b1conf = (_cstruct)"\x06\x09\x04\x03\x00\xa0\x00";
|
||||
break;
|
||||
#endif
|
||||
#ifdef AST_FORMAT_SIREN7
|
||||
case AST_FORMAT_SIREN7:
|
||||
b1conf = (_cstruct)"\x06\x24\x04\x0f\x02\xa0\x00"; /* 32 kBit/s */
|
||||
break;
|
||||
#endif
|
||||
#ifdef AST_FORMAT_SIREN14
|
||||
case AST_FORMAT_SIREN14:
|
||||
b1conf = (_cstruct)"\x06\x24\x04\x0f\x07\xa0\x00"; /* 48 kBit/s */
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR)
|
||||
case AST_FORMAT_SLINEAR:
|
||||
b1conf = (_cstruct)"\x06\x01\x04\x0f\x01\xa0\x00";
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR16)
|
||||
case AST_FORMAT_SLINEAR16:
|
||||
b1conf = (_cstruct)"\x06\x01\x04\x0f\x05\xa0\x00";
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
cc_log(LOG_ERROR, "%s: format %s(%d) invalid.\n",
|
||||
i->vname, ast_getformatname(i->codec), i->codec);
|
||||
|
@ -1666,6 +1719,7 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
const char *connectednumber;
|
||||
unsigned char *facilityarray = NULL;
|
||||
_cstruct b1conf;
|
||||
unsigned char* llc_s = NULL;
|
||||
|
||||
if (i->state == CAPI_STATE_DISCONNECTED) {
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Not answering disconnected call.\n",
|
||||
|
@ -1710,8 +1764,31 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
capi_facility_add_datetime(facilityarray);
|
||||
}
|
||||
|
||||
#if defined(AST_FORMAT_G722) || defined(AST_FORMAT_SIREN7) || defined(AST_FORMAT_SIREN14)
|
||||
if (i->bproto == CC_BPROTO_VOCODER) {
|
||||
static unsigned char llc_s_template[] = { 0x03, 0x91, 0x90, 0xa5 };
|
||||
switch(i->codec) {
|
||||
#if defined(AST_FORMAT_G722)
|
||||
case AST_FORMAT_G722:
|
||||
llc_s = llc_s_template;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN7)
|
||||
case AST_FORMAT_SIREN7:
|
||||
llc_s = llc_s_template;
|
||||
break;
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN14)
|
||||
case AST_FORMAT_SIREN14:
|
||||
llc_s = llc_s_template;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (capi_sendf(NULL, 0, CAPI_CONNECT_RESP, i->PLCI, i->MessageNumber,
|
||||
"w(wwwssss)s()()(()()()s())",
|
||||
"w(wwwssss)s()s(()()()s())",
|
||||
0, /* accept call */
|
||||
/* B protocol */
|
||||
b_protocol_table[i->bproto].b1protocol,
|
||||
|
@ -1723,7 +1800,7 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
|
|||
capi_set_global_configuration(i),
|
||||
buf, /* connected number */
|
||||
/* connected subaddress */
|
||||
/* LLC */
|
||||
llc_s,/* LLC */
|
||||
/* Additional info */
|
||||
facilityarray
|
||||
) != 0) {
|
||||
|
@ -4333,6 +4410,25 @@ static void capidev_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, u
|
|||
}
|
||||
}
|
||||
|
||||
static int pbx_capi_get_samples (struct capi_pvt *i, int length) {
|
||||
switch (i->codec) {
|
||||
case AST_FORMAT_SLINEAR:
|
||||
case AST_FORMAT_SLINEAR16:
|
||||
return (length/2);
|
||||
|
||||
case AST_FORMAT_G722:
|
||||
return (length*2);
|
||||
|
||||
case AST_FORMAT_SIREN7:
|
||||
return (length * (320 / 80));
|
||||
|
||||
case AST_FORMAT_SIREN14:
|
||||
return ((typeof(length)) length * ((float) 640 / 120));
|
||||
}
|
||||
|
||||
return (length);
|
||||
}
|
||||
|
||||
/*
|
||||
* CAPI DATA_B3_IND
|
||||
*/
|
||||
|
@ -4453,7 +4549,7 @@ static void capidev_handle_data_b3_indication(_cmsg *CMSG,
|
|||
fr.frametype = AST_FRAME_VOICE;
|
||||
fr.FRAME_DATA_PTR = b3buf;
|
||||
fr.datalen = b3len;
|
||||
fr.samples = b3len;
|
||||
fr.samples = (i->bproto == CC_BPROTO_VOCODER) ? pbx_capi_get_samples (i, b3len) : b3len;
|
||||
fr.offset = AST_FRIENDLY_OFFSET;
|
||||
fr.mallocd = 0;
|
||||
fr.delivery = ast_tv(0,0);
|
||||
|
|
|
@ -58,8 +58,9 @@ struct _diva_stream_scheduling_entry;
|
|||
|
||||
/* was : 130 bytes Alaw = 16.25 ms audio not suitable for VoIP */
|
||||
/* now : 160 bytes Alaw = 20 ms audio */
|
||||
/* now : 640 bytes slinear 16000Hz = 20 ms audio */
|
||||
/* you can tune this to your need. higher value == more latency */
|
||||
#define CAPI_MAX_B3_BLOCK_SIZE 160
|
||||
#define CAPI_MAX_B3_BLOCK_SIZE 640
|
||||
|
||||
#define ALL_SERVICES 0x1FFF03FF
|
||||
|
||||
|
|
|
@ -425,12 +425,43 @@ void voice_over_ip_profile(struct cc_capi_controller *cp)
|
|||
}
|
||||
if (payload1 & 0x00040000) {
|
||||
cp->rtpcodec |= AST_FORMAT_G729A;
|
||||
cc_verbose(3, 0, "G.729");
|
||||
cc_verbose(3, 0, "G.729 ");
|
||||
}
|
||||
if (payload1 & (1U << 27)) {
|
||||
cp->rtpcodec |= AST_FORMAT_ILBC;
|
||||
cc_verbose(3, 0, "iLBC");
|
||||
cc_verbose(3, 0, "iLBC ");
|
||||
}
|
||||
#ifdef AST_FORMAT_G722
|
||||
if (payload1 & (1U << 9)) {
|
||||
cp->rtpcodec |= AST_FORMAT_G722;
|
||||
cc_verbose(3, 0, "G.722 ");
|
||||
}
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN7) && defined(AST_FORMAT_SIREN14)
|
||||
if (payload1 & (1U << 24)) {
|
||||
#ifdef AST_FORMAT_SIREN7
|
||||
cp->rtpcodec |= AST_FORMAT_SIREN7;
|
||||
cc_verbose(3, 0, "siren7 ");
|
||||
#endif
|
||||
#ifdef AST_FORMAT_SIREN14
|
||||
cp->rtpcodec |= AST_FORMAT_SIREN14;
|
||||
cc_verbose(3, 0, "siren14 ");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR) || defined(AST_FORMAT_SLINEAR16)
|
||||
if (payload1 & (1U << 1)) {
|
||||
#if defined(AST_FORMAT_SLINEAR)
|
||||
cp->rtpcodec |= AST_FORMAT_SLINEAR;
|
||||
cc_verbose(3, 0, "slin ");
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR16)
|
||||
cp->rtpcodec |= AST_FORMAT_SLINEAR16;
|
||||
cc_verbose(3, 0, "slin16 ");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
cc_verbose(3, 0, "\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue