aboutsummaryrefslogtreecommitdiffstats
path: root/main/translate.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-10 23:33:24 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-10 23:33:24 +0000
commitdb54cffaa3ff69480afc0e0d1896ea528a95be62 (patch)
tree58761f191fd0edaf2b417d9de769a06a40aff023 /main/translate.c
parent300fa53d7960a27f73084d7f121a0538c73b9ab6 (diff)
Merged revisions 97976 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r97976 | russell | 2008-01-10 17:30:40 -0600 (Thu, 10 Jan 2008) | 3 lines Fix various timing calculations that made assumptions that the audio being processed was at a sample rate of 8 kHz. ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@97977 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/translate.c')
-rw-r--r--main/translate.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/main/translate.c b/main/translate.c
index 4a4cd3427..1236ee0ee 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -284,6 +284,14 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
return head;
}
+static inline int is16kHz(int format)
+{
+ if (format == AST_FORMAT_G722 || format == AST_FORMAT_SLINEAR16)
+ return 1;
+
+ return 0;
+}
+
/*! \brief do the actual translation */
struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
{
@@ -302,6 +310,11 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
/* XXX hmmm... check this below */
if (!ast_tvzero(f->delivery)) {
+ int in_rate = 8000;
+
+ if (is16kHz(f->subclass))
+ in_rate = 16000;
+
if (!ast_tvzero(path->nextin)) {
/* Make sure this is in line with what we were expecting */
if (!ast_tveq(path->nextin, f->delivery)) {
@@ -320,7 +333,7 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
path->nextout = f->delivery;
}
/* 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;
for ( ; out && p ; p = p->next) {
@@ -333,6 +346,11 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
return NULL;
/* we have a frame, play with times */
if (!ast_tvzero(delivery)) {
+ int out_rate = 8000;
+
+ if (is16kHz(out->subclass))
+ out_rate = 16000;
+
/* Regenerate prediction after a discontinuity */
if (ast_tvzero(path->nextout))
path->nextout = ast_tvnow();
@@ -342,7 +360,7 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
/* Predict next outgoing timestamp from samples in this
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 {
out->delivery = ast_tv(0, 0);
out->has_timing_info = has_timing_info;
@@ -361,11 +379,15 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
/*! \brief compute the cost of a single translation step */
static void calc_cost(struct ast_translator *t, int seconds)
{
- int sofar=0;
+ int num_samples = 0;
struct ast_trans_pvt *pvt;
struct rusage start;
struct rusage end;
int cost;
+ int out_rate = 8000;
+
+ if (is16kHz(t->dstfmt))
+ out_rate = 16000;
if (!seconds)
seconds = 1;
@@ -376,15 +398,18 @@ static void calc_cost(struct ast_translator *t, int seconds)
t->cost = 999999;
return;
}
+
pvt = newpvt(t);
if (!pvt) {
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
t->cost = 999999;
return;
}
+
getrusage(RUSAGE_SELF, &start);
+
/* 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();
if (!f) {
ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
@@ -395,15 +420,20 @@ static void calc_cost(struct ast_translator *t, int seconds)
framein(pvt, f);
ast_frfree(f);
while ((f = t->frameout(pvt))) {
- sofar += f->samples;
+ num_samples += f->samples;
ast_frfree(f);
}
}
+
getrusage(RUSAGE_SELF, &end);
- cost = ((end.ru_utime.tv_sec - start.ru_utime.tv_sec)*1000000) + end.ru_utime.tv_usec - start.ru_utime.tv_usec;
- cost += ((end.ru_stime.tv_sec - start.ru_stime.tv_sec)*1000000) + end.ru_stime.tv_usec - start.ru_stime.tv_usec;
+
+ cost = ((end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + end.ru_utime.tv_usec - start.ru_utime.tv_usec;
+ cost += ((end.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + end.ru_stime.tv_usec - start.ru_stime.tv_usec;
+
destroy(pvt);
+
t->cost = cost / seconds;
+
if (!t->cost)
t->cost = 1;
}