Various minor tweaks to spandsp and the ARM specific code now does fast top bit detection.
This commit is contained in:
parent
d55c4a053b
commit
0d6c3a1d73
|
@ -755,7 +755,7 @@ SPAN_DECLARE(ademco_contactid_receiver_state_t *) ademco_contactid_receiver_init
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (ademco_contactid_receiver_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (ademco_contactid_receiver_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -1090,7 +1090,7 @@ SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ade
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (ademco_contactid_sender_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (ademco_contactid_sender_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
|
|
@ -417,7 +417,7 @@ SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
|
|||
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_rx_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (dtmf_rx_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -578,7 +578,7 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s,
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_tx_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (dtmf_tx_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
|
|
@ -116,12 +116,12 @@ SPAN_DECLARE(gsm0610_state_t *) gsm0610_init(gsm0610_state_t *s, int packing)
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (gsm0610_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (gsm0610_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
memset((char *) s, '\0', sizeof (gsm0610_state_t));
|
||||
memset((char *) s, '\0', sizeof(gsm0610_state_t));
|
||||
s->nrp = 40;
|
||||
s->packing = packing;
|
||||
return s;
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef __int16 int16_t;
|
|||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
|
||||
#if !defined(INFINITY)
|
||||
#if !defined(INFINITY) && _MSC_VER < 1800
|
||||
#define INFINITY 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
|
|
|
@ -173,7 +173,6 @@ SPAN_DECLARE(void) at_set_class1_handler(at_state_t *s, at_class1_handler_t hand
|
|||
\return A pointer to the logging context */
|
||||
SPAN_DECLARE(logging_state_t *) at_get_logging_state(at_state_t *s);
|
||||
|
||||
|
||||
SPAN_DECLARE(void) at_set_modem_control_handler(at_state_t *s,
|
||||
at_modem_control_handler_t modem_control_handler,
|
||||
void *modem_control_user_data);
|
||||
|
|
|
@ -53,13 +53,13 @@ static __inline__ int top_bit(uint32_t bits)
|
|||
: [res] "=&r" (res)
|
||||
: [bits] "rm" (bits));
|
||||
return res;
|
||||
#elif defined(__GNUC__x) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
|
||||
#elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
|
||||
int res;
|
||||
|
||||
__asm__("clz %[res], %[bits]"
|
||||
: [res] "=r" (res)
|
||||
: [bits] "r" (bits));
|
||||
return res;
|
||||
return 31 - res;
|
||||
#elif defined(__ppc__) || defined(__powerpc__)
|
||||
int res;
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include "mmx.h"
|
||||
#endif
|
||||
|
||||
#include "alloc.h"
|
||||
|
||||
/*!
|
||||
16 bit integer FIR descriptor. This defines the working state for a single
|
||||
instance of an FIR filter using 16 bit integer coefficients.
|
||||
|
|
|
@ -111,7 +111,6 @@ That's it!
|
|||
*/
|
||||
typedef struct plc_state_s plc_state_t;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -34,15 +34,27 @@
|
|||
/*! Audio time scaling descriptor. */
|
||||
struct time_scale_state_s
|
||||
{
|
||||
/*! \brief The sample rate of both the incoming and outgoing signal */
|
||||
int sample_rate;
|
||||
/*! \brief The minimum pitch we will search for, in samples per cycle */
|
||||
int min_pitch;
|
||||
/*! \brief The maximum pitch we will search for, in samples per cycle */
|
||||
int max_pitch;
|
||||
int buf_len;
|
||||
/*! \brief The playout speed, as the fraction output time/input time.
|
||||
(i.e. >1.0 == slow down, 1.0 == no speed change, <1.0 == speed up) */
|
||||
float playout_rate;
|
||||
/*! \brief */
|
||||
double rcomp;
|
||||
/*! \brief The fractional sample adjustment, to allow for non-integer values of lcp. */
|
||||
double rate_nudge;
|
||||
int fill;
|
||||
/*! \brief */
|
||||
int lcp;
|
||||
/*! \brief The active length of buf at the current sample rate. */
|
||||
int buf_len;
|
||||
/*! \brief The number of samples in buf */
|
||||
int fill;
|
||||
/*! \brief Buffer for residual samples kept over from one call of time_scale() to
|
||||
the next. */
|
||||
int16_t buf[TIME_SCALE_BUF_LEN];
|
||||
};
|
||||
|
||||
|
|
|
@ -28,11 +28,33 @@
|
|||
#if !defined(_SPANDSP_T30_API_H_)
|
||||
#define _SPANDSP_T30_API_H_
|
||||
|
||||
enum
|
||||
{
|
||||
T33_NONE = 0,
|
||||
T33_SST = 1,
|
||||
T33_EXT = 2
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! Get the specified field from a T.33 formatted string.
|
||||
\brief Get the specified field from a T.33 formatted string.
|
||||
\param field The extracted field.
|
||||
\param t33 The T.33 formatted string.
|
||||
\param field_no The field number to extract. The first field is 0.
|
||||
\return The extracted field type. -1 indicates a over length or badly formatted field. */
|
||||
SPAN_DECLARE(int) t33_sub_address_extract_field(uint8_t field[21], const uint8_t t33[], int field_no);
|
||||
|
||||
/*! Append the specified field to a T.33 formatted string.
|
||||
\brief Append the specified field to a T.33 formatted string.
|
||||
\param t33 The T.33 formatted string.
|
||||
\param field The field to be adppended.
|
||||
\param type The type of the field to be appended. */
|
||||
SPAN_DECLARE(void) t33_sub_address_add_field(uint8_t t33[], const uint8_t field[], int type);
|
||||
|
||||
/*! Set the transmitted NSF frame to be associated with a T.30 context.
|
||||
\brief Set the transmitted NSF frame to be associated with a T.30 context.
|
||||
\param s The T.30 context.
|
||||
|
|
|
@ -62,25 +62,6 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
/*! Initialise a time scale context. This must be called before the first
|
||||
use of the context, to initialise its contents.
|
||||
\brief Initialise a time scale context.
|
||||
\param s The time scale context.
|
||||
\param sample_rate The sample rate of the signal.
|
||||
\param playout_rate The ratio between the output speed and the input speed.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate);
|
||||
|
||||
/*! \brief Release a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s);
|
||||
|
||||
/*! \brief Free a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s);
|
||||
|
||||
/*! Change the time scale rate.
|
||||
\brief Change the time scale rate.
|
||||
\param s The time scale context.
|
||||
|
@ -108,6 +89,27 @@ SPAN_DECLARE(int) time_scale_max_output_len(time_scale_state_t *s, int input_len
|
|||
*/
|
||||
SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[], int len);
|
||||
|
||||
SPAN_DECLARE(int) time_scale_flush(time_scale_state_t *s, int16_t out[]);
|
||||
|
||||
/*! Initialise a time scale context. This must be called before the first
|
||||
use of the context, to initialise its contents.
|
||||
\brief Initialise a time scale context.
|
||||
\param s The time scale context.
|
||||
\param sample_rate The sample rate of the signal.
|
||||
\param playout_rate The ratio between the output speed and the input speed.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate);
|
||||
|
||||
/*! \brief Release a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s);
|
||||
|
||||
/*! \brief Free a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -436,6 +436,7 @@ static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, in
|
|||
static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
|
||||
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len);
|
||||
static void set_min_scan_time(t30_state_t *s);
|
||||
static int send_cfr_sequence(t30_state_t *s, int start);
|
||||
static int build_dcs(t30_state_t *s);
|
||||
static void timer_t2_start(t30_state_t *s);
|
||||
static void timer_t2a_start(t30_state_t *s);
|
||||
|
@ -1309,7 +1310,6 @@ int t30_build_dis_or_dtc(t30_state_t *s)
|
|||
/* No Document transfer mode (DTM) */
|
||||
/* No Electronic data interchange (EDI) */
|
||||
/* No Basic transfer mode (BTM) */
|
||||
|
||||
/* No mixed mode (polling) */
|
||||
/* No character mode */
|
||||
/* No mixed mode (T.4/Annex E) */
|
||||
|
@ -5492,9 +5492,9 @@ static void timer_t2_expired(t30_state_t *s)
|
|||
/* We didn't receive a response to our T30_MCF after T30_EOM, so we must be OK
|
||||
to proceed to phase B, and pretty much act like its the beginning of a call. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Returning to phase B after %s\n", t30_frametype(s->next_rx_step));
|
||||
s->dis_received = false;
|
||||
set_phase(s, T30_PHASE_B_TX);
|
||||
timer_t2_start(s);
|
||||
s->dis_received = false;
|
||||
send_dis_or_dtc_sequence(s, true);
|
||||
return;
|
||||
}
|
||||
|
@ -5548,6 +5548,13 @@ static void timer_t2a_expired(t30_state_t *s)
|
|||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
|
||||
t30_set_status(s, T30_ERR_HDLC_CARRIER);
|
||||
/* T.30 says we should retry at this point, but we can't. We would need to
|
||||
wait for the far end to go quiet before sending. Experience says you only
|
||||
get here when the far end is buggy, and it will not go quiet unless you
|
||||
hang up. If we were to retry, how long should we wait for the line to go
|
||||
quiet? T.30 doesn't specify things like that. The only effective strategy,
|
||||
when trying to deal with problems found in logs from real world systems,
|
||||
is to abandon the call. */
|
||||
terminate_call(s);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -5571,7 +5578,8 @@ static void timer_t4_expired(t30_state_t *s)
|
|||
{
|
||||
/* There was no response (or only a corrupt response) to a command,
|
||||
within the T4 timeout period. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
|
||||
if (s->timer_t2_t4_is == TIMER_IS_T4)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
|
||||
/* Of course, things might just be a little late, especially if there are T.38
|
||||
links in the path. There is no point in simply timing out, and resending,
|
||||
if we are currently receiving something from the far end - its a half-duplex
|
||||
|
@ -6143,9 +6151,9 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
|
|||
{
|
||||
case T30_STATE_ANSWERING:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Starting answer mode\n");
|
||||
s->dis_received = false;
|
||||
set_phase(s, T30_PHASE_B_TX);
|
||||
timer_t2_start(s);
|
||||
s->dis_received = false;
|
||||
send_dis_or_dtc_sequence(s, true);
|
||||
break;
|
||||
case T30_STATE_R:
|
||||
|
|
|
@ -95,6 +95,65 @@
|
|||
|
||||
#include "t30_local.h"
|
||||
|
||||
SPAN_DECLARE(int) t33_sub_address_extract_field(uint8_t num[21], const uint8_t t33[], int field_no)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
int ch;
|
||||
int type;
|
||||
|
||||
num[0] = '\0';
|
||||
k = 0;
|
||||
for (i = 0; t33[i]; )
|
||||
{
|
||||
if (k++ == field_no)
|
||||
{
|
||||
ch = t33[i++];
|
||||
j = 0;
|
||||
if (ch != '#')
|
||||
{
|
||||
num[j++] = ch;
|
||||
type = T33_EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = T33_SST;
|
||||
}
|
||||
while (t33[i])
|
||||
{
|
||||
ch = t33[i++];
|
||||
if (ch == '#')
|
||||
break;
|
||||
num[j++] = ch;
|
||||
if (j >= 20)
|
||||
return -1;
|
||||
}
|
||||
num[j] = '\0';
|
||||
return type;
|
||||
}
|
||||
/* Skip this field */
|
||||
i++;
|
||||
while (t33[i])
|
||||
{
|
||||
if (t33[i++] == '#')
|
||||
break;
|
||||
}
|
||||
}
|
||||
return T33_NONE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) t33_sub_address_add_field(uint8_t t33[], const uint8_t field[], int type)
|
||||
{
|
||||
if (t33[0] != '\0')
|
||||
strcat((char *) t33, "#");
|
||||
if (type == T33_SST)
|
||||
strcat((char *) t33, "#");
|
||||
strcat((char *) t33, (const char *) field);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t30_set_tx_ident(t30_state_t *s, const char *id)
|
||||
{
|
||||
if (id == NULL)
|
||||
|
|
|
@ -2994,7 +2994,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
|
|||
alloced = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (t31_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (t31_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = true;
|
||||
|
|
|
@ -662,8 +662,8 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
|||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* If we are processing a message from the modem side, the contents determine the fast receive modem.
|
||||
we are to use. If it comes from the T.38 side the contents do not. */
|
||||
/* If we are processing a message from the modem side, the contents determine the fast
|
||||
receive modem we are to use. If it comes from the T.38 side the contents do not. */
|
||||
s->core.fast_bit_rate = modem_codes[i].bit_rate;
|
||||
if (from_modem)
|
||||
s->core.fast_rx_modem = modem_codes[i].modem_type;
|
||||
|
@ -700,8 +700,9 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
|||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* If we are processing a message from the modem side, the contents determine the fast receive modem.
|
||||
we are to use. If it comes from the T.38 side the contents do not. */
|
||||
/* If we are processing a DCS message from the modem side, the contents determine the fast
|
||||
receive modem we are to use. If it comes from the T.38 side the contents do not. For a
|
||||
DTC message this is reversed. */
|
||||
s->core.fast_bit_rate = modem_codes[i].bit_rate;
|
||||
if ((buf[2] == T30_DTC && !from_modem) || (buf[2] != T30_DTC && from_modem))
|
||||
s->core.fast_rx_modem = modem_codes[i].modem_type;
|
||||
|
|
|
@ -78,12 +78,15 @@ static __inline__ int amdf_pitch(int min_pitch, int max_pitch, int16_t amp[], in
|
|||
acc = 0;
|
||||
for (j = 0; j < len; j++)
|
||||
acc += abs(amp[i + j] - amp[j]);
|
||||
/*endfor*/
|
||||
if (acc < min_acc)
|
||||
{
|
||||
min_acc = acc;
|
||||
pitch = i;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
return pitch;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -102,6 +105,7 @@ static __inline__ void overlap_add(int16_t amp1[], int16_t amp2[], int len)
|
|||
amp2[i] = (int16_t) ((float) amp1[i]*(1.0f - weight) + (float) amp2[i]*weight);
|
||||
weight += step;
|
||||
}
|
||||
/*endfor*/
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -130,52 +134,6 @@ SPAN_DECLARE(int) time_scale_rate(time_scale_state_t *s, float playout_rate)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate)
|
||||
{
|
||||
bool alloced;
|
||||
|
||||
if (sample_rate > TIME_SCALE_MAX_SAMPLE_RATE)
|
||||
return NULL;
|
||||
alloced = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (time_scale_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = true;
|
||||
}
|
||||
/*endif*/
|
||||
s->sample_rate = sample_rate;
|
||||
s->min_pitch = sample_rate/TIME_SCALE_MIN_PITCH;
|
||||
s->max_pitch = sample_rate/TIME_SCALE_MAX_PITCH;
|
||||
s->buf_len = 2*sample_rate/TIME_SCALE_MIN_PITCH;
|
||||
if (time_scale_rate(s, playout_rate))
|
||||
{
|
||||
if (alloced)
|
||||
span_free(s);
|
||||
return NULL;
|
||||
}
|
||||
/*endif*/
|
||||
s->rate_nudge = 0.0f;
|
||||
s->fill = 0;
|
||||
s->lcp = 0;
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s)
|
||||
{
|
||||
span_free(s);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[], int len)
|
||||
{
|
||||
double lcpf;
|
||||
|
@ -191,10 +149,12 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
if (s->fill + len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->fill], in, len);
|
||||
s->fill += len;
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
k = s->buf_len - s->fill;
|
||||
vec_copyi16(&s->buf[s->fill], in, k);
|
||||
in_len += k;
|
||||
|
@ -208,15 +168,18 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
if (len - in_len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(s->buf, &in[in_len], len - in_len);
|
||||
s->fill = len - in_len;
|
||||
s->lcp -= s->buf_len;
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(s->buf, &in[in_len], s->buf_len);
|
||||
in_len += s->buf_len;
|
||||
s->lcp -= s->buf_len;
|
||||
}
|
||||
/*endwhile*/
|
||||
if (s->lcp > 0)
|
||||
{
|
||||
vec_copyi16(&out[out_len], s->buf, s->lcp);
|
||||
|
@ -225,15 +188,18 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
if (len - in_len < s->lcp)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], len - in_len);
|
||||
s->fill = s->buf_len - s->lcp + len - in_len;
|
||||
s->lcp = 0;
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], s->lcp);
|
||||
in_len += s->lcp;
|
||||
s->lcp = 0;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->playout_rate == 1.0f)
|
||||
{
|
||||
s->lcp = 0x7FFFFFFF;
|
||||
|
@ -256,6 +222,7 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
s->lcp++;
|
||||
s->rate_nudge += 1.0f;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->playout_rate < 1.0f)
|
||||
{
|
||||
/* Speed up - drop a chunk of data */
|
||||
|
@ -264,10 +231,12 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
if (len - in_len < pitch)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], len - in_len);
|
||||
s->fill += (len - in_len - pitch);
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], pitch);
|
||||
in_len += pitch;
|
||||
}
|
||||
|
@ -278,15 +247,88 @@ SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[],
|
|||
out_len += pitch;
|
||||
overlap_add(&s->buf[pitch], s->buf, pitch);
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endwhile*/
|
||||
return out_len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_flush(time_scale_state_t *s, int16_t out[])
|
||||
{
|
||||
int len;
|
||||
int pad;
|
||||
|
||||
if (s->playout_rate < 1.0f)
|
||||
return 0;
|
||||
/*endif*/
|
||||
vec_copyi16(out, s->buf, s->fill);
|
||||
len = s->fill;
|
||||
if (s->playout_rate > 1.0f)
|
||||
{
|
||||
pad = s->fill*(s->playout_rate - 1.0f);
|
||||
vec_zeroi16(&out[len], pad);
|
||||
len += pad;
|
||||
}
|
||||
/*endif*/
|
||||
s->fill = 0;
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_max_output_len(time_scale_state_t *s, int input_len)
|
||||
{
|
||||
return (int) (input_len*s->playout_rate + s->min_pitch + 1);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate)
|
||||
{
|
||||
bool alloced;
|
||||
|
||||
if (sample_rate > TIME_SCALE_MAX_SAMPLE_RATE)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (time_scale_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = true;
|
||||
}
|
||||
/*endif*/
|
||||
s->sample_rate = sample_rate;
|
||||
s->min_pitch = sample_rate/TIME_SCALE_MIN_PITCH;
|
||||
s->max_pitch = sample_rate/TIME_SCALE_MAX_PITCH;
|
||||
s->buf_len = 2*sample_rate/TIME_SCALE_MIN_PITCH;
|
||||
if (time_scale_rate(s, playout_rate))
|
||||
{
|
||||
if (alloced)
|
||||
span_free(s);
|
||||
/*endif*/
|
||||
return NULL;
|
||||
}
|
||||
/*endif*/
|
||||
s->rate_nudge = 0.0f;
|
||||
s->fill = 0;
|
||||
s->lcp = 0;
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s)
|
||||
{
|
||||
span_free(s);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
|
|
|
@ -579,7 +579,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
s->rx.gardner_step = 32;
|
||||
break;
|
||||
case V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES:
|
||||
/* Calling modem only */
|
||||
/* Calling modem only. */
|
||||
/* The calling modem should initially receive unscrambled ones at 1200bps */
|
||||
target = &v22bis_constellation[nearest];
|
||||
track_carrier(s, &z, target);
|
||||
|
@ -621,7 +621,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
}
|
||||
break;
|
||||
case V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES_SUSTAINING:
|
||||
/* Calling modem only */
|
||||
/* Calling modem only. */
|
||||
/* Wait for the end of the unscrambled ones at 1200bps. */
|
||||
target = &v22bis_constellation[nearest];
|
||||
track_carrier(s, &z, target);
|
||||
|
@ -682,7 +682,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
/* The transmit side needs to sustain the scrambled ones for a timed period. */
|
||||
s->tx.training_count = 0;
|
||||
s->tx.training = V22BIS_TX_TRAINING_STAGE_TIMED_S11;
|
||||
/* Normal reception starts immediately */
|
||||
/* Normal reception starts immediately. */
|
||||
s->rx.training = V22BIS_RX_TRAINING_STAGE_NORMAL_OPERATION;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->rx.carrier_track_i = 8;
|
||||
|
|
Loading…
Reference in New Issue