Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
13fbaf7e
提交
13fbaf7e
authored
3月 29, 2012
作者:
Steve Underwood
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Tweaks for spandsp
上级
7c7967fb
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
382 行增加
和
601 行删除
+382
-601
t38_terminal.h
libs/spandsp/src/spandsp/private/t38_terminal.h
+2
-2
v22bis.h
libs/spandsp/src/spandsp/private/v22bis.h
+23
-56
v22bis.h
libs/spandsp/src/spandsp/v22bis.h
+2
-4
t38_terminal.c
libs/spandsp/src/t38_terminal.c
+116
-88
v22bis_rx.c
libs/spandsp/src/v22bis_rx.c
+69
-171
v22bis_tx.c
libs/spandsp/src/v22bis_tx.c
+58
-105
v29rx.c
libs/spandsp/src/v29rx.c
+14
-8
v29tx_constellation_maps.h
libs/spandsp/src/v29tx_constellation_maps.h
+28
-36
v8.c
libs/spandsp/src/v8.c
+1
-1
Makefile.am
libs/spandsp/tests/Makefile.am
+1
-1
fax_tester.c
libs/spandsp/tests/fax_tester.c
+1
-3
fax_tests.sh
libs/spandsp/tests/fax_tests.sh
+67
-126
没有找到文件。
libs/spandsp/src/spandsp/private/t38_terminal.h
浏览文件 @
13fbaf7e
...
...
@@ -32,8 +32,8 @@ typedef struct
{
/*! \brief Internet Aware FAX mode bit mask. */
int
iaf
;
/*! \brief Required time between T.38 transmissions, in mi
lli
seconds. */
int
m
s_per_tx_chunk
;
/*! \brief Required time between T.38 transmissions, in mi
cro
seconds. */
int
u
s_per_tx_chunk
;
/*! \brief Bit fields controlling the way data is packed into chunked for transmission. */
int
chunking_modes
;
...
...
libs/spandsp/src/spandsp/private/v22bis.h
浏览文件 @
13fbaf7e
...
...
@@ -26,10 +26,10 @@
#if !defined(_SPANDSP_PRIVATE_V22BIS_H_)
#define _SPANDSP_PRIVATE_V22BIS_H_
/*! The
length of the equalizer buffer
*/
#define V22BIS_EQUALIZER_LEN
1
7
/*!
Samples before the target position in the equalizer buffer
*/
#define V22BIS_EQUALIZER_
PRE_LEN 8
/*! The
number of steps to the left and to the right of the target position in the equalizer buffer.
*/
#define V22BIS_EQUALIZER_LEN 7
/*!
One less than a power of 2 >= (2*V22BIS_EQUALIZER_LEN + 1)
*/
#define V22BIS_EQUALIZER_
MASK 15
/*! The number of taps in the transmit pulse shaping filter */
#define V22BIS_TX_FILTER_STEPS 9
...
...
@@ -65,12 +65,6 @@ enum
V22BIS_TX_TRAINING_STAGE_PARKED
};
#if defined(SPANDSP_USE_FIXED_POINT)
extern
const
complexi16_t
v22bis_constellation
[
16
];
#else
extern
const
complexf_t
v22bis_constellation
[
16
];
#endif
/*!
V.22bis modem descriptor. This defines the working state for a single instance
of a V.22bis modem.
...
...
@@ -99,15 +93,10 @@ struct v22bis_state_s
/* Receive section */
struct
{
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief The scaling factor accessed by the AGC algorithm. */
int16_t
agc_scaling
;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
#if defined(SPANDSP_USE_FIXED_POINTx)
int16_t
rrc_filter
[
V22BIS_RX_FILTER_STEPS
];
#else
/*! \brief The scaling factor accessed by the AGC algorithm. */
float
agc_scaling
;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
float
rrc_filter
[
V22BIS_RX_FILTER_STEPS
];
#endif
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
...
...
@@ -127,27 +116,19 @@ struct v22bis_state_s
/*! \brief >0 if a signal above the minimum is present. It may or may not be a V.22bis signal. */
int
signal_present
;
/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
float
training_error
;
/*! \brief The current phase of the carrier (i.e. the DDS parameter). */
uint32_t
carrier_phase
;
/*! \brief The update rate for the phase of the carrier (i.e. the DDS increment). */
int32_t
carrier_phase_rate
;
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
int32_t
training_error
;
/*! \brief The proportional part of the carrier tracking filter. */
int32_t
carrier_track_p
;
/*! \brief The integral part of the carrier tracking filter. */
int32_t
carrier_track_i
;
#else
/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
float
training_error
;
/*! \brief The proportional part of the carrier tracking filter. */
float
carrier_track_p
;
/*! \brief The integral part of the carrier tracking filter. */
float
carrier_track_i
;
#endif
/*! \brief A callback function which may be enabled to report every symbol's
constellation position. */
...
...
@@ -162,23 +143,21 @@ struct v22bis_state_s
int32_t
carrier_on_power
;
/*! \brief The power meter level at which carrier off is declared. */
int32_t
carrier_off_power
;
/*! \brief The scaling factor accessed by the AGC algorithm. */
float
agc_scaling
;
int
constellation_state
;
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief The current delta factor for updating the equalizer coefficients. */
int16_t
eq_delta
;
/*! \brief The adaptive equalizer coefficients. */
complexi16_t
eq_coeff
[
V22BIS_EQUALIZER_LEN
];
/*! \brief The equalizer signal buffer. */
complexi16_t
eq_buf
[
V22BIS_EQUALIZER_LEN
];
#else
/*! \brief The current delta factor for updating the equalizer coefficients. */
float
eq_delta
;
#if defined(SPANDSP_USE_FIXED_POINTx)
/*! \brief The adaptive equalizer coefficients. */
complex
f_t
eq_coeff
[
V22BIS_EQUALIZER_LEN
];
complex
i_t
eq_coeff
[
2
*
V22BIS_EQUALIZER_LEN
+
1
];
/*! \brief The equalizer signal buffer. */
complexf_t
eq_buf
[
V22BIS_EQUALIZER_LEN
];
complexi_t
eq_buf
[
V22BIS_EQUALIZER_MASK
+
1
];
#else
complexf_t
eq_coeff
[
2
*
V22BIS_EQUALIZER_LEN
+
1
];
complexf_t
eq_buf
[
V22BIS_EQUALIZER_MASK
+
1
];
#endif
/*! \brief Current offset into the equalizer buffer. */
int
eq_step
;
...
...
@@ -204,24 +183,11 @@ struct v22bis_state_s
/* Transmit section */
struct
{
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief The guard tone level. */
int16_t
guard_tone_gain
;
/*! \brief The gain factor needed to achieve the specified output power. */
int16_t
gain
;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
int16_t
rrc_filter_re
[
V22BIS_TX_FILTER_STEPS
];
int16_t
rrc_filter_im
[
V22BIS_TX_FILTER_STEPS
];
#else
/*! \brief The guard tone level. */
float
guard_tone_gain
;
/*! \brief The gain factor needed to achieve the specified output power. */
float
gain
;
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
float
rrc_filter_re
[
V22BIS_TX_FILTER_STEPS
];
float
rrc_filter_im
[
V22BIS_TX_FILTER_STEPS
];
#endif
/*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */
complexf_t
rrc_filter
[
2
*
V22BIS_TX_FILTER_STEPS
];
/*! \brief Current offset into the RRC pulse shaping filter buffer. */
int
rrc_filter_step
;
...
...
@@ -243,6 +209,7 @@ struct v22bis_state_s
uint32_t
guard_phase
;
/*! \brief The update rate for the phase of the guard tone (i.e. the DDS increment). */
int32_t
guard_phase_rate
;
float
guard_level
;
/*! \brief The current fractional phase of the baud timing. */
int
baud_phase
;
/*! \brief The code number for the current position in the constellation. */
...
...
libs/spandsp/src/spandsp/v22bis.h
浏览文件 @
13fbaf7e
...
...
@@ -61,6 +61,8 @@ enum
*/
typedef
struct
v22bis_state_s
v22bis_state_t
;
extern
const
complexf_t
v22bis_constellation
[
16
];
#if defined(__cplusplus)
extern
"C"
{
...
...
@@ -86,11 +88,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx_fillin(v22bis_state_t *s, int len);
\brief Get a snapshot of the current equalizer coefficients.
\param coeffs The vector of complex coefficients.
\return The number of coefficients in the vector. */
#if defined(SPANDSP_USE_FIXED_POINT)
SPAN_DECLARE
(
int
)
v22bis_rx_equalizer_state
(
v22bis_state_t
*
s
,
complexi16_t
**
coeffs
);
#else
SPAN_DECLARE
(
int
)
v22bis_rx_equalizer_state
(
v22bis_state_t
*
s
,
complexf_t
**
coeffs
);
#endif
/*! Get the current received carrier frequency.
\param s The modem context.
...
...
libs/spandsp/src/t38_terminal.c
浏览文件 @
13fbaf7e
...
...
@@ -109,7 +109,7 @@
#include "spandsp/private/t38_terminal.h"
/* Settings suitable for paced transmission over a UDP transport */
#define DEFAULT_
MS_PER_TX_CHUNK 3
0
#define DEFAULT_
US_PER_TX_CHUNK 3000
0
#define INDICATOR_TX_COUNT 3
#define DATA_TX_COUNT 1
...
...
@@ -613,7 +613,8 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
}
else
{
s
->
t38_fe
.
hdlc_tx
.
extra_bits
=
extra_bits_in_stuffed_frame
(
msg
,
len
);
if
(
s
->
t38_fe
.
us_per_tx_chunk
)
s
->
t38_fe
.
hdlc_tx
.
extra_bits
=
extra_bits_in_stuffed_frame
(
msg
,
len
);
bit_reverse
(
s
->
t38_fe
.
hdlc_tx
.
buf
,
msg
,
len
);
s
->
t38_fe
.
hdlc_tx
.
len
=
len
;
s
->
t38_fe
.
hdlc_tx
.
ptr
=
0
;
...
...
@@ -624,7 +625,7 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
static
__inline__
int
bits_to_us
(
t38_terminal_state_t
*
s
,
int
bits
)
{
if
(
s
->
t38_fe
.
m
s_per_tx_chunk
==
0
||
s
->
t38_fe
.
tx_bit_rate
==
0
)
if
(
s
->
t38_fe
.
u
s_per_tx_chunk
==
0
||
s
->
t38_fe
.
tx_bit_rate
==
0
)
return
0
;
/*endif*/
return
bits
*
1000000
/
s
->
t38_fe
.
tx_bit_rate
;
...
...
@@ -634,9 +635,9 @@ static __inline__ int bits_to_us(t38_terminal_state_t *s, int bits)
static
void
set_octets_per_data_packet
(
t38_terminal_state_t
*
s
,
int
bit_rate
)
{
s
->
t38_fe
.
tx_bit_rate
=
bit_rate
;
if
(
s
->
t38_fe
.
m
s_per_tx_chunk
)
if
(
s
->
t38_fe
.
u
s_per_tx_chunk
)
{
s
->
t38_fe
.
octets_per_data_packet
=
s
->
t38_fe
.
ms_per_tx_chunk
*
bit_rate
/
(
8
*
1000
);
s
->
t38_fe
.
octets_per_data_packet
=
(
s
->
t38_fe
.
us_per_tx_chunk
/
1000
)
*
bit_rate
/
(
8
*
1000
);
/* Make sure we have a positive number (i.e. we didn't truncate to zero). */
if
(
s
->
t38_fe
.
octets_per_data_packet
<
1
)
s
->
t38_fe
.
octets_per_data_packet
=
1
;
...
...
@@ -660,14 +661,12 @@ static int set_no_signal(t38_terminal_state_t *s)
return
delay
;
/*endif*/
s
->
t38_fe
.
timed_step
=
T38_TIMED_STEP_NO_SIGNAL
;
#if 0
if
((
s
->
t38_fe
.
chunking_modes
&
T38_CHUNKING_SEND_2S_REGULAR_INDICATORS
))
s
->
t38_fe
.
timeout_tx_samples
=
s
->
t38_fe
.
next_tx_samples
+
us_to_samples
(
2000000
);
else
s
->
t38_fe
.
timeout_tx_samples
=
0
;
/*endif*/
#endif
return
s
->
t38_fe
.
ms_per_tx_chunk
*
1000
;
return
s
->
t38_fe
.
us_per_tx_chunk
;
}
/*endif*/
if
((
delay
=
t38_core_send_indicator
(
&
s
->
t38_fe
.
t38
,
T38_IND_NO_SIGNAL
))
<
0
)
...
...
@@ -685,12 +684,10 @@ static int stream_no_signal(t38_terminal_state_t *s)
if
((
delay
=
t38_core_send_indicator
(
&
s
->
t38_fe
.
t38
,
0x100
|
T38_IND_NO_SIGNAL
))
<
0
)
return
delay
;
/*endif*/
#if 0
if
(
s
->
t38_fe
.
timeout_tx_samples
&&
s
->
t38_fe
.
next_tx_samples
>=
s
->
t38_fe
.
timeout_tx_samples
)
s
->
t38_fe
.
timed_step
=
T38_TIMED_STEP_NONE
;
/*endif*/
#endif
return
s
->
t38_fe
.
ms_per_tx_chunk
*
1000
;
return
s
->
t38_fe
.
us_per_tx_chunk
;
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -717,20 +714,19 @@ static int stream_non_ecm(t38_terminal_state_t *s)
}
else
{
delay
=
75000
;
if
(
fe
->
us_per_tx_chunk
)
delay
=
75000
;
/*endif*/
}
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_NON_ECM_MODEM_2
;
#if 0
fe
->
timeout_tx_samples
=
fe
->
next_tx_samples
+
us_to_samples
(
t38_core_send_training_delay
(
&
fe
->
t38
,
fe
->
next_tx_indicator
));
#endif
fe
->
next_tx_samples
=
fe
->
samples
;
break
;
case
T38_TIMED_STEP_NON_ECM_MODEM_2
:
/* Switch on a fast modem, and give the training time to complete */
#if 0
if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS))
if
((
fe
->
chunking_modes
&
T38_CHUNKING_SEND_REGULAR_INDICATORS
))
{
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
0x100
|
fe
->
next_tx_indicator
))
<
0
)
return
delay
;
...
...
@@ -738,10 +734,9 @@ static int stream_non_ecm(t38_terminal_state_t *s)
if
(
fe
->
next_tx_samples
>=
fe
->
timeout_tx_samples
)
fe
->
timed_step
=
T38_TIMED_STEP_NON_ECM_MODEM_3
;
/*endif*/
return fe->
ms_per_tx_chunk*1000
;
return
fe
->
us_per_tx_chunk
;
}
/*endif*/
#endif
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
fe
->
next_tx_indicator
))
<
0
)
return
delay
;
/*endif*/
...
...
@@ -760,7 +755,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
if
(
len
<
fe
->
octets_per_data_packet
)
{
/* That's the end of the image data. */
if
(
s
->
t38_fe
.
m
s_per_tx_chunk
)
if
(
fe
->
u
s_per_tx_chunk
)
{
/* Pad the end of the data with some zeros. If we just stop abruptly
at the end of the EOLs, some ATAs fail to clean up properly before
...
...
@@ -781,7 +776,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
return
res
;
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_NON_ECM_MODEM_5
;
delay
=
0
;
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
)
;
break
;
}
/*endif*/
...
...
@@ -790,7 +785,9 @@ static int stream_non_ecm(t38_terminal_state_t *s)
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
T38_FIELD_T4_NON_ECM_DATA
,
buf
,
len
,
T38_PACKET_CATEGORY_IMAGE_DATA
))
<
0
)
return
res
;
/*endif*/
delay
=
bits_to_us
(
s
,
8
*
len
);
if
(
fe
->
us_per_tx_chunk
)
delay
=
bits_to_us
(
s
,
8
*
len
);
/*endif*/
break
;
case
T38_TIMED_STEP_NON_ECM_MODEM_4
:
/* Send padding */
...
...
@@ -806,9 +803,8 @@ static int stream_non_ecm(t38_terminal_state_t *s)
fe
->
timed_step
=
T38_TIMED_STEP_NON_ECM_MODEM_5
;
/* Allow a bit more time than the data will take to play out, to ensure the far ATA does not
cut things short. */
delay
=
bits_to_us
(
s
,
8
*
len
);
if
(
s
->
t38_fe
.
ms_per_tx_chunk
)
delay
+=
60000
;
if
(
fe
->
us_per_tx_chunk
)
delay
=
bits_to_us
(
s
,
8
*
len
)
+
60000
;
/*endif*/
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
break
;
...
...
@@ -818,12 +814,21 @@ static int stream_non_ecm(t38_terminal_state_t *s)
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
T38_FIELD_T4_NON_ECM_DATA
,
buf
,
len
,
T38_PACKET_CATEGORY_IMAGE_DATA
))
<
0
)
return
res
;
/*endif*/
delay
=
bits_to_us
(
s
,
8
*
len
);
if
(
fe
->
us_per_tx_chunk
)
delay
=
bits_to_us
(
s
,
8
*
len
);
/*endif*/
break
;
case
T38_TIMED_STEP_NON_ECM_MODEM_5
:
/* This should not be needed, since the message above indicates the end of the signal, but it
seems like it can improve compatibility with quirky implementations. */
return
set_no_signal
(
s
);
delay
=
set_no_signal
(
s
);
if
(
fe
->
queued_timed_step
!=
T38_TIMED_STEP_NONE
)
{
fe
->
timed_step
=
fe
->
queued_timed_step
;
fe
->
queued_timed_step
=
T38_TIMED_STEP_NONE
;
}
/*endif*/
return
delay
;
}
/*endswitch*/
}
...
...
@@ -858,22 +863,19 @@ static int stream_hdlc(t38_terminal_state_t *s)
}
else
{
delay
=
7500
0
;
delay
=
(
fe
->
us_per_tx_chunk
)
?
75000
:
0
;
}
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_2
;
#if 0
fe
->
timeout_tx_samples
=
fe
->
next_tx_samples
+
us_to_samples
(
t38_core_send_training_delay
(
&
fe
->
t38
,
fe
->
next_tx_indicator
))
+
us_to_samples
(
t38_core_send_flags_delay
(
&
fe
->
t38
,
fe
->
next_tx_indicator
))
+
us_to_samples
(
delay
);
#endif
fe
->
next_tx_samples
=
fe
->
samples
;
break
;
case
T38_TIMED_STEP_HDLC_MODEM_2
:
/* Send HDLC preambling */
#if 0
if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS))
if
((
fe
->
chunking_modes
&
T38_CHUNKING_SEND_REGULAR_INDICATORS
))
{
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
0x100
|
fe
->
next_tx_indicator
))
<
0
)
return
delay
;
...
...
@@ -881,10 +883,9 @@ static int stream_hdlc(t38_terminal_state_t *s)
if
(
fe
->
next_tx_samples
>=
fe
->
timeout_tx_samples
)
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_3
;
/*endif*/
return fe->
ms_per_tx_chunk*1000
;
return
fe
->
us_per_tx_chunk
;
}
/*endif*/
#endif
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
fe
->
next_tx_indicator
))
<
0
)
return
delay
;
/*endif*/
...
...
@@ -897,7 +898,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
if
(
fe
->
octets_per_data_packet
>=
i
)
{
/* The last part of an HDLC frame */
if
(
fe
->
chunking_modes
&
T38_CHUNKING_MERGE_FCS_WITH_DATA
)
if
(
(
fe
->
chunking_modes
&
T38_CHUNKING_MERGE_FCS_WITH_DATA
)
)
{
/* Copy the data, as we might be about to refill the buffer it is in */
memcpy
(
buf
,
&
fe
->
hdlc_tx
.
buf
[
fe
->
hdlc_tx
.
ptr
],
i
);
...
...
@@ -911,41 +912,41 @@ static int stream_hdlc(t38_terminal_state_t *s)
fe
->
hdlc_tx
.
len
=
0
;
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
/* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */
if
(
fe
->
hdlc_tx
.
len
<
0
)
if
(
fe
->
hdlc_tx
.
len
>=
0
)
{
data_fields
[
1
].
field_type
=
T38_FIELD_HDLC_FCS_OK
_SIG_END
;
data_fields
[
1
].
field_type
=
T38_FIELD_HDLC_FCS_OK
;
data_fields
[
1
].
field
=
NULL
;
data_fields
[
1
].
field_len
=
0
;
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA_END
:
T38_PACKET_CATEGORY_IMAGE_DATA_END
;
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
if
((
res
=
t38_core_send_data_multi_field
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
data_fields
,
2
,
category
))
<
0
)
return
res
;
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_5
;
/* We add a bit of extra time here, as with some implementations
the carrier falling too abruptly causes data loss. */
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_3
;
delay
=
bits_to_us
(
s
,
i
*
8
+
fe
->
hdlc_tx
.
extra_bits
);
if
(
s
->
t38_fe
.
ms_per_tx_chunk
)
delay
+=
100000
;
/*endif*/
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
}
else
{
data_fields
[
1
].
field_type
=
T38_FIELD_HDLC_FCS_OK
;
data_fields
[
1
].
field_type
=
T38_FIELD_HDLC_FCS_OK
_SIG_END
;
data_fields
[
1
].
field
=
NULL
;
data_fields
[
1
].
field_len
=
0
;
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA_END
:
T38_PACKET_CATEGORY_IMAGE_DATA_END
;
if
((
res
=
t38_core_send_data_multi_field
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
data_fields
,
2
,
category
))
<
0
)
return
res
;
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_3
;
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_5
;
/* We add a bit of extra time here, as with some implementations
the carrier falling too abruptly causes data loss. */
delay
=
bits_to_us
(
s
,
i
*
8
+
fe
->
hdlc_tx
.
extra_bits
);
if
(
fe
->
us_per_tx_chunk
)
delay
+=
100000
;
/*endif*/
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
}
/*endif*/
break
;
}
/*endif*/
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
T38_FIELD_HDLC_DATA
,
&
fe
->
hdlc_tx
.
buf
[
fe
->
hdlc_tx
.
ptr
],
i
,
category
))
<
0
)
return
res
;
/*endif*/
...
...
@@ -954,7 +955,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
else
{
i
=
fe
->
octets_per_data_packet
;
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
fe
->
current_tx_data_type
,
T38_FIELD_HDLC_DATA
,
&
fe
->
hdlc_tx
.
buf
[
fe
->
hdlc_tx
.
ptr
],
i
,
category
))
<
0
)
return
res
;
/*endif*/
...
...
@@ -970,10 +971,28 @@ static int stream_hdlc(t38_terminal_state_t *s)
fe
->
hdlc_tx
.
len
=
0
;
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
/* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */
if
(
fe
->
hdlc_tx
.
len
<
0
)
if
(
fe
->
hdlc_tx
.
len
>=
0
)
{
if
(
fe
->
hdlc_tx
.
len
==
0
)
{
/* Now, how did we get here? We have finished a frame, but have no new frame to
send, and no end of transmission condition. */
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"No new frame or end transmission condition.
\n
"
);
}
/*endif*/
/* Finish the current frame off, and prepare for the next one. */
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
previous
,
T38_FIELD_HDLC_FCS_OK
,
NULL
,
0
,
category
))
<
0
)
return
res
;
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_3
;
/* We should now wait enough time for everything to clear through an analogue modem at the far end. */
delay
=
bits_to_us
(
s
,
fe
->
hdlc_tx
.
extra_bits
);
}
else
{
/* End of transmission */
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA_END
:
T38_PACKET_CATEGORY_IMAGE_DATA_END
;
category
=
(
fe
->
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA_END
:
T38_PACKET_CATEGORY_IMAGE_DATA_END
;
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
previous
,
T38_FIELD_HDLC_FCS_OK_SIG_END
,
NULL
,
0
,
category
))
<
0
)
return
res
;
/*endif*/
...
...
@@ -981,33 +1000,24 @@ static int stream_hdlc(t38_terminal_state_t *s)
/* We add a bit of extra time here, as with some implementations
the carrier falling too abruptly causes data loss. */
delay
=
bits_to_us
(
s
,
fe
->
hdlc_tx
.
extra_bits
);
if
(
s
->
t38_fe
.
m
s_per_tx_chunk
)
if
(
fe
->
u
s_per_tx_chunk
)
delay
+=
100000
;
/*endif*/
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
break
;
}
/*endif*/
if
(
fe
->
hdlc_tx
.
len
==
0
)
{
/* Now, how did we get here? We have finished a frame, but have no new frame to
send, and no end of transmission condition. */
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"No new frame or end transmission condition.
\n
"
);
}
/*endif*/
/* Finish the current frame off, and prepare for the next one. */
category
=
(
s
->
t38_fe
.
current_tx_data_type
==
T38_DATA_V21
)
?
T38_PACKET_CATEGORY_CONTROL_DATA
:
T38_PACKET_CATEGORY_IMAGE_DATA
;
if
((
res
=
t38_core_send_data
(
&
fe
->
t38
,
previous
,
T38_FIELD_HDLC_FCS_OK
,
NULL
,
0
,
category
))
<
0
)
return
res
;
/*endif*/
fe
->
timed_step
=
T38_TIMED_STEP_HDLC_MODEM_3
;
/* We should now wait enough time for everything to clear through an analogue modem at the far end. */
delay
=
bits_to_us
(
s
,
fe
->
hdlc_tx
.
extra_bits
);
break
;
case
T38_TIMED_STEP_HDLC_MODEM_5
:
/* Note that some boxes do not like us sending a T38_FIELD_HDLC_SIG_END at this point.
A T38_IND_NO_SIGNAL should always be OK. */
return
set_no_signal
(
s
);
delay
=
set_no_signal
(
s
);
if
(
fe
->
queued_timed_step
!=
T38_TIMED_STEP_NONE
)
{
fe
->
timed_step
=
fe
->
queued_timed_step
;
fe
->
queued_timed_step
=
T38_TIMED_STEP_NONE
;
}
/*endif*/
return
delay
;
}
/*endswitch*/
}
...
...
@@ -1035,7 +1045,7 @@ static int stream_ced(t38_terminal_state_t *s)
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
T38_IND_NO_SIGNAL
))
<
0
)
return
delay
;
/*endif*/
delay
=
20000
0
;
delay
=
(
fe
->
us_per_tx_chunk
)
?
200000
:
0
;
fe
->
next_tx_samples
=
fe
->
samples
;
break
;
case
T38_TIMED_STEP_CED_2
:
...
...
@@ -1048,7 +1058,7 @@ static int stream_ced(t38_terminal_state_t *s)
break
;
case
T38_TIMED_STEP_CED_3
:
/* End of CED */
fe
->
timed_step
=
T38_TIMED_STEP_NONE
;
fe
->
timed_step
=
fe
->
queued_timed_step
;
front_end_status
(
s
,
T30_FRONT_END_SEND_STEP_COMPLETE
);
return
0
;
}
...
...
@@ -1078,17 +1088,15 @@ static int stream_cng(t38_terminal_state_t *s)
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
T38_IND_NO_SIGNAL
))
<
0
)
return
delay
;
/*endif*/
delay
=
20000
0
;
delay
=
(
fe
->
us_per_tx_chunk
)
?
200000
:
0
;
fe
->
next_tx_samples
=
fe
->
samples
;
break
;
case
T38_TIMED_STEP_CNG_2
:
/* Initial short delay over. Send the CNG indicator. CNG persists until something
coming the other way interrupts it, or a long timeout controlled by the T.30 engine
expires. */
fe
->
timed_step
=
T38_TIMED_STEP_NONE
;
if
((
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
T38_IND_CNG
))
<
0
)
return
delay
;
/*endif*/
delay
=
t38_core_send_indicator
(
&
fe
->
t38
,
T38_IND_CNG
);
fe
->
timed_step
=
fe
->
queued_timed_step
;
fe
->
current_tx_data_type
=
T38_DATA_NONE
;
return
delay
;
}
...
...
@@ -1123,7 +1131,7 @@ SPAN_DECLARE(int) t38_terminal_send_timeout(t38_terminal_state_t *s, int samples
/*endif*/
/* Wait until the right time comes along, unless we are working in "no delays" mode, while talking to an
IAF terminal. */
if
(
fe
->
m
s_per_tx_chunk
&&
fe
->
samples
<
fe
->
next_tx_samples
)
if
(
fe
->
u
s_per_tx_chunk
&&
fe
->
samples
<
fe
->
next_tx_samples
)
return
FALSE
;
/*endif*/
/* Its time to send something */
...
...
@@ -1175,22 +1183,26 @@ static void set_rx_type(void *user_data, int type, int bit_rate, int short_train
static
void
start_tx
(
t38_terminal_front_end_state_t
*
fe
,
int
use_hdlc
)
{
int
step
;
/* The actual transmission process depends on whether we are sending at a paced manner,
for interaction with a traditional FAX machine, or streaming as fast as we can, normally
over a TCP connection to a machine directly connected to the internet. */
if
(
fe
->
ms_per_tx_chunk
)
step
=
(
use_hdlc
)
?
T38_TIMED_STEP_HDLC_MODEM
:
T38_TIMED_STEP_NON_ECM_MODEM
;
if
(
fe
->
timed_step
==
T38_TIMED_STEP_NONE
)
{
/* Start the paced packet transmission process. */
fe
->
timed_step
=
(
use_hdlc
)
?
T38_TIMED_STEP_HDLC_MODEM
:
T38_TIMED_STEP_NON_ECM_MODEM
;
if
(
fe
->
next_tx_samples
<
fe
->
samples
)
fe
->
next_tx_samples
=
fe
->
samples
;
/*endif*/
fe
->
queued_timed_step
=
T38_TIMED_STEP_NONE
;
fe
->
timed_step
=
step
;
}
else
{
/* Start the fast streaming transmission process. */
fe
->
queued_timed_step
=
step
;
}
/*endif*/
if
(
fe
->
next_tx_samples
<
fe
->
samples
)
fe
->
next_tx_samples
=
fe
->
samples
;
/*endif*/
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -1217,8 +1229,21 @@ static void set_tx_type(void *user_data, int type, int bit_rate, int short_train
fe
->
current_tx_data_type
=
T38_DATA_NONE
;
break
;
case
T30_MODEM_PAUSE
:
fe
->
next_tx_samples
=
fe
->
samples
+
ms_to_samples
(
short_train
);
fe
->
timed_step
=
T38_TIMED_STEP_PAUSE
;
if
(
s
->
t38_fe
.
us_per_tx_chunk
)
fe
->
next_tx_samples
=
fe
->
samples
+
ms_to_samples
(
short_train
);
else
fe
->
next_tx_samples
=
fe
->
samples
;
/*endif*/
if
(
fe
->
timed_step
==
T38_TIMED_STEP_NONE
)
{
fe
->
queued_timed_step
=
T38_TIMED_STEP_NONE
;
fe
->
timed_step
=
T38_TIMED_STEP_PAUSE
;
}
else
{
fe
->
queued_timed_step
=
T38_TIMED_STEP_PAUSE
;
}
/*endif*/
fe
->
current_tx_data_type
=
T38_DATA_NONE
;
break
;
case
T30_MODEM_CED
:
...
...
@@ -1316,7 +1341,7 @@ SPAN_DECLARE(void) t38_terminal_set_config(t38_terminal_state_t *s, int config)
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_CONTROL_DATA_END
,
1
);
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_IMAGE_DATA
,
1
);
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_IMAGE_DATA_END
,
1
);
s
->
t38_fe
.
m
s_per_tx_chunk
=
0
;
s
->
t38_fe
.
u
s_per_tx_chunk
=
0
;
s
->
t38_fe
.
chunking_modes
&=
~
T38_CHUNKING_SEND_REGULAR_INDICATORS
;
s
->
t38_fe
.
chunking_modes
|=
T38_CHUNKING_MERGE_FCS_WITH_DATA
;
}
...
...
@@ -1334,7 +1359,7 @@ SPAN_DECLARE(void) t38_terminal_set_config(t38_terminal_state_t *s, int config)
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_CONTROL_DATA_END
,
DATA_END_TX_COUNT
);
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_IMAGE_DATA
,
DATA_TX_COUNT
);
t38_set_redundancy_control
(
&
s
->
t38_fe
.
t38
,
T38_PACKET_CATEGORY_IMAGE_DATA_END
,
DATA_END_TX_COUNT
);
s
->
t38_fe
.
ms_per_tx_chunk
=
DEFAULT_M
S_PER_TX_CHUNK
;
s
->
t38_fe
.
us_per_tx_chunk
=
DEFAULT_U
S_PER_TX_CHUNK
;
if
((
config
&
(
T38_TERMINAL_OPTION_REGULAR_INDICATORS
|
T38_TERMINAL_OPTION_2S_REPEATING_INDICATORS
)))
s
->
t38_fe
.
chunking_modes
|=
T38_CHUNKING_SEND_REGULAR_INDICATORS
;
else
...
...
@@ -1401,6 +1426,7 @@ static int t38_terminal_t38_fe_restart(t38_terminal_state_t *t)
s
->
next_tx_samples
=
0
;
s
->
hdlc_tx
.
ptr
=
0
;
s
->
hdlc_tx
.
extra_bits
=
0
;
return
0
;
}
...
...
@@ -1424,6 +1450,7 @@ static int t38_terminal_t38_fe_init(t38_terminal_state_t *t,
s
->
rx_signal_present
=
FALSE
;
s
->
timed_step
=
T38_TIMED_STEP_NONE
;
s
->
queued_timed_step
=
T38_TIMED_STEP_NONE
;
//s->iaf = T30_IAF_MODE_T37 | T30_IAF_MODE_T38;
s
->
iaf
=
T30_IAF_MODE_T38
;
...
...
@@ -1432,6 +1459,7 @@ static int t38_terminal_t38_fe_init(t38_terminal_state_t *t,
s
->
chunking_modes
=
T38_CHUNKING_ALLOW_TEP_TIME
;
s
->
hdlc_tx
.
ptr
=
0
;
s
->
hdlc_tx
.
extra_bits
=
0
;
return
0
;
}
...
...
libs/spandsp/src/v22bis_rx.c
浏览文件 @
13fbaf7e
...
...
@@ -69,9 +69,9 @@
#include "spandsp/private/logging.h"
#include "spandsp/private/v22bis.h"
#if defined(SPANDSP_USE_FIXED_POINT)
#include "v22bis_rx_1200_f
ixed
_rrc.h"
#include "v22bis_rx_2400_f
ixed
_rrc.h"
#if defined(SPANDSP_USE_FIXED_POINT
x
)
#include "v22bis_rx_1200_f
loating
_rrc.h"
#include "v22bis_rx_2400_f
loating
_rrc.h"
#else
#include "v22bis_rx_1200_floating_rrc.h"
#include "v22bis_rx_2400_floating_rrc.h"
...
...
@@ -79,11 +79,6 @@
#define ms_to_symbols(t) (((t)*600)/1000)
#if defined(SPANDSP_USE_FIXED_POINT)
#define FP_FACTOR 4096
#define FP_SHIFT_FACTOR 12
#endif
/*! The adaption rate coefficient for the equalizer */
#define EQUALIZER_DELTA 0.25f
/*! The number of phase shifted coefficient set for the pulse shaping/bandpass filter */
...
...
@@ -172,28 +167,24 @@ void v22bis_report_status_change(v22bis_state_t *s, int status)
}
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
SPAN_DECLARE
(
int
)
v22bis_rx_equalizer_state
(
v22bis_state_t
*
s
,
complexi16_t
**
coeffs
)
#else
SPAN_DECLARE
(
int
)
v22bis_rx_equalizer_state
(
v22bis_state_t
*
s
,
complexf_t
**
coeffs
)
#endif
{
*
coeffs
=
s
->
rx
.
eq_coeff
;
return
V22BIS_EQUALIZER_LEN
;
return
2
*
V22BIS_EQUALIZER_LEN
+
1
;
}
/*- End of function --------------------------------------------------------*/
void
v22bis_equalizer_coefficient_reset
(
v22bis_state_t
*
s
)
{
/* Start with an equalizer based on everything being perfect */
#if defined(SPANDSP_USE_FIXED_POINT)
cvec_zeroi16
(
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
);
s
->
rx
.
eq_coeff
[
V22BIS_EQUALIZER_
PRE_LEN
]
=
complex_seti16
(
FP_Q_4_12
(
3
.
0
),
FP_Q_4_12
(
0
.
0
)
);
s
->
rx
.
eq_delta
=
32768
.
0
f
*
EQUALIZER_DELTA
/
V22BIS_EQUALIZER_LEN
;
#if defined(SPANDSP_USE_FIXED_POINT
x
)
cvec_zeroi16
(
s
->
rx
.
eq_coeff
,
2
*
V22BIS_EQUALIZER_LEN
+
1
);
s
->
rx
.
eq_coeff
[
V22BIS_EQUALIZER_
LEN
]
=
complex_seti16
(
3
*
FP_FACTOR
,
0
*
FP_FACTOR
);
s
->
rx
.
eq_delta
=
32768
.
0
f
*
EQUALIZER_DELTA
/
(
2
*
V22BIS_EQUALIZER_LEN
+
1
)
;
#else
cvec_zerof
(
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
);
s
->
rx
.
eq_coeff
[
V22BIS_EQUALIZER_
PRE_
LEN
]
=
complex_setf
(
3
.
0
f
,
0
.
0
f
);
s
->
rx
.
eq_delta
=
EQUALIZER_DELTA
/
V22BIS_EQUALIZER_LEN
;
cvec_zerof
(
s
->
rx
.
eq_coeff
,
2
*
V22BIS_EQUALIZER_LEN
+
1
);
s
->
rx
.
eq_coeff
[
V22BIS_EQUALIZER_LEN
]
=
complex_setf
(
3
.
0
f
,
0
.
0
f
);
s
->
rx
.
eq_delta
=
EQUALIZER_DELTA
/
(
2
*
V22BIS_EQUALIZER_LEN
+
1
)
;
#endif
}
/*- End of function --------------------------------------------------------*/
...
...
@@ -201,68 +192,63 @@ void v22bis_equalizer_coefficient_reset(v22bis_state_t *s)
static
void
equalizer_reset
(
v22bis_state_t
*
s
)
{
v22bis_equalizer_coefficient_reset
(
s
);
#if defined(SPANDSP_USE_FIXED_POINT)
cvec_zeroi16
(
s
->
rx
.
eq_buf
,
V22BIS_EQUALIZER_
LEN
);
#if defined(SPANDSP_USE_FIXED_POINT
x
)
cvec_zeroi16
(
s
->
rx
.
eq_buf
,
V22BIS_EQUALIZER_
MASK
+
1
);
#else
cvec_zerof
(
s
->
rx
.
eq_buf
,
V22BIS_EQUALIZER_
LEN
);
cvec_zerof
(
s
->
rx
.
eq_buf
,
V22BIS_EQUALIZER_
MASK
+
1
);
#endif
s
->
rx
.
eq_put_step
=
20
-
1
;
s
->
rx
.
eq_step
=
0
;
}
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
__inline__
complexi16_t
equalizer_get
(
v22bis_state_t
*
s
)
static
complexf_t
equalizer_get
(
v22bis_state_t
*
s
)
{
complexi32_t
zz
;
complexi16_t
z
;
int
i
;
int
p
;
complexf_t
z
;
complexf_t
z1
;
/* Get the next equalized value. */
zz
=
cvec_circular_dot_prodi16
(
s
->
rx
.
eq_buf
,
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
,
s
->
rx
.
eq_step
);
z
.
re
=
zz
.
re
>>
FP_SHIFT_FACTOR
;
z
.
im
=
zz
.
im
>>
FP_SHIFT_FACTOR
;
z
=
complex_setf
(
0
.
0
f
,
0
.
0
f
);
p
=
s
->
rx
.
eq_step
-
1
;
for
(
i
=
0
;
i
<
2
*
V22BIS_EQUALIZER_LEN
+
1
;
i
++
)
{
p
=
(
p
-
1
)
&
V22BIS_EQUALIZER_MASK
;
z1
=
complex_mulf
(
&
s
->
rx
.
eq_coeff
[
i
],
&
s
->
rx
.
eq_buf
[
p
]);
z
=
complex_addf
(
&
z
,
&
z1
);
}
return
z
;
}
#else
static
__inline__
complexf_t
equalizer_get
(
v22bis_state_t
*
s
)
{
/* Get the next equalized value. */
return
cvec_circular_dot_prodf
(
s
->
rx
.
eq_buf
,
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
,
s
->
rx
.
eq_step
);
}
#endif
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
void
tune_equalizer
(
v22bis_state_t
*
s
,
const
complexi16_t
*
z
,
const
complexi16_t
*
target
)
{
complexi16_t
err
;
/* Find the x and y mismatch from the exact constellation position. */
err
.
re
=
target
->
re
*
FP_FACTOR
-
z
->
re
;
err
.
im
=
target
->
im
*
FP_FACTOR
-
z
->
im
;
err
.
re
=
((
int32_t
)
err
.
re
*
s
->
rx
.
eq_delta
)
>>
15
;
err
.
im
=
((
int32_t
)
err
.
im
*
s
->
rx
.
eq_delta
)
>>
15
;
cvec_circular_lmsi16
(
s
->
rx
.
eq_buf
,
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
,
s
->
rx
.
eq_step
,
&
err
);
}
#else
static
void
tune_equalizer
(
v22bis_state_t
*
s
,
const
complexf_t
*
z
,
const
complexf_t
*
target
)
{
complexf_t
err
;
int
i
;
int
p
;
complexf_t
ez
;
complexf_t
z1
;
/* Find the x and y mismatch from the exact constellation position. */
err
=
complex_subf
(
target
,
z
);
err
.
re
*=
s
->
rx
.
eq_delta
;
err
.
im
*=
s
->
rx
.
eq_delta
;
cvec_circular_lmsf
(
s
->
rx
.
eq_buf
,
s
->
rx
.
eq_coeff
,
V22BIS_EQUALIZER_LEN
,
s
->
rx
.
eq_step
,
&
err
);
ez
=
complex_subf
(
target
,
z
);
ez
.
re
*=
s
->
rx
.
eq_delta
;
ez
.
im
*=
s
->
rx
.
eq_delta
;
p
=
s
->
rx
.
eq_step
-
1
;
for
(
i
=
0
;
i
<
2
*
V22BIS_EQUALIZER_LEN
+
1
;
i
++
)
{
p
=
(
p
-
1
)
&
V22BIS_EQUALIZER_MASK
;
z1
=
complex_conjf
(
&
s
->
rx
.
eq_buf
[
p
]);
z1
=
complex_mulf
(
&
ez
,
&
z1
);
s
->
rx
.
eq_coeff
[
i
]
=
complex_addf
(
&
s
->
rx
.
eq_coeff
[
i
],
&
z1
);
/* If we don't leak a little bit we seem to get some wandering adaption */
s
->
rx
.
eq_coeff
[
i
].
re
*=
0
.
9999
f
;
s
->
rx
.
eq_coeff
[
i
].
im
*=
0
.
9999
f
;
}
}
#endif
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
__inline__
void
track_carrier
(
v22bis_state_t
*
s
,
const
complexi16_t
*
z
,
const
complexi16_t
*
target
)
#else
static
__inline__
void
track_carrier
(
v22bis_state_t
*
s
,
const
complexf_t
*
z
,
const
complexf_t
*
target
)
#endif
{
float
error
;
...
...
@@ -350,69 +336,40 @@ static int decode_baudx(v22bis_state_t *s, int nearest)
static
__inline__
void
symbol_sync
(
v22bis_state_t
*
s
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
int32_t
p
;
int32_t
q
;
complexi16_t
zz
;
complexi16_t
a
;
complexi16_t
b
;
complexi16_t
c
;
#else
float
p
;
float
q
;
complexf_t
zz
;
complexf_t
a
;
complexf_t
b
;
complexf_t
c
;
#endif
int
aa
[
3
];
int
i
;
int
j
;
/* This routine adapts the position of the half baud samples entering the equalizer. */
/* Perform a Gardner test for baud alignment on the three most recent samples. */
for
(
i
=
0
,
j
=
s
->
rx
.
eq_step
;
i
<
3
;
i
++
)
{
if
(
--
j
<
0
)
j
=
V22BIS_EQUALIZER_LEN
-
1
;
aa
[
i
]
=
j
;
}
if
(
s
->
rx
.
sixteen_way_decisions
)
{
p
=
s
->
rx
.
eq_buf
[
aa
[
2
]].
re
-
s
->
rx
.
eq_buf
[
aa
[
0
]].
re
;
p
*=
s
->
rx
.
eq_buf
[
aa
[
1
]].
re
;
p
=
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
3
)
&
V22BIS_EQUALIZER_MASK
].
re
-
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
1
)
&
V22BIS_EQUALIZER_MASK
].
re
;
p
*=
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
2
)
&
V22BIS_EQUALIZER_MASK
].
re
;
q
=
s
->
rx
.
eq_buf
[
aa
[
2
]].
im
-
s
->
rx
.
eq_buf
[
aa
[
0
]].
im
;
q
*=
s
->
rx
.
eq_buf
[
aa
[
1
]].
im
;
q
=
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
3
)
&
V22BIS_EQUALIZER_MASK
].
im
-
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
1
)
&
V22BIS_EQUALIZER_MASK
].
im
;
q
*=
s
->
rx
.
eq_buf
[(
s
->
rx
.
eq_step
-
2
)
&
V22BIS_EQUALIZER_MASK
].
im
;
}
else
{
/* Rotate the points to the 45 degree positions, to maximise the effectiveness of
the Gardner algorithm. This is particularly significant at the start of operation
to pull things in quickly. */
#if defined(SPANDSP_USE_FIXED_POINT)
zz
=
complex_seti16
(
FP_Q_6_10
(
0
.
894427
),
FP_Q_6_10
(
0
.
44721
f
));
a
=
complex_muli16
(
&
s
->
rx
.
eq_buf
[
aa
[
2
]],
&
zz
);
b
=
complex_muli16
(
&
s
->
rx
.
eq_buf
[
aa
[
1
]],
&
zz
);
c
=
complex_muli16
(
&
s
->
rx
.
eq_buf
[
aa
[
0
]],
&
zz
);
p
=
(
a
.
re
-
c
.
re
)
*
b
.
re
;
q
=
(
a
.
im
-
c
.
im
)
*
b
.
im
;
#else
zz
=
complex_setf
(
0
.
894427
,
0
.
44721
f
);
a
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
aa
[
2
]
],
&
zz
);
b
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
aa
[
1
]
],
&
zz
);
c
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
aa
[
0
]
],
&
zz
);
a
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
(
s
->
rx
.
eq_step
-
3
)
&
V22BIS_EQUALIZER_MASK
],
&
zz
);
b
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
(
s
->
rx
.
eq_step
-
2
)
&
V22BIS_EQUALIZER_MASK
],
&
zz
);
c
=
complex_mulf
(
&
s
->
rx
.
eq_buf
[
(
s
->
rx
.
eq_step
-
1
)
&
V22BIS_EQUALIZER_MASK
],
&
zz
);
p
=
(
a
.
re
-
c
.
re
)
*
b
.
re
;
q
=
(
a
.
im
-
c
.
im
)
*
b
.
im
;
#endif
}
#if defined(SPANDSP_USE_FIXED_POINT)
s
->
rx
.
gardner_integrate
+=
(
p
+
q
>
0
)
?
s
->
rx
.
gardner_step
:
-
s
->
rx
.
gardner_step
;
#else
s
->
rx
.
gardner_integrate
+=
(
p
+
q
>
0
.
0
f
)
?
s
->
rx
.
gardner_step
:
-
s
->
rx
.
gardner_step
;
#endif
if
(
abs
(
s
->
rx
.
gardner_integrate
)
>=
16
)
{
...
...
@@ -429,21 +386,11 @@ static __inline__ void symbol_sync(v22bis_state_t *s)
}
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
void
process_half_baud
(
v22bis_state_t
*
s
,
const
complexi16_t
*
sample
)
#else
static
void
process_half_baud
(
v22bis_state_t
*
s
,
const
complexf_t
*
sample
)
#endif
{
#if defined(SPANDSP_USE_FIXED_POINT)
complexi16_t
z
;
complexi16_t
zz
;
const
complexi16_t
*
target
;
#else
complexf_t
z
;
complexf_t
zz
;
const
complexf_t
*
target
;
#endif
int
re
;
int
im
;
int
nearest
;
...
...
@@ -456,8 +403,7 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
at this time. */
s
->
rx
.
eq_buf
[
s
->
rx
.
eq_step
]
=
z
;
if
(
++
s
->
rx
.
eq_step
>=
V22BIS_EQUALIZER_LEN
)
s
->
rx
.
eq_step
=
0
;
s
->
rx
.
eq_step
=
(
s
->
rx
.
eq_step
+
1
)
&
V22BIS_EQUALIZER_MASK
;
/* On alternate insertions we have a whole baud and must process it. */
if
((
s
->
rx
.
baud_phase
^=
1
))
...
...
@@ -470,18 +416,6 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
/* Find the constellation point */
if
(
s
->
rx
.
sixteen_way_decisions
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
re
=
(
int
)
(
z
.
re
+
FP_Q_6_10
(
3
.
0
f
));
if
(
re
>
5
)
re
=
5
;
else
if
(
re
<
0
)
re
=
0
;
im
=
(
int
)
(
z
.
im
+
FP_Q_6_10
(
3
.
0
f
));
if
(
im
>
5
)
im
=
5
;
else
if
(
im
<
0
)
im
=
0
;
#else
re
=
(
int
)
(
z
.
re
+
3
.
0
f
);
if
(
re
>
5
)
re
=
5
;
...
...
@@ -492,19 +426,13 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
im
=
5
;
else
if
(
im
<
0
)
im
=
0
;
#endif
nearest
=
space_map_v22bis
[
re
][
im
];
}
else
{
/* Rotate to 45 degrees, to make the slicing trivial */
#if defined(SPANDSP_USE_FIXED_POINT)
zz
=
complex_seti16
(
FP_Q_4_12
(
0
.
894427
),
FP_Q_4_12
(
0
.
44721
f
));
zz
=
complex_muli16
(
&
z
,
&
zz
);
#else
zz
=
complex_setf
(
0
.
894427
,
0
.
44721
f
);
zz
=
complex_mulf
(
&
z
,
&
zz
);
#endif
nearest
=
0x01
;
if
(
zz
.
re
<
0
.
0
f
)
nearest
|=
0x04
;
...
...
@@ -562,7 +490,10 @@ static void process_half_baud(v22bis_state_t *s, const complexf_t *sample)
error could be higher. */
s
->
rx
.
gardner_step
=
4
;
s
->
rx
.
pattern_repeats
=
0
;
s
->
rx
.
training
=
(
s
->
calling_party
)
?
V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES
:
V22BIS_RX_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200
;
if
(
s
->
calling_party
)
s
->
rx
.
training
=
V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES
;
else
s
->
rx
.
training
=
V22BIS_RX_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200
;
/* Be pessimistic and see what the handshake brings */
s
->
negotiated_bit_rate
=
1200
;
break
;
...
...
@@ -764,21 +695,12 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
{
int
i
;
int
step
;
#if defined(SPANDSP_USE_FIXED_POINT)
complexi16_t
z
;
complexi16_t
zz
;
complexi16_t
sample
;
int32_t
ii
;
int32_t
qq
;
float
vv
;
#else
complexf_t
z
;
complexf_t
zz
;
int32_t
power
;
complexf_t
sample
;
float
ii
;
float
qq
;
#endif
int32_t
power
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
...
...
@@ -795,7 +717,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
if
(
s
->
calling_party
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#else
ii
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#endif
...
...
@@ -803,7 +725,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
else
{
#if defined(SPANDSP_USE_FIXED_POINT)
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#else
ii
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
6
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#endif
...
...
@@ -831,25 +753,11 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
{
/* Only spend effort processing this data if the modem is not
parked, after a training failure. */
#if defined(SPANDSP_USE_FIXED_POINT)
z
=
dds_complexi16
(
&
s
->
rx
.
carrier_phase
,
s
->
rx
.
carrier_phase_rate
);
#else
z
=
dds_complexf
(
&
s
->
rx
.
carrier_phase
,
s
->
rx
.
carrier_phase_rate
);
#endif
if
(
s
->
rx
.
training
==
V22BIS_RX_TRAINING_STAGE_SYMBOL_ACQUISITION
)
{
/* Only AGC during the initial symbol acquisition, and then lock the gain. */
#if defined(SPANDSP_USE_FIXED_POINT)
vv
=
0
.
18
f
*
3
.
60
f
/
sqrtf
(
power
);
if
(
vv
>
32767
.
0
f
)
s
->
rx
.
agc_scaling
=
32767
;
else
if
(
vv
>
-
32768
.
0
f
)
s
->
rx
.
agc_scaling
=
-
32768
;
else
s
->
rx
.
agc_scaling
=
vv
;
#else
s
->
rx
.
agc_scaling
=
0
.
18
f
*
3
.
60
f
/
sqrtf
(
power
);
#endif
}
/* Put things into the equalization buffer at T/2 rate. The Gardner algorithm
will fiddle the step to align this with the symbols. */
...
...
@@ -866,8 +774,8 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
if
(
s
->
calling_party
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
qq
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
qq
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#else
ii
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
qq
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_2400_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
...
...
@@ -876,20 +784,15 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx(v22bis_state_t *s, const int16_t amp[], int l
else
{
#if defined(SPANDSP_USE_FIXED_POINT)
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
qq
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
)
>>
15
;
ii
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
qq
=
vec_circular_dot_prodi16
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#else
ii
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_re
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
qq
=
vec_circular_dot_prodf
(
s
->
rx
.
rrc_filter
,
rx_pulseshaper_1200_im
[
step
],
V22BIS_RX_FILTER_STEPS
,
s
->
rx
.
rrc_filter_step
);
#endif
}
#if defined(SPANDSP_USE_FIXED_POINT)
sample
.
re
=
((
int32_t
)
ii
*
s
->
rx
.
agc_scaling
)
>>
10
;
sample
.
im
=
((
int32_t
)
qq
*
s
->
rx
.
agc_scaling
)
>>
10
;
#else
sample
.
re
=
ii
*
s
->
rx
.
agc_scaling
;
sample
.
im
=
qq
*
s
->
rx
.
agc_scaling
;
#endif
/* Shift to baseband - since this is done in a full complex form, the
result is clean, and requires no further filtering apart from the
equalizer. */
...
...
@@ -914,7 +817,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx_fillin(v22bis_state_t *s, int len)
return
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
#if defined(SPANDSP_USE_FIXED_POINT
x
)
dds_advance
(
&
s
->
rx
.
carrier_phase
,
s
->
rx
.
carrier_phase_rate
);
#else
dds_advancef
(
&
s
->
rx
.
carrier_phase
,
s
->
rx
.
carrier_phase_rate
);
...
...
@@ -927,7 +830,7 @@ SPAN_DECLARE_NONSTD(int) v22bis_rx_fillin(v22bis_state_t *s, int len)
int
v22bis_rx_restart
(
v22bis_state_t
*
s
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
#if defined(SPANDSP_USE_FIXED_POINT
x
)
vec_zeroi16
(
s
->
rx
.
rrc_filter
,
sizeof
(
s
->
rx
.
rrc_filter
)
/
sizeof
(
s
->
rx
.
rrc_filter
[
0
]));
#else
vec_zerof
(
s
->
rx
.
rrc_filter
,
sizeof
(
s
->
rx
.
rrc_filter
)
/
sizeof
(
s
->
rx
.
rrc_filter
[
0
]));
...
...
@@ -958,13 +861,8 @@ int v22bis_rx_restart(v22bis_state_t *s)
s
->
rx
.
training_error
=
0
.
0
f
;
s
->
rx
.
total_baud_timing_correction
=
0
;
/* We want the carrier to pull in faster on the answerer side, as it has very little time to adapt. */
#if defined(SPANDSP_USE_FIXED_POINT)
s
->
rx
.
carrier_track_i
=
(
s
->
calling_party
)
?
8000
:
40000
;
s
->
rx
.
carrier_track_p
=
8000000
;
#else
s
->
rx
.
carrier_track_i
=
(
s
->
calling_party
)
?
8000
.
0
f
:
40000
.
0
f
;
s
->
rx
.
carrier_track_p
=
8000000
.
0
f
;
#endif
s
->
negotiated_bit_rate
=
1200
;
...
...
libs/spandsp/src/v22bis_tx.c
浏览文件 @
13fbaf7e
...
...
@@ -62,7 +62,7 @@
#include "spandsp/private/logging.h"
#include "spandsp/private/v22bis.h"
#if defined(SPANDSP_USE_FIXED_POINT)
#if defined(SPANDSP_USE_FIXED_POINT
x
)
#include "v22bis_tx_fixed_rrc.h"
#else
#include "v22bis_tx_floating_rrc.h"
...
...
@@ -246,28 +246,24 @@ static const int phase_steps[4] =
1
,
0
,
2
,
3
};
#if defined(SPANDSP_USE_FIXED_POINT)
const
complexi16_t
v22bis_constellation
[
16
]
=
#else
const
complexf_t
v22bis_constellation
[
16
]
=
#endif
{
{
1
,
1
},
{
3
,
1
},
/* 1200bps 00 */
{
1
,
3
},
{
3
,
3
},
{
-
1
,
1
},
{
-
1
,
3
},
/* 1200bps 01 */
{
-
3
,
1
},
{
-
3
,
3
},
{
-
1
,
-
1
},
{
-
3
,
-
1
},
/* 1200bps 10 */
{
-
1
,
-
3
},
{
-
3
,
-
3
},
{
1
,
-
1
},
{
1
,
-
3
},
/* 1200bps 11 */
{
3
,
-
1
},
{
3
,
-
3
}
{
1
.
0
f
,
1
.
0
f
},
{
3
.
0
f
,
1
.
0
f
},
/* 1200bps 00 */
{
1
.
0
f
,
3
.
0
f
},
{
3
.
0
f
,
3
.
0
f
},
{
-
1
.
0
f
,
1
.
0
f
},
{
-
1
.
0
f
,
3
.
0
f
},
/* 1200bps 01 */
{
-
3
.
0
f
,
1
.
0
f
},
{
-
3
.
0
f
,
3
.
0
f
},
{
-
1
.
0
f
,
-
1
.
0
f
},
{
-
3
.
0
f
,
-
1
.
0
f
},
/* 1200bps 10 */
{
-
1
.
0
f
,
-
3
.
0
f
},
{
-
3
.
0
f
,
-
3
.
0
f
},
{
1
.
0
f
,
-
1
.
0
f
},
{
1
.
0
f
,
-
3
.
0
f
},
/* 1200bps 11 */
{
3
.
0
f
,
-
1
.
0
f
},
{
3
.
0
f
,
-
3
.
0
f
}
};
static
int
fake_get_bit
(
void
*
user_data
)
...
...
@@ -312,17 +308,9 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s)
}
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
complexi16_t
training_get
(
v22bis_state_t
*
s
)
#else
static
complexf_t
training_get
(
v22bis_state_t
*
s
)
#endif
{
#if defined(SPANDSP_USE_FIXED_POINT)
static
const
complexi16_t
zero
=
{
0
,
0
};
#else
static
const
complexf_t
zero
=
{
0
.
0
f
,
0
.
0
f
};
#endif
complexf_t
z
;
int
bits
;
/* V.22bis training sequence */
...
...
@@ -341,17 +329,20 @@ static complexf_t training_get(v22bis_state_t *s)
case
V22BIS_TX_TRAINING_STAGE_INITIAL_SILENCE
:
/* Silence */
s
->
tx
.
constellation_state
=
0
;
return
zero
;
z
=
complex_setf
(
0
.
0
f
,
0
.
0
f
);
break
;
case
V22BIS_TX_TRAINING_STAGE_U11
:
/* Send continuous unscrambled ones at 1200bps (i.e. 270 degree phase steps). */
/* Only the answering modem sends unscrambled ones. It is the first thing exchanged between the modems. */
s
->
tx
.
constellation_state
=
(
s
->
tx
.
constellation_state
+
phase_steps
[
3
])
&
3
;
return
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
];
z
=
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
];
break
;
case
V22BIS_TX_TRAINING_STAGE_U0011
:
/* Continuous unscrambled double dibit 00 11 at 1200bps. This is termed the S1 segment in
the V.22bis spec. It is only sent to request or accept 2400bps mode, and lasts 100+-3ms. After this
timed burst, we unconditionally change to sending scrambled ones at 1200bps. */
s
->
tx
.
constellation_state
=
(
s
->
tx
.
constellation_state
+
phase_steps
[
3
*
(
s
->
tx
.
training_count
&
1
)])
&
3
;
z
=
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
];
if
(
++
s
->
tx
.
training_count
>=
ms_to_symbols
(
100
))
{
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"+++ starting S11 after U0011
\n
"
);
...
...
@@ -366,7 +357,7 @@ static complexf_t training_get(v22bis_state_t *s)
s
->
tx
.
training
=
V22BIS_TX_TRAINING_STAGE_TIMED_S11
;
}
}
return
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
]
;
break
;
case
V22BIS_TX_TRAINING_STAGE_TIMED_S11
:
/* A timed period of scrambled ones at 1200bps. */
if
(
++
s
->
tx
.
training_count
>=
ms_to_symbols
(
756
))
...
...
@@ -392,7 +383,8 @@ static complexf_t training_get(v22bis_state_t *s)
bits
=
scramble
(
s
,
1
);
bits
=
(
bits
<<
1
)
|
scramble
(
s
,
1
);
s
->
tx
.
constellation_state
=
(
s
->
tx
.
constellation_state
+
phase_steps
[
bits
])
&
3
;
return
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
];
z
=
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
0x01
];
break
;
case
V22BIS_TX_TRAINING_STAGE_S1111
:
/* Scrambled ones at 2400bps. We send a timed 200ms burst, and switch to normal operation at 2400bps */
bits
=
scramble
(
s
,
1
);
...
...
@@ -400,6 +392,7 @@ static complexf_t training_get(v22bis_state_t *s)
s
->
tx
.
constellation_state
=
(
s
->
tx
.
constellation_state
+
phase_steps
[
bits
])
&
3
;
bits
=
scramble
(
s
,
1
);
bits
=
(
bits
<<
1
)
|
scramble
(
s
,
1
);
z
=
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
bits
];
if
(
++
s
->
tx
.
training_count
>=
ms_to_symbols
(
200
))
{
/* We have completed training. Now handle some real work. */
...
...
@@ -409,23 +402,18 @@ static complexf_t training_get(v22bis_state_t *s)
v22bis_report_status_change
(
s
,
SIG_STATUS_TRAINING_SUCCEEDED
);
s
->
tx
.
current_get_bit
=
s
->
get_bit
;
}
return
v22bis_constellation
[(
s
->
tx
.
constellation_state
<<
2
)
|
bits
];
break
;
case
V22BIS_TX_TRAINING_STAGE_PARKED
:
default:
z
=
complex_setf
(
0
.
0
f
,
0
.
0
f
);
break
;
}
return
z
ero
;
return
z
;
}
/*- End of function --------------------------------------------------------*/
#if defined(SPANDSP_USE_FIXED_POINT)
static
complexi16_t
getbaud
(
v22bis_state_t
*
s
)
#else
static
complexf_t
getbaud
(
v22bis_state_t
*
s
)
#endif
{
#if defined(SPANDSP_USE_FIXED_POINT)
static
const
complexi16_t
zero
=
{
0
,
0
};
#else
static
const
complexf_t
zero
=
{
0
.
0
f
,
0
.
0
f
};
#endif
int
bits
;
if
(
s
->
tx
.
training
)
...
...
@@ -440,7 +428,7 @@ static complexf_t getbaud(v22bis_state_t *s)
if
(
s
->
tx
.
shutdown
)
{
if
(
++
s
->
tx
.
shutdown
>
10
)
return
zero
;
return
complex_setf
(
0
.
0
f
,
0
.
0
f
)
;
}
/* The first two bits define the quadrant */
bits
=
get_scrambled_bit
(
s
);
...
...
@@ -462,18 +450,11 @@ static complexf_t getbaud(v22bis_state_t *s)
SPAN_DECLARE_NONSTD
(
int
)
v22bis_tx
(
v22bis_state_t
*
s
,
int16_t
amp
[],
int
len
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
complexi16_t
v
;
complexi32_t
x
;
complexi32_t
z
;
int16_t
iamp
;
#else
complexf_t
v
;
complexf_t
x
;
complexf_t
z
;
float
famp
;
#endif
int
i
;
int
sample
;
float
famp
;
if
(
s
->
tx
.
shutdown
>
10
)
return
0
;
...
...
@@ -482,41 +463,28 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
if
((
s
->
tx
.
baud_phase
+=
3
)
>=
40
)
{
s
->
tx
.
baud_phase
-=
40
;
v
=
getbaud
(
s
);
s
->
tx
.
rrc_filter_re
[
s
->
tx
.
rrc_filter_step
]
=
v
.
re
;
s
->
tx
.
rrc_filter_im
[
s
->
tx
.
rrc_filter_step
]
=
v
.
im
;
s
->
tx
.
rrc_filter
[
s
->
tx
.
rrc_filter_step
]
=
s
->
tx
.
rrc_filter
[
s
->
tx
.
rrc_filter_step
+
V22BIS_TX_FILTER_STEPS
]
=
getbaud
(
s
);
if
(
++
s
->
tx
.
rrc_filter_step
>=
V22BIS_TX_FILTER_STEPS
)
s
->
tx
.
rrc_filter_step
=
0
;
}
#if defined(SPANDSP_USE_FIXED_POINT)
x
.
re
=
vec_circular_dot_prodi16
(
s
->
tx
.
rrc_filter_re
,
tx_pulseshaper
[
TX_PULSESHAPER_COEFF_SETS
-
1
-
s
->
tx
.
baud_phase
],
V22BIS_TX_FILTER_STEPS
,
s
->
tx
.
rrc_filter_step
)
>>
4
;
x
.
im
=
vec_circular_dot_prodi16
(
s
->
tx
.
rrc_filter_im
,
tx_pulseshaper
[
TX_PULSESHAPER_COEFF_SETS
-
1
-
s
->
tx
.
baud_phase
],
V22BIS_TX_FILTER_STEPS
,
s
->
tx
.
rrc_filter_step
)
>>
4
;
/* Now create and modulate the carrier */
z
=
dds_complexi32
(
&
s
->
tx
.
carrier_phase
,
s
->
tx
.
carrier_phase_rate
);
iamp
=
(
x
.
re
*
z
.
re
-
x
.
im
*
z
.
im
)
>>
15
;
iamp
=
(
int16_t
)
(((
int32_t
)
iamp
*
s
->
tx
.
gain
)
>>
11
);
if
(
s
->
tx
.
guard_phase_rate
&&
(
s
->
tx
.
rrc_filter_re
[
s
->
tx
.
rrc_filter_step
]
!=
0
||
s
->
tx
.
rrc_filter_im
[
s
->
tx
.
rrc_filter_step
]
!=
0
))
/* Root raised cosine pulse shaping at baseband */
x
=
complex_setf
(
0
.
0
f
,
0
.
0
f
);
for
(
i
=
0
;
i
<
V22BIS_TX_FILTER_STEPS
;
i
++
)
{
/* Add the guard tone */
iamp
+=
dds_mod
(
&
s
->
tx
.
guard_phase
,
s
->
tx
.
guard_phase_rate
,
s
->
tx
.
guard_tone_gain
,
0
)
;
x
.
re
+=
tx_pulseshaper
[
39
-
s
->
tx
.
baud_phase
][
i
]
*
s
->
tx
.
rrc_filter
[
i
+
s
->
tx
.
rrc_filter_step
].
re
;
x
.
im
+=
tx_pulseshaper
[
39
-
s
->
tx
.
baud_phase
][
i
]
*
s
->
tx
.
rrc_filter
[
i
+
s
->
tx
.
rrc_filter_step
].
im
;
}
/* Don't bother saturating. We should never clip. */
amp
[
sample
]
=
iamp
;
#else
/* Root raised cosine pulse shaping at baseband */
x
.
re
=
vec_circular_dot_prodf
(
s
->
tx
.
rrc_filter_re
,
tx_pulseshaper
[
TX_PULSESHAPER_COEFF_SETS
-
1
-
s
->
tx
.
baud_phase
],
V22BIS_TX_FILTER_STEPS
,
s
->
tx
.
rrc_filter_step
);
x
.
im
=
vec_circular_dot_prodf
(
s
->
tx
.
rrc_filter_im
,
tx_pulseshaper
[
TX_PULSESHAPER_COEFF_SETS
-
1
-
s
->
tx
.
baud_phase
],
V22BIS_TX_FILTER_STEPS
,
s
->
tx
.
rrc_filter_step
);
/* Now create and modulate the carrier */
z
=
dds_complexf
(
&
(
s
->
tx
.
carrier_phase
),
s
->
tx
.
carrier_phase_rate
);
famp
=
(
x
.
re
*
z
.
re
-
x
.
im
*
z
.
im
)
*
s
->
tx
.
gain
;
if
(
s
->
tx
.
guard_phase_rate
&&
(
s
->
tx
.
rrc_filter
_re
[
s
->
tx
.
rrc_filter_step
]
!=
0
.
0
f
||
s
->
tx
.
rrc_filter_im
[
s
->
tx
.
rrc_filter_step
]
!=
0
.
0
f
))
if
(
s
->
tx
.
guard_phase_rate
&&
(
s
->
tx
.
rrc_filter
[
s
->
tx
.
rrc_filter_step
].
re
!=
0
.
0
f
||
s
->
tx
.
rrc_filter
[
s
->
tx
.
rrc_filter_step
].
im
!=
0
.
0
f
))
{
/* Add the guard tone */
famp
+=
dds_modf
(
&
s
->
tx
.
guard_phase
,
s
->
tx
.
guard_phase_rate
,
s
->
tx
.
guard_tone_gain
,
0
);
famp
+=
dds_modf
(
&
(
s
->
tx
.
guard_phase
),
s
->
tx
.
guard_phase_rate
,
s
->
tx
.
guard_level
,
0
);
}
/* Don't bother saturating. We should never clip. */
amp
[
sample
]
=
(
int16_t
)
lfastrintf
(
famp
);
#endif
}
return
sample
;
}
...
...
@@ -524,49 +492,34 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
SPAN_DECLARE
(
void
)
v22bis_tx_power
(
v22bis_state_t
*
s
,
float
power
)
{
float
sig_power
;
float
guard_tone_power
;
float
sig_gain
;
float
guard_tone_gain
;
float
l
;
/* If is there is a guard tone we need to scale down the signal power a bit, so the aggregate of the signal
and guard tone power is the specified power. */
if
(
s
->
tx
.
guard_phase_rate
==
dds_phase_ratef
(
550
.
0
f
))
{
sig_power
=
power
-
1
.
0
f
;
guard_tone_power
=
sig_power
-
3
.
0
f
;
l
=
1
.
6
f
*
powf
(
10
.
0
f
,
(
power
-
1
.
0
f
-
DBM0_MAX_POWER
)
/
20
.
0
f
);
s
->
tx
.
gain
=
l
*
32768
.
0
f
/
(
TX_PULSESHAPER_GAIN
*
3
.
0
f
);
l
=
powf
(
10
.
0
f
,
(
power
-
1
.
0
f
-
3
.
0
f
-
DBM0_MAX_POWER
)
/
20
.
0
f
);
s
->
tx
.
guard_level
=
l
*
32768
.
0
f
;
}
else
if
(
s
->
tx
.
guard_phase_rate
==
dds_phase_ratef
(
1800
.
0
f
))
{
sig_power
=
power
-
0
.
55
f
;
guard_tone_power
=
sig_power
-
6
.
0
f
;
l
=
1
.
6
f
*
powf
(
10
.
0
f
,
(
power
-
1
.
0
f
-
1
.
0
f
-
DBM0_MAX_POWER
)
/
20
.
0
f
);
s
->
tx
.
gain
=
l
*
32768
.
0
f
/
(
TX_PULSESHAPER_GAIN
*
3
.
0
f
);
l
=
powf
(
10
.
0
f
,
(
power
-
1
.
0
f
-
6
.
0
f
-
DBM0_MAX_POWER
)
/
20
.
0
f
);
s
->
tx
.
guard_level
=
l
*
32768
.
0
f
;
}
else
{
sig_power
=
power
;
guard_tone_power
=
-
9999
.
0
f
;
l
=
1
.
6
f
*
powf
(
10
.
0
f
,
(
power
-
DBM0_MAX_POWER
)
/
20
.
0
f
);
s
->
tx
.
gain
=
l
*
32768
.
0
f
/
(
TX_PULSESHAPER_GAIN
*
3
.
0
f
);
s
->
tx
.
guard_level
=
0
;
}
sig_gain
=
0
.
4490
f
*
powf
(
10
.
0
f
,
(
sig_power
-
DBM0_MAX_POWER
)
/
20
.
0
f
)
*
32768
.
0
f
/
TX_PULSESHAPER_GAIN
;
guard_tone_gain
=
powf
(
10
.
0
f
,
(
guard_tone_power
-
DBM0_MAX_POWER
)
/
20
.
0
f
)
*
32768
.
0
f
;
#if defined(SPANDSP_USE_FIXED_POINT)
s
->
tx
.
gain
=
(
int16_t
)
sig_gain
;
s
->
tx
.
guard_tone_gain
=
(
int16_t
)
guard_tone_gain
;
#else
s
->
tx
.
gain
=
sig_gain
;
s
->
tx
.
guard_tone_gain
=
guard_tone_gain
;
#endif
}
/*- End of function --------------------------------------------------------*/
static
int
v22bis_tx_restart
(
v22bis_state_t
*
s
)
{
#if defined(SPANDSP_USE_FIXED_POINT)
vec_zeroi16
(
s
->
tx
.
rrc_filter_re
,
sizeof
(
s
->
tx
.
rrc_filter_re
)
/
sizeof
(
s
->
tx
.
rrc_filter_re
[
0
]));
vec_zeroi16
(
s
->
tx
.
rrc_filter_im
,
sizeof
(
s
->
tx
.
rrc_filter_im
)
/
sizeof
(
s
->
tx
.
rrc_filter_im
[
0
]));
#else
vec_zerof
(
s
->
tx
.
rrc_filter_re
,
sizeof
(
s
->
tx
.
rrc_filter_re
)
/
sizeof
(
s
->
tx
.
rrc_filter_re
[
0
]));
vec_zerof
(
s
->
tx
.
rrc_filter_im
,
sizeof
(
s
->
tx
.
rrc_filter_im
)
/
sizeof
(
s
->
tx
.
rrc_filter_im
[
0
]));
#endif
cvec_zerof
(
s
->
tx
.
rrc_filter
,
sizeof
(
s
->
tx
.
rrc_filter
)
/
sizeof
(
s
->
tx
.
rrc_filter
[
0
]));
s
->
tx
.
rrc_filter_step
=
0
;
s
->
tx
.
scramble_reg
=
0
;
s
->
tx
.
scrambler_pattern_count
=
0
;
...
...
libs/spandsp/src/v29rx.c
浏览文件 @
13fbaf7e
...
...
@@ -230,13 +230,17 @@ static void equalizer_reset(v29_rx_state_t *s)
{
/* Start with an equalizer based on everything being perfect */
#if defined(SPANDSP_USE_FIXED_POINT)
static
const
complexi16_t
x
=
{
3
*
FP_FACTOR
,
0
*
FP_FACTOR
};
cvec_zeroi16
(
s
->
eq_coeff
,
V29_EQUALIZER_LEN
);
s
->
eq_coeff
[
V29_EQUALIZER_PRE_LEN
]
=
complex_seti16
(
3
*
FP_FACTOR
,
0
*
FP_FACTOR
)
;
s
->
eq_coeff
[
V29_EQUALIZER_PRE_LEN
]
=
x
;
cvec_zeroi16
(
s
->
eq_buf
,
V29_EQUALIZER_LEN
);
s
->
eq_delta
=
32768
.
0
f
*
EQUALIZER_DELTA
/
V29_EQUALIZER_LEN
;
#else
static
const
complexf_t
x
=
{
3
.
0
f
,
0
.
0
f
};
cvec_zerof
(
s
->
eq_coeff
,
V29_EQUALIZER_LEN
);
s
->
eq_coeff
[
V29_EQUALIZER_PRE_LEN
]
=
complex_setf
(
3
.
0
f
,
0
.
0
f
)
;
s
->
eq_coeff
[
V29_EQUALIZER_PRE_LEN
]
=
x
;
cvec_zerof
(
s
->
eq_buf
,
V29_EQUALIZER_LEN
);
s
->
eq_delta
=
EQUALIZER_DELTA
/
V29_EQUALIZER_LEN
;
#endif
...
...
@@ -538,7 +542,7 @@ static __inline__ void symbol_sync(v29_rx_state_t *s)
i
=
(
v
>
1000
.
0
f
)
?
5
:
1
;
if
(
s
->
baud_phase
<
0
.
0
f
)
i
=
-
i
;
//printf("v = %10.5f %5d - %f %f %d
%d
\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
//printf("v = %10.5f %5d - %f %f %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
s
->
eq_put_step
+=
i
;
s
->
total_baud_timing_correction
+=
i
;
}
...
...
@@ -645,8 +649,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
if
(
i
)
{
j
=
i
&
0xF
;
ang
=
(
s
->
angles
[
j
]
-
s
->
start_angles
[
0
])
/
i
+
(
s
->
angles
[
j
|
0x1
]
-
s
->
start_angles
[
1
])
/
i
;
ang
=
(
s
->
angles
[
j
]
-
s
->
start_angles
[
0
])
/
i
+
(
s
->
angles
[
j
|
0x1
]
-
s
->
start_angles
[
1
])
/
i
;
s
->
carrier_phase_rate
+=
3
*
(
ang
/
20
);
}
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"Coarse carrier frequency %7.2f
\n
"
,
dds_frequencyf
(
s
->
carrier_phase_rate
));
...
...
@@ -719,11 +722,12 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
if
(
++
s
->
training_count
>=
V29_TRAINING_SEG_3_LEN
-
48
)
{
s
->
training_stage
=
TRAINING_STAGE_TRAIN_ON_CDCD_AND_TEST
;
s
->
training_error
=
0
.
0
f
;
#if defined(SPANDSP_USE_FIXED_POINT)
s
->
training_error
=
0
;
s
->
carrier_track_i
=
200
;
s
->
carrier_track_p
=
1000000
;
#else
s
->
training_error
=
0
.
0
f
;
s
->
carrier_track_i
=
200
.
0
f
;
s
->
carrier_track_p
=
1000000
.
0
f
;
#endif
...
...
@@ -946,10 +950,12 @@ SPAN_DECLARE_NONSTD(int) v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
parked, after training failure. */
s
->
eq_put_step
-=
RX_PULSESHAPER_COEFF_SETS
;
step
=
-
s
->
eq_put_step
;
if
(
step
>
RX_PULSESHAPER_COEFF_SETS
-
1
)
step
=
RX_PULSESHAPER_COEFF_SETS
-
1
;
if
(
step
<
0
)
step
+=
RX_PULSESHAPER_COEFF_SETS
;
if
(
step
<
0
)
step
=
0
;
else
if
(
step
>
RX_PULSESHAPER_COEFF_SETS
-
1
)
step
=
RX_PULSESHAPER_COEFF_SETS
-
1
;
#if defined(SPANDSP_USE_FIXED_POINT)
v
=
vec_circular_dot_prodi16
(
s
->
rrc_filter
,
rx_pulseshaper_re
[
step
],
V29_RX_FILTER_STEPS
,
s
->
rrc_filter_step
);
sample
.
re
=
(
v
*
s
->
agc_scaling
)
>>
15
;
...
...
libs/spandsp/src/v29tx_constellation_maps.h
浏览文件 @
13fbaf7e
...
...
@@ -24,26 +24,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(FP_SCALE)
#if defined(SPANDSP_USE_FIXED_POINT)
#define FP_SCALE(x) ((int16_t) x)
#else
#define FP_SCALE(x) (x)
#endif
#endif
#if defined(SPANDSP_USE_FIXED_POINT)
static
const
complexi16_t
v29_abab_constellation
[
6
]
=
#else
static
const
complexf_t
v29_abab_constellation
[
6
]
=
#endif
{
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
-
3
.
0
f
)},
/* 315deg high 9600 */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 180deg low */
{
FP_SCALE
(
1
.
0
f
),
FP_SCALE
(
-
1
.
0
f
)},
/* 315deg low 7200 */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 180deg low */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
-
3
.
0
f
)},
/* 270deg low 4800 */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)}
/* 180deg low */
{
3
,
-
3
},
/* 315deg high 9600 */
{
-
3
,
0
},
/* 180deg low */
{
1
,
-
1
},
/* 315deg low 7200 */
{
-
3
,
0
},
/* 180deg low */
{
0
,
-
3
},
/* 270deg low 4800 */
{
-
3
,
0
}
/* 180deg low */
};
#if defined(SPANDSP_USE_FIXED_POINT)
...
...
@@ -52,12 +44,12 @@ static const complexi16_t v29_cdcd_constellation[6] =
static
const
complexf_t
v29_cdcd_constellation
[
6
]
=
#endif
{
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 0deg low 9600 */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
3
.
0
f
)},
/* 135deg high */
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 0deg low 7200 */
{
FP_SCALE
(
-
1
.
0
f
),
FP_SCALE
(
1
.
0
f
)},
/* 135deg low */
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 0deg low 4800 */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
3
.
0
f
)}
/* 90deg low */
{
3
,
0
},
/* 0deg low 9600 */
{
-
3
,
3
},
/* 135deg high */
{
3
,
0
},
/* 0deg low 7200 */
{
-
1
,
1
},
/* 135deg low */
{
3
,
0
},
/* 0deg low 4800 */
{
0
,
3
}
/* 90deg low */
};
#if defined(SPANDSP_USE_FIXED_POINT)
...
...
@@ -66,22 +58,22 @@ static const complexi16_t v29_9600_constellation[16] =
static
const
complexf_t
v29_9600_constellation
[
16
]
=
#endif
{
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 0deg low */
{
FP_SCALE
(
1
.
0
f
),
FP_SCALE
(
1
.
0
f
)},
/* 45deg low */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
3
.
0
f
)},
/* 90deg low */
{
FP_SCALE
(
-
1
.
0
f
),
FP_SCALE
(
1
.
0
f
)},
/* 135deg low */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 180deg low */
{
FP_SCALE
(
-
1
.
0
f
),
FP_SCALE
(
-
1
.
0
f
)},
/* 225deg low */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
-
3
.
0
f
)},
/* 270deg low */
{
FP_SCALE
(
1
.
0
f
),
FP_SCALE
(
-
1
.
0
f
)},
/* 315deg low */
{
FP_SCALE
(
5
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 0deg high */
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
3
.
0
f
)},
/* 45deg high */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
5
.
0
f
)},
/* 90deg high */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
3
.
0
f
)},
/* 135deg high */
{
FP_SCALE
(
-
5
.
0
f
),
FP_SCALE
(
0
.
0
f
)},
/* 180deg high */
{
FP_SCALE
(
-
3
.
0
f
),
FP_SCALE
(
-
3
.
0
f
)},
/* 225deg high */
{
FP_SCALE
(
0
.
0
f
),
FP_SCALE
(
-
5
.
0
f
)},
/* 270deg high */
{
FP_SCALE
(
3
.
0
f
),
FP_SCALE
(
-
3
.
0
f
)}
/* 315deg high */
{
3
,
0
},
/* 0deg low */
{
1
,
1
},
/* 45deg low */
{
0
,
3
},
/* 90deg low */
{
-
1
,
1
},
/* 135deg low */
{
-
3
,
0
},
/* 180deg low */
{
-
1
,
-
1
},
/* 225deg low */
{
0
,
-
3
},
/* 270deg low */
{
1
,
-
1
},
/* 315deg low */
{
5
,
0
},
/* 0deg high */
{
3
,
3
},
/* 45deg high */
{
0
,
5
},
/* 90deg high */
{
-
3
,
3
},
/* 135deg high */
{
-
5
,
0
},
/* 180deg high */
{
-
3
,
-
3
},
/* 225deg high */
{
0
,
-
5
},
/* 270deg high */
{
3
,
-
3
}
/* 315deg high */
};
/*- End of file ------------------------------------------------------------*/
libs/spandsp/src/v8.c
浏览文件 @
13fbaf7e
...
...
@@ -1024,9 +1024,9 @@ SPAN_DECLARE(int) v8_restart(v8_state_t *s, int calling_party, v8_parms_t *parms
{
/* Send the ANSam or ANSam/ tone */
s
->
state
=
V8_CM_WAIT
;
s
->
negotiation_timer
=
ms_to_samples
(
200
+
5000
);
v8_decode_init
(
s
);
modem_connect_tones_tx_init
(
&
s
->
ansam_tx
,
s
->
parms
.
modem_connect_tone
);
s
->
negotiation_timer
=
ms_to_samples
(
200
+
5000
);
s
->
modem_connect_tone_tx_on
=
ms_to_samples
(
75
)
+
1
;
}
...
...
libs/spandsp/tests/Makefile.am
浏览文件 @
13fbaf7e
...
...
@@ -300,7 +300,7 @@ t38_core_tests_SOURCES = t38_core_tests.c
t38_core_tests_LDADD
=
$(LIBDIR)
-lspandsp
t38_decode_SOURCES
=
t38_decode.c fax_utils.c pcap_parse.c udptl.c
t38_decode_LDADD
=
-L
$(top_builddir)
/spandsp-sim
-lspandsp-sim
$(LIBDIR)
-lspandsp
-lpcap
t38_decode_LDADD
=
-L
$(top_builddir)
/spandsp-sim
-lspandsp-sim
$(LIBDIR)
-lspandsp
t38_non_ecm_buffer_tests_SOURCES
=
t38_non_ecm_buffer_tests.c
t38_non_ecm_buffer_tests_LDADD
=
$(LIBDIR)
-lspandsp
...
...
libs/spandsp/tests/fax_tester.c
浏览文件 @
13fbaf7e
...
...
@@ -287,7 +287,7 @@ static void hdlc_rx_status(void *user_data, int status)
faxtester_state_t
*
s
;
s
=
(
faxtester_state_t
*
)
user_data
;
fprintf
(
stderr
,
"HDLC carrier status is %s (%d)
\n
"
,
signal_status_to_str
(
status
),
status
);
span_log
(
&
s
->
logging
,
SPAN_LOG_FLOW
,
"HDLC carrier status is %s (%d)
\n
"
,
signal_status_to_str
(
status
),
status
);
switch
(
status
)
{
case
SIG_STATUS_TRAINING_FAILED
:
...
...
@@ -409,9 +409,7 @@ int faxtester_rx(faxtester_state_t *s, int16_t *amp, int len)
int
faxtester_tx
(
faxtester_state_t
*
s
,
int16_t
*
amp
,
int
max_len
)
{
int
len
;
int
required_len
;
required_len
=
max_len
;
len
=
0
;
if
(
s
->
transmit
)
{
...
...
libs/spandsp/tests/fax_tests.sh
浏览文件 @
13fbaf7e
...
...
@@ -18,8 +18,8 @@
run_fax_test
()
{
rm
-f
fax_tests_1.tif
echo
-i
${
FILE
}
${
OPTS
}
./fax_tests
-i
${
FILE
}
${
OPTS
}
>
xyzzy 2>xyzzy2
echo
-i
${
FILE
}
${
OPTS
}
-i
${
FILE
}
./fax_tests
${
OPTS
}
-i
${
FILE
}
>
xyzzy 2>xyzzy2
RETVAL
=
$?
if
[
$RETVAL
!=
0
]
then
...
...
@@ -28,7 +28,7 @@ run_fax_test()
fi
# Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t
# option means the normal differences in tags will be ignored.
tiffcmp
-t
${
FILE
}
fax_tests
_1
.tif
#>/dev/null
tiffcmp
-t
${
FILE
}
fax_tests.tif
#>/dev/null
RETVAL
=
$?
if
[
$RETVAL
!=
0
]
then
...
...
@@ -39,165 +39,106 @@ run_fax_test()
echo
tested
${
FILE
}
}
OPTS
=
"-e"
ITUTESTS_DIR
=
../test-data/itu/fax
FILE
=
"../itutests/fax/R8_385_A4.tif"
run_fax_test
for
OPTS
in
"-p AA"
"-p AA -e"
"-p TT"
"-p TT -e"
"-p GG"
"-p GG -e"
"-p TG"
"-p TG -e"
"-p GT"
"-p GT -e"
do
FILE
=
"
${
ITUTESTS_DIR
}
/R8_385_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_385_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_385_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_385_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_385_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_77_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_77_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_77_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_77_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_77_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_77_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_154_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_154_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_154_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_154_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R8_154_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R8_154_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_300_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_300_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_300_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_300_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_300_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_300_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_600_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_600_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_600_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_600_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R300_600_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R300_600_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_154_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_154_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_154_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_154_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_154_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_154_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_800_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_800_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_800_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_800_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R16_800_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R16_800_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_600_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_600_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_600_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_600_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_600_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_600_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_1200_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_1200_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_1200_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_1200_B4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R600_1200_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R600_1200_A3.tif"
run_fax_test
FILE
=
"../itutests/fax
/R1200_1200_A4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R1200_1200_A4.tif"
run_fax_test
FILE
=
"../itutests/fax
/R1200_1200_B4.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R1200_1200_B4.tif"
run_fax_test
FILE
=
"../itutests/fax/R1200_1200_A3.tif"
run_fax_test
OPTS
=
""
FILE
=
"../itutests/fax/R8_385_A4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_385_B4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_385_A3.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_77_A4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_77_B4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_77_A3.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_154_A4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_154_B4.tif"
run_fax_test
FILE
=
"../itutests/fax/R8_154_A3.tif"
run_fax_test
FILE
=
"../itutests/fax/R16_385_A4.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_385_B4.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_385_A3.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_77_A4.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_77_B4.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_77_A3.tif"
#run_fax_test
FILE
=
"../itutests/fax/R16_154_A4.tif"
run_fax_test
FILE
=
"../itutests/fax/R16_154_B4.tif"
run_fax_test
FILE
=
"../itutests/fax/R16_154_A3.tif"
run_fax_test
FILE
=
"
${
ITUTESTS_DIR
}
/R1200_1200_A3.tif"
run_fax_test
done
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论