Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
c741332d
提交
c741332d
authored
7月 23, 2013
作者:
Steve Underwood
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Spandsp tweaks
上级
8d005a41
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
790 行增加
和
598 行删除
+790
-598
t42.h
libs/spandsp/src/spandsp/t42.h
+0
-10
v18.h
libs/spandsp/src/spandsp/v18.h
+2
-23
t4_tx.c
libs/spandsp/src/t4_tx.c
+47
-17
v18.c
libs/spandsp/src/v18.c
+265
-100
fax_tests.sh
libs/spandsp/tests/fax_tests.sh
+44
-38
v18_tests.c
libs/spandsp/tests/v18_tests.c
+430
-408
mod_spandsp_dsp.c
src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
+2
-2
没有找到文件。
libs/spandsp/src/spandsp/t42.h
浏览文件 @
c741332d
...
...
@@ -76,16 +76,6 @@ SPAN_DECLARE(void) set_lab_gamut2(lab_params_t *s, int L_P, int L_Q, int a_P, in
SPAN_DECLARE
(
void
)
get_lab_gamut2
(
lab_params_t
*
s
,
int
*
L_P
,
int
*
L_Q
,
int
*
a_P
,
int
*
a_Q
,
int
*
b_P
,
int
*
b_Q
);
SPAN_DECLARE
(
int
)
t42_itulab_to_itulab
(
logging_state_t
*
logging
,
tdata_t
*
dst
,
tsize_t
*
dstlen
,
tdata_t
src
,
tsize_t
srclen
,
uint32_t
width
,
uint32_t
height
);
SPAN_DECLARE
(
int
)
t42_itulab_to_jpeg
(
logging_state_t
*
logging
,
lab_params_t
*
s
,
tdata_t
*
dst
,
tsize_t
*
dstlen
,
tdata_t
src
,
tsize_t
srclen
);
SPAN_DECLARE
(
int
)
t42_jpeg_to_itulab
(
logging_state_t
*
logging
,
lab_params_t
*
s
,
tdata_t
*
dst
,
tsize_t
*
dstlen
,
tdata_t
src
,
tsize_t
srclen
);
SPAN_DECLARE
(
int
)
t42_srgb_to_itulab
(
logging_state_t
*
logging
,
lab_params_t
*
s
,
tdata_t
*
dst
,
tsize_t
*
dstlen
,
tdata_t
src
,
tsize_t
srclen
,
uint32_t
width
,
uint32_t
height
);
SPAN_DECLARE
(
int
)
t42_itulab_to_srgb
(
logging_state_t
*
logging
,
lab_params_t
*
s
,
tdata_t
dst
,
tsize_t
*
dstlen
,
tdata_t
src
,
tsize_t
srclen
,
uint32_t
*
width
,
uint32_t
*
height
);
SPAN_DECLARE
(
void
)
t42_encode_set_options
(
t42_encode_state_t
*
s
,
uint32_t
l0
,
int
quality
,
int
options
);
SPAN_DECLARE
(
int
)
t42_encode_set_image_width
(
t42_encode_state_t
*
s
,
uint32_t
image_width
);
...
...
libs/spandsp/src/spandsp/v18.h
浏览文件 @
c741332d
...
...
@@ -40,7 +40,7 @@ enum
{
V18_MODE_NONE
=
0
,
/* V.18 Annex A - Weitbrecht TDD at 45.45bps (US TTY), half-duplex, 5 bit baudot (USA). */
V18_MODE_5BIT_45
=
1
,
V18_MODE_5BIT_45
45
=
1
,
/* V.18 Annex A - Weitbrecht TDD at 50bps (International TTY), half-duplex, 5 bit baudot (UK, Australia and others). */
V18_MODE_5BIT_50
=
2
,
/* V.18 Annex B - DTMF encoding of ASCII (Denmark, Holland and others). */
...
...
@@ -55,6 +55,7 @@ enum
V18_MODE_V21TEXTPHONE
=
7
,
/* V.18 Annex G - V.18 text telephone mode. */
V18_MODE_V18TEXTPHONE
=
8
,
V18_MODE_5BIT_476
=
9
,
/* Use repetitive shift characters where character set shifts are used */
V18_MODE_REPETITIVE_SHIFTS_OPTION
=
0x1000
};
...
...
@@ -171,28 +172,6 @@ SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len);
invalid, this function will return -1. */
SPAN_DECLARE
(
int
)
v18_put
(
v18_state_t
*
s
,
const
char
msg
[],
int
len
);
/*! Convert a text string to a V.18 DTMF string.
\brief Convert a text string to a V.18 DTMF string.
\param s The V.18 context.
\param dtmf The resulting DTMF string.
\param msg The text string to be converted.
\return The length of the DTMF string.
*/
SPAN_DECLARE
(
int
)
v18_encode_dtmf
(
v18_state_t
*
s
,
char
dtmf
[],
const
char
msg
[]);
/*! Convert a V.18 DTMF string to a text string.
\brief Convert a V.18 DTMF string to a text string.
\param s The V.18 context.
\param msg The resulting test string.
\param dtmf The DTMF string to be converted.
\return The length of the text string.
*/
SPAN_DECLARE
(
int
)
v18_decode_dtmf
(
v18_state_t
*
s
,
char
msg
[],
const
char
dtmf
[]);
SPAN_DECLARE
(
uint16_t
)
v18_encode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
);
SPAN_DECLARE
(
uint8_t
)
v18_decode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
);
/*! \brief Return a short name for an V.18 mode
\param mode The code for the V.18 mode.
\return A pointer to the name.
...
...
libs/spandsp/src/t4_tx.c
浏览文件 @
c741332d
...
...
@@ -132,18 +132,19 @@ static const res_table_t y_res_table[] =
{
-
1
.
00
f
,
-
1
}
};
static
const
int
resolution_map
[
10
][
10
]
=
static
const
int
resolution_map
[
10
][
9
]
=
{
{
0
,
0
,
0
,
T4_RESOLUTION_R8_STANDARD
,
0
,
0
,
0
,
0
,
0
,
0
},
{
T4_RESOLUTION_100_100
,
0
,
T4_RESOLUTION_200_100
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
T4_RESOLUTION_R8_FINE
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
T4_RESOLUTION_200_200
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
T4_RESOLUTION_300_300
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
T4_RESOLUTION_R8_SUPERFINE
,
0
,
0
,
T4_RESOLUTION_R16_SUPERFINE
,
0
,
0
,
0
},
{
0
,
0
,
T4_RESOLUTION_200_400
,
0
,
0
,
T4_RESOLUTION_400_400
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
T4_RESOLUTION_300_600
,
0
,
0
,
T4_RESOLUTION_600_600
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
T4_RESOLUTION_400_800
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
T4_RESOLUTION_600_1200
,
0
,
T4_RESOLUTION_1200_1200
},
/* x = 100 102 200 204 300 400 408 600 1200 */
{
0
,
0
,
0
,
T4_RESOLUTION_R8_STANDARD
,
0
,
0
,
0
,
0
,
0
},
/* y = 3.85/mm */
{
T4_RESOLUTION_100_100
,
0
,
T4_RESOLUTION_200_100
,
0
,
0
,
0
,
0
,
0
,
0
},
/* y = 100 */
{
0
,
0
,
0
,
T4_RESOLUTION_R8_FINE
,
0
,
0
,
0
,
0
,
0
},
/* y = 7.7/mm */
{
0
,
0
,
T4_RESOLUTION_200_200
,
0
,
0
,
0
,
0
,
0
,
0
},
/* y = 200 */
{
0
,
0
,
0
,
0
,
T4_RESOLUTION_300_300
,
0
,
0
,
0
,
0
},
/* y = 300 */
{
0
,
0
,
0
,
T4_RESOLUTION_R8_SUPERFINE
,
0
,
0
,
T4_RESOLUTION_R16_SUPERFINE
,
0
,
0
},
/* y = 154/mm */
{
0
,
0
,
T4_RESOLUTION_200_400
,
0
,
0
,
T4_RESOLUTION_400_400
,
0
,
0
,
0
},
/* y = 400 */
{
0
,
0
,
0
,
0
,
T4_RESOLUTION_300_600
,
0
,
0
,
T4_RESOLUTION_600_600
,
0
},
/* y = 600 */
{
0
,
0
,
0
,
0
,
0
,
T4_RESOLUTION_400_800
,
0
,
0
,
0
},
/* y = 800 */
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
T4_RESOLUTION_600_1200
,
T4_RESOLUTION_1200_1200
}
/* y = 1200 */
};
#if defined(SPANDSP_SUPPORT_TIFF_FX)
...
...
@@ -1354,12 +1355,14 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
t
->
image_type
=
s
->
tiff
.
image_type
;
t
->
image_width
=
s
->
tiff
.
image_width
;
t
->
image_length
=
s
->
tiff
.
image_length
;
t
->
image_x_resolution
=
s
->
tiff
.
x_resolution
;
t
->
image_y_resolution
=
s
->
tiff
.
y_resolution
;
t
->
x_resolution
=
s
->
metadata
.
x_resolution
;
t
->
y_resolution
=
s
->
metadata
.
y_resolution
/
s
->
row_squashing_ratio
;
t
->
compression
=
s
->
metadata
.
compression
;
switch
(
s
->
metadata
.
compression
)
{
case
T4_COMPRESSION_T4_1D
:
...
...
@@ -1417,7 +1420,7 @@ SPAN_DECLARE(int) t4_tx_image_complete(t4_tx_state_t *s)
return
t85_encode_image_complete
(
&
s
->
encoder
.
t85
);
#if defined(SPANDSP_SUPPORT_T88)
case
T4_COMPRESSION_T88
:
break
;
return
t88_encode_image_complete
(
&
s
->
encoder
.
t88
)
;
#endif
case
T4_COMPRESSION_T42_T81
:
case
T4_COMPRESSION_SYCC_T81
:
...
...
@@ -1428,7 +1431,7 @@ SPAN_DECLARE(int) t4_tx_image_complete(t4_tx_state_t *s)
#endif
#if defined(SPANDSP_SUPPORT_T45)
case
T4_COMPRESSION_T45
:
break
;
return
t45_encode_image_complete
(
&
s
->
encoder
.
t45
)
;
#endif
}
return
SIG_STATUS_END_OF_DATA
;
...
...
@@ -1444,6 +1447,19 @@ SPAN_DECLARE(int) t4_tx_get_bit(t4_tx_state_t *s)
SPAN_DECLARE
(
int
)
t4_tx_get
(
t4_tx_state_t
*
s
,
uint8_t
buf
[],
size_t
max_len
)
{
#if 0
if (s->pre_encoded_len > 0)
{
if (max_len > (s->pre_encoded_len - s->pre_encoded_ptr))
max_len = s->pre_encoded_len - s->pre_encoded_ptr;
memcpy(buf, &s->pre_encoded_buf[s->pre_encoded_ptr], max_len);
s->pre_encoded_ptr += max_len;
return max_len;
}
if (s->image_get_handler)
return s->image_get_handler((void *) &s->encoder, buf, max_len);
#else
switch
(
s
->
metadata
.
compression
)
{
case
T4_COMPRESSION_T4_1D
:
...
...
@@ -1469,6 +1485,7 @@ SPAN_DECLARE(int) t4_tx_get(t4_tx_state_t *s, uint8_t buf[], size_t max_len)
break
;
#endif
}
#endif
return
0
;
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -1497,31 +1514,44 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
case
T4_COMPRESSION_T4_2D
:
case
T4_COMPRESSION_T6
:
t4_t6_encode_restart
(
&
s
->
encoder
.
t4_t6
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t4_t6_encode_get
;
break
;
case
T4_COMPRESSION_T85
:
case
T4_COMPRESSION_T85_L0
:
t85_encode_restart
(
&
s
->
encoder
.
t85
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t85_encode_get
;
break
;
#if defined(SPANDSP_SUPPORT_T88)
case
T4_COMPRESSION_T88
:
t88_encode_restart
(
&
s
->
encoder
.
t88
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t88_encode_get
;
break
;
#endif
case
T4_COMPRESSION_T42_T81
:
case
T4_COMPRESSION_SYCC_T81
:
t42_encode_restart
(
&
s
->
encoder
.
t42
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t42_encode_get
;
break
;
#if defined(SPANDSP_SUPPORT_T43)
case
T4_COMPRESSION_T43
:
t43_encode_restart
(
&
s
->
encoder
.
t43
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t43_encode_get
;
break
;
#endif
#if defined(SPANDSP_SUPPORT_T45)
case
T4_COMPRESSION_T45
:
t45_encode_restart
(
&
s
->
encoder
.
t45
,
s
->
metadata
.
image_width
,
s
->
metadata
.
image_length
);
s
->
image_get_handler
=
(
t4_image_get_handler_t
)
t45_encode_get
;
break
;
#endif
default
:
s
->
image_get_handler
=
NULL
;
break
;
}
/* If there is a page header, create that first */
if
(
s
->
tiff
.
image_type
==
T4_IMAGE_TYPE_BILEVEL
&&
s
->
header_info
&&
s
->
header_info
[
0
]
&&
make_header
(
s
)
==
0
)
if
(
s
->
metadata
.
image_type
==
T4_IMAGE_TYPE_BILEVEL
&&
s
->
header_info
&&
s
->
header_info
[
0
]
&&
make_header
(
s
)
==
0
)
//if (s->header_info && s->header_info[0] && make_header(s) == 0)
{
s
->
header_row
=
0
;
set_row_read_handler
(
s
,
header_row_read_handler
,
(
void
*
)
s
);
...
...
@@ -1634,7 +1664,7 @@ SPAN_DECLARE(int) t4_tx_release(t4_tx_state_t *s)
return
t85_encode_release
(
&
s
->
encoder
.
t85
);
#if defined(SPANDSP_SUPPORT_T88)
case
T4_COMPRESSION_T88
:
break
;
return
t88_encode_release
(
&
s
->
encoder
.
t88
)
;
#endif
case
T4_COMPRESSION_T42_T81
:
case
T4_COMPRESSION_SYCC_T81
:
...
...
@@ -1645,7 +1675,7 @@ SPAN_DECLARE(int) t4_tx_release(t4_tx_state_t *s)
#endif
#if defined(SPANDSP_SUPPORT_T45)
case
T4_COMPRESSION_T45
:
break
;
return
t45_encode_release
(
&
s
->
encoder
.
t45
)
;
#endif
}
return
-
1
;
...
...
libs/spandsp/src/v18.c
浏览文件 @
c741332d
...
...
@@ -78,13 +78,13 @@
Silence for 0.5s then send TXP
DTMF
Proceed as Annex B
1650Hz (V21 ch 2 low)
1650Hz (V21 ch 2 low)
[1650Hz +-12Hz]
Proceed as Annex F in call mode
1300Hz (Calling tone)
1300Hz (Calling tone)
[1300Hz +-16Hz]
Proceed as Annex E in call mode
1400Hz/1800Hz (Weitbrecht)
1400Hz/1800Hz (Weitbrecht)
[1400Hz +-5% and 1800Hz +-5%]
Detect rate and proceed as Annex A
980Hz/1180Hz (V21 ch 1)
980Hz/1180Hz (V21 ch 1)
[980Hz +-12Hz, 1180Hz +-12Hz]
Start timer Tr
2225Hz (Bell ANS)
Proceed as Annex D call mode
...
...
@@ -98,21 +98,21 @@
Monitor as caller for 980Hz or 1300Hz
CI/XCI
Respond with ANSam
1300Hz
1300Hz
[1300Hz +-16Hz]
Probe
Timer Ta (3s)
Probe
1400Hz/1800Hz (Weitbrecht)
1400Hz/1800Hz (Weitbrecht)
[1400Hz +-5% and 1800Hz +-5%]
Detect rate and proceed as Annex A
DTMF
Proceed as Annex B
980Hz (V21 ch 1 low)
980Hz (V21 ch 1 low)
[980Hz +-12Hz]
Start timer Te
1270Hz (Bell103 ch 2 high)
Proceed as Annex D answer mode
2225Hz (Bell ANS)
Proceed as Annex D call mode
1650Hz (V21 ch 2 low)
1650Hz (V21 ch 2 low)
[1650Hz +-12Hz]
Proceed as Annex F answer mode
ANSam
Proceed as V.8 caller Annex G
...
...
@@ -131,6 +131,7 @@ struct dtmf_to_ascii_s
static
const
struct
dtmf_to_ascii_s
dtmf_to_ascii
[]
=
{
{
"###0"
,
'!'
},
{
"###1"
,
'C'
},
{
"###2"
,
'F'
},
{
"###3"
,
'I'
},
...
...
@@ -140,7 +141,6 @@ static const struct dtmf_to_ascii_s dtmf_to_ascii[] =
{
"###7"
,
'U'
},
{
"###8"
,
'X'
},
{
"###9"
,
';'
},
{
"###0"
,
'!'
},
{
"##*1"
,
'A'
},
{
"##*2"
,
'D'
},
{
"##*3"
,
'G'
},
...
...
@@ -373,71 +373,174 @@ static const uint8_t txp[] = "1111111111000101011100001101110000010101";
100 ms mark. */
static
const
uint8_t
xci
[]
=
"01111111110111111111"
;
static
int
cmp
(
const
void
*
s
,
const
void
*
t
)
/* The entries here must match the order in which the related names are defined in v18.h */
static
const
int
automoding_sequences
[][
6
]
=
{
const
char
*
ss
;
struct
dtmf_to_ascii_s
*
tt
;
ss
=
(
const
char
*
)
s
;
tt
=
(
struct
dtmf_to_ascii_s
*
)
t
;
return
strncmp
(
ss
,
tt
->
dtmf
,
strlen
(
tt
->
dtmf
));
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE
(
int
)
v18_encode_dtmf
(
v18_state_t
*
s
,
char
dtmf
[],
const
char
msg
[])
{
const
char
*
t
;
const
char
*
v
;
char
*
u
;
t
=
msg
;
u
=
dtmf
;
while
(
*
t
)
{
v
=
ascii_to_dtmf
[
*
t
&
0x7F
];
while
(
*
v
)
*
u
++
=
*
v
++
;
t
++
;
}
*
u
=
'\0'
;
return
u
-
dtmf
;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE
(
int
)
v18_decode_dtmf
(
v18_state_t
*
s
,
char
msg
[],
const
char
dtmf
[])
{
int
entries
;
const
char
*
t
;
char
*
u
;
struct
dtmf_to_ascii_s
*
ss
;
entries
=
sizeof
(
dtmf_to_ascii
)
/
sizeof
(
dtmf_to_ascii
[
0
])
-
1
;
t
=
dtmf
;
u
=
msg
;
while
(
*
t
)
/* Dummy entry 0 */
V18_MODE_5BIT_4545
,
V18_MODE_BELL103
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
},
{
ss
=
bsearch
(
t
,
dtmf_to_ascii
,
entries
,
sizeof
(
dtmf_to_ascii
[
0
]),
cmp
);
if
(
ss
)
/* Australia */
V18_MODE_5BIT_50
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
t
+=
strlen
(
ss
->
dtmf
);
*
u
++
=
ss
->
ascii
;
}
else
/* Ireland */
V18_MODE_5BIT_50
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Can't match the code. Let's assume this is a code we just don't know, and skip over it */
while
(
*
t
==
'#'
||
*
t
==
'*'
)
t
++
;
if
(
*
t
)
t
++
;
}
/* Germany */
V18_MODE_EDT
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Switzerland */
V18_MODE_EDT
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Italy */
V18_MODE_EDT
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Spain */
V18_MODE_EDT
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Austria */
V18_MODE_EDT
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* Netherlands */
V18_MODE_DTMF
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_BELL103
},
{
/* Iceland */
V18_MODE_V21TEXTPHONE
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_BELL103
},
{
/* Norway */
V18_MODE_V21TEXTPHONE
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_BELL103
},
{
/* Sweden */
V18_MODE_V21TEXTPHONE
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_BELL103
},
{
/* Finland */
V18_MODE_V21TEXTPHONE
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_BELL103
},
{
/* Denmark */
V18_MODE_V21TEXTPHONE
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_EDT
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_BELL103
},
{
/* UK */
V18_MODE_V21TEXTPHONE
,
V18_MODE_5BIT_50
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
,
V18_MODE_BELL103
},
{
/* USA */
V18_MODE_5BIT_4545
,
V18_MODE_BELL103
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
},
{
/* France */
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_BELL103
},
{
/* Belgium */
V18_MODE_V23VIDEOTEX
,
V18_MODE_EDT
,
V18_MODE_DTMF
,
V18_MODE_5BIT_50
,
V18_MODE_V21TEXTPHONE
,
V18_MODE_BELL103
}
*
u
=
'\0'
;
return
u
-
msg
;
}
/*- End of function --------------------------------------------------------*/
};
SPAN_DECLARE
(
uint16_t
)
v18_
encode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
)
static
uint16_t
encode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
)
{
static
const
uint8_t
conv
[
128
]
=
{
...
...
@@ -449,7 +552,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
0xFF
,
/* ENQ */
0xFF
,
/* ACK */
0xFF
,
/* BEL */
0x
0
0
,
/* BS */
0x
4
0
,
/* BS */
0x44
,
/* HT >> SPACE */
0x42
,
/* LF */
0x42
,
/* VT >> LF */
...
...
@@ -572,14 +675,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
};
uint16_t
shift
;
if
(
ch
==
0x7F
)
{
/* DLE is a special character meaning "force a
change to the letter character set */
shift
=
BAUDOT_LETTER_SHIFT
;
return
0
;
}
ch
=
conv
[
ch
];
ch
=
conv
[
ch
&
0x7F
];
/* Is it a non-existant code? */
if
(
ch
==
0xFF
)
return
0
;
...
...
@@ -605,7 +701,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE
(
uint8_t
)
v18_
decode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
)
static
uint8_t
decode_baudot
(
v18_state_t
*
s
,
uint8_t
ch
)
{
static
const
uint8_t
conv
[
2
][
32
]
=
{
...
...
@@ -624,8 +720,8 @@ SPAN_DECLARE(uint8_t) v18_decode_baudot(v18_state_t *s, uint8_t ch)
default:
return
conv
[
s
->
baudot_rx_shift
][
ch
];
}
/*
return 0
if we did not produce a character */
return
0
;
/*
Return 0xFF
if we did not produce a character */
return
0
xFF
;
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -649,7 +745,7 @@ static int v18_tdd_get_async_byte(void *user_data)
if
(
s
->
tx_signal_on
)
{
/* The FSK should now be switched off. */
s
->
tx_signal_on
=
FALSE
;
s
->
tx_signal_on
=
0
;
}
return
0x1F
;
}
...
...
@@ -659,14 +755,16 @@ static void v18_dtmf_get(void *user_data)
{
v18_state_t
*
s
;
int
ch
;
const
char
*
v
;
int
len
;
const
char
*
t
;
s
=
(
v18_state_t
*
)
user_data
;
if
((
ch
=
queue_read_byte
(
&
s
->
queue
.
queue
))
>=
0
)
{
v
=
ascii_to_dtmf
[
ch
&
0x7F
];
dtmf_tx_put
(
&
s
->
dtmf_tx
,
v
,
strlen
(
v
));
s
->
rx_suppression
=
((
300
+
100
*
strlen
(
v
))
*
SAMPLE_RATE
)
/
1000
;
t
=
ascii_to_dtmf
[
ch
&
0x7F
];
len
=
strlen
(
t
);
dtmf_tx_put
(
&
s
->
dtmf_tx
,
t
,
len
);
s
->
rx_suppression
=
((
300
+
100
*
len
)
*
SAMPLE_RATE
)
/
1000
;
}
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -685,7 +783,7 @@ static int v18_edt_get_async_byte(void *user_data)
if
(
s
->
tx_signal_on
)
{
/* The FSK should now be switched off. */
s
->
tx_signal_on
=
FALSE
;
s
->
tx_signal_on
=
0
;
}
return
0
;
}
...
...
@@ -726,7 +824,7 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
return
;
}
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"Rx byte %x
\n
"
,
byte
);
if
((
octet
=
v18_decode_baudot
(
s
,
byte
))
)
if
((
octet
=
decode_baudot
(
s
,
byte
))
!=
0xFF
)
s
->
rx_msg
[
s
->
rx_msg_len
++
]
=
octet
;
if
(
s
->
rx_msg_len
>=
256
)
{
...
...
@@ -738,11 +836,55 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
}
/*- End of function --------------------------------------------------------*/
static
int
decode_dtmf_cmp
(
const
void
*
s
,
const
void
*
t
)
{
const
char
*
ss
;
struct
dtmf_to_ascii_s
*
tt
;
ss
=
(
const
char
*
)
s
;
tt
=
(
struct
dtmf_to_ascii_s
*
)
t
;
return
strncmp
(
ss
,
tt
->
dtmf
,
strlen
(
tt
->
dtmf
));
}
/*- End of function --------------------------------------------------------*/
static
int
decode_dtmf
(
v18_state_t
*
s
,
char
msg
[],
const
char
dtmf
[])
{
int
entries
;
int
len
;
const
char
*
t
;
char
*
u
;
struct
dtmf_to_ascii_s
*
ss
;
entries
=
sizeof
(
dtmf_to_ascii
)
/
sizeof
(
dtmf_to_ascii
[
0
])
-
1
;
t
=
dtmf
;
u
=
msg
;
while
(
*
t
)
{
ss
=
bsearch
(
t
,
dtmf_to_ascii
,
entries
,
sizeof
(
dtmf_to_ascii
[
0
]),
decode_dtmf_cmp
);
if
(
ss
)
{
len
=
strlen
(
ss
->
dtmf
);
t
+=
len
;
*
u
++
=
ss
->
ascii
;
return
len
;
}
/* Can't match the code. Let's assume this is a code we just don't know, and skip over it */
while
(
*
t
==
'#'
||
*
t
==
'*'
)
t
++
;
if
(
*
t
)
t
++
;
}
*
u
=
'\0'
;
return
u
-
msg
;
}
/*- End of function --------------------------------------------------------*/
static
void
v18_dtmf_put
(
void
*
user_data
,
const
char
dtmf
[],
int
len
)
{
v18_state_t
*
s
;
char
buf
[
128
];
int
i
;
int
matched
;
s
=
(
v18_state_t
*
)
user_data
;
if
(
s
->
rx_suppression
>
0
)
...
...
@@ -753,11 +895,17 @@ static void v18_dtmf_put(void *user_data, const char dtmf[], int len)
if
(
dtmf
[
i
]
>=
'0'
&&
dtmf
[
i
]
<=
'9'
)
{
s
->
rx_msg
[
s
->
rx_msg_len
]
=
'\0'
;
if
(
v18_decode_dtmf
(
s
,
buf
,
(
const
char
*
)
s
->
rx_msg
)
>
0
)
if
((
matched
=
decode_dtmf
(
s
,
buf
,
(
const
char
*
)
s
->
rx_msg
))
>
0
)
{
buf
[
1
]
=
'\0'
;
s
->
put_msg
(
s
->
user_data
,
(
const
uint8_t
*
)
buf
,
1
);
s
->
rx_msg_len
=
0
;
}
if
(
s
->
rx_msg_len
>
matched
)
memcpy
(
&
s
->
rx_msg
[
0
],
&
s
->
rx_msg
[
matched
],
s
->
rx_msg_len
-
matched
);
s
->
rx_msg_len
-=
matched
;
}
}
s
->
in_progress
=
5
*
SAMPLE_RATE
;
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -815,7 +963,7 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len)
if
(
len
<
max_len
)
{
if
((
lenx
=
fsk_tx
(
&
s
->
fsk_tx
,
amp
+
len
,
max_len
-
len
))
<=
0
)
s
->
tx_signal_on
=
FALSE
;
s
->
tx_signal_on
=
0
;
len
+=
lenx
;
}
break
;
...
...
@@ -894,12 +1042,12 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
}
switch
(
s
->
mode
)
{
case
V18_MODE_5BIT_45
:
case
V18_MODE_5BIT_45
45
:
case
V18_MODE_5BIT_50
:
for
(
i
=
0
;
i
<
len
;
i
++
)
{
n
=
0
;
if
((
x
=
v18_
encode_baudot
(
s
,
msg
[
i
])))
if
((
x
=
encode_baudot
(
s
,
msg
[
i
])))
{
if
((
x
&
0x3E0
))
buf
[
n
++
]
=
(
uint8_t
)
((
x
>>
5
)
&
0x1F
);
...
...
@@ -907,7 +1055,7 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
/* TODO: Deal with out of space condition */
if
(
queue_write
(
&
s
->
queue
.
queue
,
(
const
uint8_t
*
)
buf
,
n
)
<
0
)
return
i
;
s
->
tx_signal_on
=
TRUE
;
s
->
tx_signal_on
=
1
;
}
}
return
len
;
...
...
@@ -920,12 +1068,14 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
SPAN_DECLARE
(
const
char
*
)
v18_mode_to_str
(
int
mode
)
{
switch
((
mode
&
0xFF
))
switch
((
mode
&
0xFF
F
))
{
case
V18_MODE_NONE
:
return
"None"
;
case
V18_MODE_5BIT_45
:
case
V18_MODE_5BIT_45
45
:
return
"Weitbrecht TDD (45.45bps)"
;
case
V18_MODE_5BIT_476
:
return
"Weitbrecht TDD (47.6bps)"
;
case
V18_MODE_5BIT_50
:
return
"Weitbrecht TDD (50bps)"
;
case
V18_MODE_DTMF
:
...
...
@@ -958,6 +1108,9 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
put_msg_func_t
put_msg
,
void
*
user_data
)
{
if
(
nation
<
0
||
nation
>=
V18_AUTOMODING_END
)
return
NULL
;
if
(
s
==
NULL
)
{
if
((
s
=
(
v18_state_t
*
)
malloc
(
sizeof
(
*
s
)))
==
NULL
)
...
...
@@ -965,14 +1118,14 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
}
memset
(
s
,
0
,
sizeof
(
*
s
));
s
->
calling_party
=
calling_party
;
s
->
mode
=
mode
&
0xFF
;
s
->
mode
=
mode
&
~
V18_MODE_REPETITIVE_SHIFTS_OPTION
;
s
->
put_msg
=
put_msg
;
s
->
user_data
=
user_data
;
switch
(
s
->
mode
)
{
case
V18_MODE_5BIT_45
:
s
->
repeat_shifts
=
mode
&
0x100
;
case
V18_MODE_5BIT_45
45
:
s
->
repeat_shifts
=
mode
&
V18_MODE_REPETITIVE_SHIFTS_OPTION
;
fsk_tx_init
(
&
s
->
fsk_tx
,
&
preset_fsk_specs
[
FSK_WEITBRECHT_4545
],
async_tx_get_bit
,
&
s
->
async_tx
);
async_tx_init
(
&
s
->
async_tx
,
5
,
ASYNC_PARITY_NONE
,
2
,
FALSE
,
v18_tdd_get_async_byte
,
s
);
/* Schedule an explicit shift at the start of baudot transmission */
...
...
@@ -983,8 +1136,20 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
s
->
baudot_rx_shift
=
0
;
s
->
next_byte
=
(
uint8_t
)
0xFF
;
break
;
case
V18_MODE_5BIT_476
:
s
->
repeat_shifts
=
mode
&
V18_MODE_REPETITIVE_SHIFTS_OPTION
;
fsk_tx_init
(
&
s
->
fsk_tx
,
&
preset_fsk_specs
[
FSK_WEITBRECHT_476
],
async_tx_get_bit
,
&
s
->
async_tx
);
async_tx_init
(
&
s
->
async_tx
,
5
,
ASYNC_PARITY_NONE
,
2
,
FALSE
,
v18_tdd_get_async_byte
,
s
);
/* Schedule an explicit shift at the start of baudot transmission */
s
->
baudot_tx_shift
=
2
;
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
ride over the fraction. */
fsk_rx_init
(
&
s
->
fsk_rx
,
&
preset_fsk_specs
[
FSK_WEITBRECHT_476
],
FSK_FRAME_MODE_5N1_FRAMES
,
v18_tdd_put_async_byte
,
s
);
s
->
baudot_rx_shift
=
0
;
s
->
next_byte
=
(
uint8_t
)
0xFF
;
break
;
case
V18_MODE_5BIT_50
:
s
->
repeat_shifts
=
mode
&
0x100
;
s
->
repeat_shifts
=
mode
&
V18_MODE_REPETITIVE_SHIFTS_OPTION
;
fsk_tx_init
(
&
s
->
fsk_tx
,
&
preset_fsk_specs
[
FSK_WEITBRECHT_50
],
async_tx_get_bit
,
&
s
->
async_tx
);
async_tx_init
(
&
s
->
async_tx
,
5
,
ASYNC_PARITY_NONE
,
2
,
FALSE
,
v18_tdd_get_async_byte
,
s
);
/* Schedule an explicit shift at the start of baudot transmission */
...
...
libs/spandsp/tests/fax_tests.sh
浏览文件 @
c741332d
...
...
@@ -70,49 +70,55 @@ LOCALTESTS_DIR=../test-data/local
# Colour/gray -> bilevel by not allowing ECM
for
OPTS
in
"-p AA"
"-p TT"
"-p GG"
"-p TG"
"-p GT"
do
IN_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-colour.tif"
OUT_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-colour-bilevel.tif"
run_colour_fax_test
IN_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-bw.tif"
OUT_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-bw-bilevel.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/c03x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/c03x_02x.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/l02x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/l02x_02x.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/l04x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/l04x_02x.tif"
run_colour_fax_test
echo
Colour to bi-level tests disabled
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
# OUT_FILE="${LOCALTESTS_DIR}/lenna-colour-bilevel.tif"
# run_colour_fax_test
# IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw-bilevel.tif"
# run_colour_fax_test
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw-bilevel.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
# run_colour_fax_test
done
# Colour/gray -> colour/gray by allowing ECM
for
OPTS
in
"-p AA -C -e"
"-p TT -C -e"
"-p GG -C -e"
"-p TG -C -e"
"-p GT -C -e"
do
IN_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-colour.tif"
OUT_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-colour.tif"
run_colour_fax_test
IN_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-bw.tif"
OUT_FILE
=
"
${
LOCALTESTS_DIR
}
/lenna-bw.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/c03x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/c03x_02x.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/l02x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/l02x_02x.tif"
run_colour_fax_test
IN_FILE
=
"
${
TIFFFX_DIR
}
/l04x_02x.tif"
OUT_FILE
=
"
${
TIFFFX_DIR
}
/l04x_02x.tif"
run_colour_fax_test
echo
Colour to colour tests disabled
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
# OUT_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
# run_colour_fax_test
# IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
# run_colour_fax_test
# IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
# OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
# run_colour_fax_test
done
# Bi-level tests
...
...
libs/spandsp/tests/v18_tests.c
浏览文件 @
c741332d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
浏览文件 @
c741332d
...
...
@@ -150,11 +150,11 @@ static int get_v18_mode(switch_core_session_t *session)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
const
char
*
var
;
int
r
=
V18_MODE_5BIT_45
;
int
r
=
V18_MODE_5BIT_45
45
;
if
((
var
=
switch_channel_get_variable
(
channel
,
"v18_mode"
)))
{
if
(
!
strcasecmp
(
var
,
"5BIT_45"
)
||
!
strcasecmp
(
var
,
"baudot"
))
{
r
=
V18_MODE_5BIT_45
;
r
=
V18_MODE_5BIT_45
45
;
}
else
if
(
!
strcasecmp
(
var
,
"5BIT_50"
))
{
r
=
V18_MODE_5BIT_50
;
}
else
if
(
!
strcasecmp
(
var
,
"DTMF"
))
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论