Various tweaks to spandsp, including starting to add some genuine ARM

optimisations.
This commit is contained in:
Steve Underwood 2012-12-12 03:23:27 +08:00
parent 8aba7238a8
commit 38bf6342fa
11 changed files with 232 additions and 93 deletions

View File

@ -183,9 +183,7 @@ SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit)
s->put_byte(s->user_data, s->byte_in_progress); s->put_byte(s->user_data, s->byte_in_progress);
s->bitpos = 0; s->bitpos = 0;
} }
else else if (s->use_v14)
{
if (s->use_v14)
{ {
/* This is actually the start bit for the next character, and /* This is actually the start bit for the next character, and
the stop bit has been dropped from the stream. This is the the stop bit has been dropped from the stream. This is the
@ -205,7 +203,6 @@ SPAN_DECLARE_NONSTD(void) async_rx_put_bit(void *user_data, int bit)
} }
} }
} }
}
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s, SPAN_DECLARE(async_tx_state_t *) async_tx_init(async_tx_state_t *s,

View File

@ -128,6 +128,68 @@ static const char *at_response_codes[] =
"+FRH:3" "+FRH:3"
}; };
SPAN_DECLARE(const char *) at_call_state_to_str(int state)
{
switch (state)
{
case AT_CALL_EVENT_ALERTING:
return "Alerting";
case AT_CALL_EVENT_CONNECTED:
return "Connected";
case AT_CALL_EVENT_ANSWERED:
return "Answered";
case AT_CALL_EVENT_BUSY:
return "Busy";
case AT_CALL_EVENT_NO_DIALTONE:
return "No dialtone";
case AT_CALL_EVENT_NO_ANSWER:
return "No answer";
case AT_CALL_EVENT_HANGUP:
return "Hangup";
}
/*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(const char *) at_modem_control_to_str(int state)
{
switch (state)
{
case AT_MODEM_CONTROL_CALL:
return "Call";
case AT_MODEM_CONTROL_ANSWER:
return "Answer";
case AT_MODEM_CONTROL_HANGUP:
return "Hangup";
case AT_MODEM_CONTROL_OFFHOOK:
return "Off hook";
case AT_MODEM_CONTROL_ONHOOK:
return "On hook";
case AT_MODEM_CONTROL_DTR:
return "DTR";
case AT_MODEM_CONTROL_RTS:
return "RTS";
case AT_MODEM_CONTROL_CTS:
return "CTS";
case AT_MODEM_CONTROL_CAR:
return "CAR";
case AT_MODEM_CONTROL_RNG:
return "RNG";
case AT_MODEM_CONTROL_DSR:
return "DSR";
case AT_MODEM_CONTROL_SETID:
return "Set ID";
case AT_MODEM_CONTROL_RESTART:
return "Restart";
case AT_MODEM_CONTROL_DTE_TIMEOUT:
return "DTE timeout";
}
/*endswitch*/
return "???";
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode) SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode)
{ {
/* The use of a DTE timeout is mode dependent. Set the timeout appropriately in /* The use of a DTE timeout is mode dependent. Set the timeout appropriately in
@ -363,8 +425,8 @@ SPAN_DECLARE(void) at_display_call_info(at_state_t *s)
snprintf(buf, snprintf(buf,
sizeof(buf), sizeof(buf),
"%s=%s", "%s=%s",
call_id->id ? call_id->id : "NULL", (call_id->id) ? call_id->id : "NULL",
call_id->value ? call_id->value : "<NONE>"); (call_id->value) ? call_id->value : "<NONE>");
at_put_response(s, buf); at_put_response(s, buf);
call_id = call_id->next; call_id = call_id->next;
} }

View File

@ -560,8 +560,7 @@ static void quantization_and_coding(int16_t LAR[8])
#undef STEP #undef STEP
#define STEP(A,B,MAC,MIC) \ #define STEP(A,B,MAC,MIC) \
temp = saturated_mul16(A, *LAR); \ temp = saturated_mul16(A, *LAR); \
temp = saturated_add16(temp, B); \ temp = saturated_add16(temp, (B + 256)); \
temp = saturated_add16(temp, 256); \
temp >>= 9; \ temp >>= 9; \
*LAR = (int16_t) ((temp > MAC) \ *LAR = (int16_t) ((temp > MAC) \
? \ ? \

View File

@ -201,10 +201,9 @@ static int image_gray8_to_colour16_row(uint16_t colour16[], uint8_t gray8[], int
for (i = pixels - 1; i >= 0; i--) for (i = pixels - 1; i >= 0; i--)
{ {
/* TODO: need to balance the colours */ colour16[3*i] = saturateu16((gray8[i]*36532U) >> 7);
colour16[3*i] = gray8[i] << 8; colour16[3*i + 1] = saturateu16((gray8[i]*37216U) >> 8);
colour16[3*i + 1] = gray8[i] << 8; colour16[3*i + 2] = saturateu16((gray8[i]*47900U) >> 6);
colour16[3*i + 2] = gray8[i] << 8;
} }
return pixels; return pixels;
} }
@ -216,10 +215,9 @@ static int image_gray8_to_colour8_row(uint8_t colour8[], uint8_t gray8[], int pi
for (i = pixels - 1; i >= 0; i--) for (i = pixels - 1; i >= 0; i--)
{ {
/* TODO: need to balance the colours */ colour8[3*i] = saturateu8((gray8[i]*36532U) >> 15);
colour8[3*i] = gray8[i]; colour8[3*i + 1] = saturateu8((gray8[i]*37216U) >> 16);
colour8[3*i + 1] = gray8[i]; colour8[3*i + 2] = saturateu8((gray8[i]*47900U) >> 14);
colour8[3*i + 2] = gray8[i];
} }
return pixels; return pixels;
} }

View File

@ -433,7 +433,7 @@ void lpc10_voicing(lpc10_encode_state_t *s,
s->voibuf[1][1] = 1; s->voibuf[1][1] = 1;
break; break;
case 11: case 11:
if (s->voice[1][9] < -s->voice[0][1]) if (s->voice[1][0] < -s->voice[0][1])
s->voibuf[2][0] = 0; s->voibuf[2][0] = 0;
else else
s->voibuf[1][1] = 1; s->voibuf[1][1] = 1;

View File

@ -486,7 +486,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
if (s->tone_present != MODEM_CONNECT_TONES_FAX_CNG) if (s->tone_present != MODEM_CONNECT_TONES_FAX_CNG)
{ {
if (++s->tone_cycle_duration >= ms_to_samples(415)) if (++s->tone_cycle_duration >= ms_to_samples(415))
report_tone_state(s, MODEM_CONNECT_TONES_FAX_CNG, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f)); report_tone_state(s, MODEM_CONNECT_TONES_FAX_CNG, lfastrintf(((s->channel_level == 0) ? (-96.329f + DBM0_MAX_POWER) : log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
} }
} }
else else
@ -565,7 +565,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
{ {
report_tone_state(s, report_tone_state(s,
(s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM_PR : MODEM_CONNECT_TONES_ANS_PR, (s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM_PR : MODEM_CONNECT_TONES_ANS_PR,
lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f)); lfastrintf(((s->channel_level == 0) ? (-96.329f + DBM0_MAX_POWER) : log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
} }
} }
else else
@ -583,7 +583,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
{ {
report_tone_state(s, report_tone_state(s,
(s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM : MODEM_CONNECT_TONES_ANS, (s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM : MODEM_CONNECT_TONES_ANS,
lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f)); lfastrintf(((s->channel_level == 0) ? (-96.329f + DBM0_MAX_POWER) : log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
} }
s->good_cycles = 0; s->good_cycles = 0;
s->tone_cycle_duration = ms_to_samples(450 + 100); s->tone_cycle_duration = ms_to_samples(450 + 100);
@ -637,7 +637,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
if (s->tone_present != MODEM_CONNECT_TONES_BELL_ANS) if (s->tone_present != MODEM_CONNECT_TONES_BELL_ANS)
{ {
if (++s->tone_cycle_duration >= ms_to_samples(415)) if (++s->tone_cycle_duration >= ms_to_samples(415))
report_tone_state(s, MODEM_CONNECT_TONES_BELL_ANS, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f)); report_tone_state(s, MODEM_CONNECT_TONES_BELL_ANS, lfastrintf(((s->channel_level == 0) ? (-96.329f + DBM0_MAX_POWER) : log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
} }
} }
else else
@ -675,7 +675,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE) if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE)
{ {
if (++s->tone_cycle_duration >= ms_to_samples(415)) if (++s->tone_cycle_duration >= ms_to_samples(415))
report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f)); report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(((s->channel_level == 0) ? (-96.329f + DBM0_MAX_POWER) : log10f(s->channel_level/32768.0f)*20.0f) + DBM0_MAX_POWER + 0.8f));
} }
} }
else else

View File

@ -136,6 +136,10 @@ extern "C"
{ {
#endif #endif
SPAN_DECLARE(const char *) at_call_state_to_str(int state);
SPAN_DECLARE(const char *) at_modem_control_to_str(int state);
SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode); SPAN_DECLARE(void) at_set_at_rx_mode(at_state_t *s, int new_mode);
SPAN_DECLARE(void) at_put_response(at_state_t *s, const char *t); SPAN_DECLARE(void) at_put_response(at_state_t *s, const char *t);

View File

@ -45,68 +45,123 @@ extern "C"
/* This is the same as saturate16(), but is here for historic reasons */ /* This is the same as saturate16(), but is here for historic reasons */
static __inline__ int16_t saturate(int32_t amp) static __inline__ int16_t saturate(int32_t amp)
{ {
int16_t amp16; #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int16_t z;
__asm__ __volatile__(
" ssat %[z],#16,%[amp];\n"
: [z] "=r" (z)
: [amp] "r" (amp)
);
return z;
#else
int16_t z;
/* Hopefully this is optimised for the common case - not clipping */ /* Hopefully this is optimised for the common case - not clipping */
amp16 = (int16_t) amp; z = (int16_t) amp;
if (amp == amp16) if (amp == z)
return amp16; return z;
if (amp > INT16_MAX) if (amp > INT16_MAX)
return INT16_MAX; return INT16_MAX;
return INT16_MIN; return INT16_MIN;
#endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static __inline__ int16_t saturate16(int32_t amp) static __inline__ int16_t saturate16(int32_t amp)
{ {
int16_t amp16; #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int16_t z;
__asm__ __volatile__(
" ssat %[z],#16,%[amp];\n"
: [z] "=r" (z)
: [amp] "r" (amp)
);
return z;
#else
int16_t z;
/* Hopefully this is optimised for the common case - not clipping */ /* Hopefully this is optimised for the common case - not clipping */
amp16 = (int16_t) amp; z = (int16_t) amp;
if (amp == amp16) if (amp == z)
return amp16; return z;
if (amp > INT16_MAX) if (amp > INT16_MAX)
return INT16_MAX; return INT16_MAX;
return INT16_MIN; return INT16_MIN;
#endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
/*! Saturate to 15 bits, rather than the usual 16 bits. This is often a useful function. */ /*! Saturate to 15 bits, rather than the usual 16 bits. This is often a useful function. */
static __inline__ int16_t saturate15(int32_t amp) static __inline__ int16_t saturate15(int32_t amp)
{ {
#if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int16_t z;
__asm__ __volatile__(
" ssat %[z],#15,%[amp];\n"
: [z] "=r" (z)
: [amp] "r" (amp)
);
return z;
#else
if (amp > 16383) if (amp > 16383)
return 16383; return 16383;
if (amp < -16384) if (amp < -16384)
return -16384; return -16384;
return (int16_t) amp; return (int16_t) amp;
#endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static __inline__ uint16_t saturateu16(int32_t amp) static __inline__ uint16_t saturateu16(int32_t amp)
{ {
uint16_t amp16; #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
uint16_t z;
__asm__ __volatile__(
" usat %[z],#16,%[amp];\n"
: [z] "=r" (z)
: [amp] "r" (amp)
);
return z;
#else
uint16_t z;
/* Hopefully this is optimised for the common case - not clipping */ /* Hopefully this is optimised for the common case - not clipping */
amp16 = (uint16_t) amp; z = (uint16_t) amp;
if (amp == amp16) if (amp == z)
return amp16; return z;
if (amp > UINT16_MAX) if (amp > UINT16_MAX)
return UINT16_MAX; return UINT16_MAX;
return 0; return 0;
#endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static __inline__ uint8_t saturateu8(int32_t amp) static __inline__ uint8_t saturateu8(int32_t amp)
{ {
uint8_t amp8; #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
uint8_t z;
__asm__ __volatile__(
" usat %[z],#8,%[amp];\n"
: [z] "=r" (z)
: [amp] "r" (amp)
);
return z;
#else
uint8_t z;
/* Hopefully this is optimised for the common case - not clipping */ /* Hopefully this is optimised for the common case - not clipping */
amp8 = (uint8_t) amp; z = (uint8_t) amp;
if (amp == amp8) if (amp == z)
return amp8; return z;
if (amp > UINT8_MAX) if (amp > UINT8_MAX)
return UINT8_MAX; return UINT8_MAX;
return 0; return 0;
#endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -188,15 +243,15 @@ static __inline__ int16_t saturated_add16(int16_t a, int16_t b)
: "cc" : "cc"
); );
return a; return a;
#elif defined(__GNUC__) && defined(__arm5__) #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int16_t result; int16_t z;
__asm__ __volatile__( __asm__ __volatile__(
" sadd16 %0,%1,%2;\n" " qsub16 %[z],%[a],%[b];\n"
: "=r" (result) : [z] "=r" (z)
: "0" (a), "ir" (b) : [a] "r" (a), [b] "r" (b)
); );
return result; return z;
#else #else
return saturate((int32_t) a + (int32_t) b); return saturate((int32_t) a + (int32_t) b);
#endif #endif
@ -217,25 +272,25 @@ static __inline__ int32_t saturated_add32(int32_t a, int32_t b)
: "cc" : "cc"
); );
return a; return a;
#elif defined(__GNUC__) && defined(__arm5__) #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int32_t result; int32_t z;
__asm__ __volatile__( __asm__ __volatile__(
" qadd %0,%1,%2;\n" " qadd %[z],%[a],%[b];\n"
: "=r" (result) : [z] "=r" (z)
: "0" (a), "ir" (b) : [a] "r" (a), [b] "r" (b)
); );
return result; return z;
#else #else
int32_t sum; int32_t z;
sum = a + b; z = a + b;
if ((a ^ b) >= 0) if ((a ^ b) >= 0)
{ {
if ((sum ^ a) < 0) if ((z ^ a) < 0)
sum = (a < 0) ? INT32_MIN : INT32_MAX; z = (a < 0) ? INT32_MIN : INT32_MAX;
} }
return sum; return z;
#endif #endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -254,15 +309,15 @@ static __inline__ int16_t saturated_sub16(int16_t a, int16_t b)
: "cc" : "cc"
); );
return a; return a;
#elif defined(__GNUC__) && defined(__arm5__) #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int16_t result; int16_t z;
__asm__ __volatile__( __asm__ __volatile__(
" ssub16 %0,%1,%2;\n" " qsub16 %[z],%[a],%[b];\n"
: "=r" (result) : [z] "=r" (z)
: "0" (a), "ir" (b) : [a] "r" (a), [b] "r" (b)
); );
return result; return z;
#else #else
return saturate((int32_t) a - (int32_t) b); return saturate((int32_t) a - (int32_t) b);
#endif #endif
@ -283,25 +338,25 @@ static __inline__ int32_t saturated_sub32(int32_t a, int32_t b)
: "cc" : "cc"
); );
return a; return a;
#elif defined(__GNUC__) && defined(__arm5__) #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
int32_t result; int32_t z;
__asm__ __volatile__( __asm__ __volatile__(
" qsub %0,%1,%2;\n" " qsub %[z],%[a],%[b];\n"
: "=r" (result) : [z] "=r" (z)
: "0" (a), "ir" (b) : [a] "r" (a), [b] "r" (b)
); );
return result; return z;
#else #else
int32_t diff; int32_t z;
diff = a - b; z = a - b;
if ((a ^ b) < 0) if ((a ^ b) < 0)
{ {
if ((diff ^ a) & INT32_MIN) if ((z ^ a) & INT32_MIN)
diff = (a < 0L) ? INT32_MIN : INT32_MAX; z = (a < 0L) ? INT32_MIN : INT32_MAX;
} }
return diff; return z;
#endif #endif
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/

View File

@ -240,6 +240,7 @@ SPAN_DECLARE(const char *) t30_completion_code_to_str(int result)
case T30_ERR_CSA_UNACCEPTABLE: case T30_ERR_CSA_UNACCEPTABLE:
return "Called subscriber internet address not accepted"; return "Called subscriber internet address not accepted";
} }
/*endswitch*/
return "???"; return "???";
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -411,6 +412,7 @@ SPAN_DECLARE(const char *) t30_frametype(uint8_t x)
case T4_RCP: case T4_RCP:
return "RCP"; return "RCP";
} }
/*endswitch*/
return "???"; return "???";
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
@ -436,6 +438,7 @@ static void octet_reserved_bit(logging_state_t *log,
s[7 - bit_no + ((bit_no < 4) ? 1 : 0)] = (uint8_t) (bit + '0'); s[7 - bit_no + ((bit_no < 4) ? 1 : 0)] = (uint8_t) (bit + '0');
span_log(log, SPAN_LOG_FLOW, " %s= Unexpected state for reserved bit: %d\n", s, bit); span_log(log, SPAN_LOG_FLOW, " %s= Unexpected state for reserved bit: %d\n", s, bit);
} }
/*endif*/
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/

View File

@ -155,7 +155,9 @@ enum
{ {
T38_CHUNKING_MERGE_FCS_WITH_DATA = 0x0001, T38_CHUNKING_MERGE_FCS_WITH_DATA = 0x0001,
T38_CHUNKING_WHOLE_FRAMES = 0x0002, T38_CHUNKING_WHOLE_FRAMES = 0x0002,
T38_CHUNKING_ALLOW_TEP_TIME = 0x0004 T38_CHUNKING_ALLOW_TEP_TIME = 0x0004,
T38_CHUNKING_SEND_REGULAR_INDICATORS = 0x0008,
T38_CHUNKING_SEND_2S_REGULAR_INDICATORS = 0x0010
}; };
enum enum
@ -181,7 +183,8 @@ enum
T38_TIMED_STEP_CED_3 = 0x42, T38_TIMED_STEP_CED_3 = 0x42,
T38_TIMED_STEP_CNG = 0x50, T38_TIMED_STEP_CNG = 0x50,
T38_TIMED_STEP_CNG_2 = 0x51, T38_TIMED_STEP_CNG_2 = 0x51,
T38_TIMED_STEP_PAUSE = 0x60 T38_TIMED_STEP_PAUSE = 0x60,
T38_TIMED_STEP_NO_SIGNAL = 0x70
}; };
static int restart_modem(t31_state_t *s, int new_modem); static int restart_modem(t31_state_t *s, int new_modem);

View File

@ -230,6 +230,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
/* Protect against T.38 stuff arriving after we've actually finished. */ /* Protect against T.38 stuff arriving after we've actually finished. */
if (fe->current_rx_type == T30_MODEM_DONE) if (fe->current_rx_type == T30_MODEM_DONE)
return 0; return 0;
/*endif*/
if (t->current_rx_indicator == indicator) if (t->current_rx_indicator == indicator)
{ {
@ -333,6 +334,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
/* Protect against T.38 stuff arriving after we've actually finished. */ /* Protect against T.38 stuff arriving after we've actually finished. */
if (fe->current_rx_type == T30_MODEM_DONE) if (fe->current_rx_type == T30_MODEM_DONE)
return 0; return 0;
/*endif*/
/* In termination mode we don't care very much what the data type is apart from a couple of /* In termination mode we don't care very much what the data type is apart from a couple of
special cases. */ special cases. */
@ -608,6 +610,7 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)
{ {
if (s->t38_fe.us_per_tx_chunk) if (s->t38_fe.us_per_tx_chunk)
s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len); s->t38_fe.hdlc_tx.extra_bits = extra_bits_in_stuffed_frame(msg, len);
/*endif*/
bit_reverse(s->t38_fe.hdlc_tx.buf, msg, len); bit_reverse(s->t38_fe.hdlc_tx.buf, msg, len);
s->t38_fe.hdlc_tx.len = len; s->t38_fe.hdlc_tx.len = len;
s->t38_fe.hdlc_tx.ptr = 0; s->t38_fe.hdlc_tx.ptr = 0;
@ -774,6 +777,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5; fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5;
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
break; break;
} }
/*endif*/ /*endif*/
@ -805,6 +809,7 @@ static int stream_non_ecm(t38_terminal_state_t *s)
/*endif*/ /*endif*/
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
break; break;
} }
/*endif*/ /*endif*/
@ -825,6 +830,10 @@ static int stream_non_ecm(t38_terminal_state_t *s)
fe->timed_step = fe->queued_timed_step; fe->timed_step = fe->queued_timed_step;
fe->queued_timed_step = T38_TIMED_STEP_NONE; fe->queued_timed_step = T38_TIMED_STEP_NONE;
} }
else
{
fe->timed_step = T38_TIMED_STEP_NONE;
}
/*endif*/ /*endif*/
return delay; return delay;
} }
@ -910,6 +919,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
fe->hdlc_tx.len = 0; fe->hdlc_tx.len = 0;
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
/* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */ /* 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)
{ {
@ -941,6 +951,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
/*endif*/ /*endif*/
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
} }
/*endif*/ /*endif*/
break; break;
@ -971,6 +982,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
fe->hdlc_tx.len = 0; fe->hdlc_tx.len = 0;
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
/* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */ /* 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)
{ {
@ -1006,6 +1018,7 @@ static int stream_hdlc(t38_terminal_state_t *s)
/*endif*/ /*endif*/
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
} }
/*endif*/ /*endif*/
break; break;
@ -1018,6 +1031,10 @@ static int stream_hdlc(t38_terminal_state_t *s)
fe->timed_step = fe->queued_timed_step; fe->timed_step = fe->queued_timed_step;
fe->queued_timed_step = T38_TIMED_STEP_NONE; fe->queued_timed_step = T38_TIMED_STEP_NONE;
} }
else
{
fe->timed_step = T38_TIMED_STEP_NONE;
}
/*endif*/ /*endif*/
return delay; return delay;
} }
@ -1063,6 +1080,7 @@ static int stream_ced(t38_terminal_state_t *s)
fe->timed_step = fe->queued_timed_step; fe->timed_step = fe->queued_timed_step;
if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0)
return -1; return -1;
/*endif*/
return 0; return 0;
} }
/*endswitch*/ /*endswitch*/