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:
Russell Bryant
2008-01-10 23:30:40 +00:00
parent 7f61492a42
commit 8fd3d8a51b

View File

@@ -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;
} }