mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Fix various timing calculations that made assumptions that the audio being
processed was at a sample rate of 8 kHz. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@97976 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -294,6 +294,14 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
|
|||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int is16kHz(int format)
|
||||||
|
{
|
||||||
|
if (format == AST_FORMAT_G722)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief do the actual translation */
|
/*! \brief do the actual translation */
|
||||||
struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
|
struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
|
||||||
{
|
{
|
||||||
@@ -312,6 +320,11 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
|
|
||||||
/* XXX hmmm... check this below */
|
/* XXX hmmm... check this below */
|
||||||
if (!ast_tvzero(f->delivery)) {
|
if (!ast_tvzero(f->delivery)) {
|
||||||
|
int in_rate = 8000;
|
||||||
|
|
||||||
|
if (is16kHz(f->subclass))
|
||||||
|
in_rate = 16000;
|
||||||
|
|
||||||
if (!ast_tvzero(path->nextin)) {
|
if (!ast_tvzero(path->nextin)) {
|
||||||
/* Make sure this is in line with what we were expecting */
|
/* Make sure this is in line with what we were expecting */
|
||||||
if (!ast_tveq(path->nextin, f->delivery)) {
|
if (!ast_tveq(path->nextin, f->delivery)) {
|
||||||
@@ -330,7 +343,7 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
path->nextout = f->delivery;
|
path->nextout = f->delivery;
|
||||||
}
|
}
|
||||||
/* Predict next incoming sample */
|
/* Predict next incoming sample */
|
||||||
path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000));
|
path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, in_rate));
|
||||||
}
|
}
|
||||||
delivery = f->delivery;
|
delivery = f->delivery;
|
||||||
for ( ; out && p ; p = p->next) {
|
for ( ; out && p ; p = p->next) {
|
||||||
@@ -343,6 +356,11 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
return NULL;
|
return NULL;
|
||||||
/* we have a frame, play with times */
|
/* we have a frame, play with times */
|
||||||
if (!ast_tvzero(delivery)) {
|
if (!ast_tvzero(delivery)) {
|
||||||
|
int out_rate = 8000;
|
||||||
|
|
||||||
|
if (is16kHz(out->subclass))
|
||||||
|
out_rate = 16000;
|
||||||
|
|
||||||
/* Regenerate prediction after a discontinuity */
|
/* Regenerate prediction after a discontinuity */
|
||||||
if (ast_tvzero(path->nextout))
|
if (ast_tvzero(path->nextout))
|
||||||
path->nextout = ast_tvnow();
|
path->nextout = ast_tvnow();
|
||||||
@@ -352,7 +370,7 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
|
|
||||||
/* Predict next outgoing timestamp from samples in this
|
/* Predict next outgoing timestamp from samples in this
|
||||||
frame. */
|
frame. */
|
||||||
path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000));
|
path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, out_rate));
|
||||||
} else {
|
} else {
|
||||||
out->delivery = ast_tv(0, 0);
|
out->delivery = ast_tv(0, 0);
|
||||||
out->has_timing_info = has_timing_info;
|
out->has_timing_info = has_timing_info;
|
||||||
@@ -371,10 +389,14 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
/*! \brief compute the cost of a single translation step */
|
/*! \brief compute the cost of a single translation step */
|
||||||
static void calc_cost(struct ast_translator *t, int seconds)
|
static void calc_cost(struct ast_translator *t, int seconds)
|
||||||
{
|
{
|
||||||
int sofar=0;
|
int num_samples = 0;
|
||||||
struct ast_trans_pvt *pvt;
|
struct ast_trans_pvt *pvt;
|
||||||
struct timeval start;
|
struct timeval start;
|
||||||
int cost;
|
int cost;
|
||||||
|
int out_rate = 8000;
|
||||||
|
|
||||||
|
if (is16kHz(t->dstfmt))
|
||||||
|
out_rate = 16000;
|
||||||
|
|
||||||
if (!seconds)
|
if (!seconds)
|
||||||
seconds = 1;
|
seconds = 1;
|
||||||
@@ -385,15 +407,18 @@ static void calc_cost(struct ast_translator *t, int seconds)
|
|||||||
t->cost = 99999;
|
t->cost = 99999;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pvt = newpvt(t);
|
pvt = newpvt(t);
|
||||||
if (!pvt) {
|
if (!pvt) {
|
||||||
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
|
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
|
||||||
t->cost = 99999;
|
t->cost = 99999;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = ast_tvnow();
|
start = ast_tvnow();
|
||||||
|
|
||||||
/* Call the encoder until we've processed the required number of samples */
|
/* Call the encoder until we've processed the required number of samples */
|
||||||
while (sofar < seconds * 8000) {
|
while (num_samples < seconds * out_rate) {
|
||||||
struct ast_frame *f = t->sample();
|
struct ast_frame *f = t->sample();
|
||||||
if (!f) {
|
if (!f) {
|
||||||
ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
|
ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
|
||||||
@@ -404,13 +429,17 @@ static void calc_cost(struct ast_translator *t, int seconds)
|
|||||||
framein(pvt, f);
|
framein(pvt, f);
|
||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
while ((f = t->frameout(pvt))) {
|
while ((f = t->frameout(pvt))) {
|
||||||
sofar += f->samples;
|
num_samples += f->samples;
|
||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cost = ast_tvdiff_ms(ast_tvnow(), start);
|
cost = ast_tvdiff_ms(ast_tvnow(), start);
|
||||||
|
|
||||||
destroy(pvt);
|
destroy(pvt);
|
||||||
|
|
||||||
t->cost = cost / seconds;
|
t->cost = cost / seconds;
|
||||||
|
|
||||||
if (!t->cost)
|
if (!t->cost)
|
||||||
t->cost = 1;
|
t->cost = 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user