From 58115e9c213fe71729abfd86c5ba97bc575146d3 Mon Sep 17 00:00:00 2001
From: Alexander Traud <pabstraud@compuserve.com>
Date: Sun, 26 Nov 2017 18:47:17 +0100
Subject: [PATCH] translate: Transcode siren14, speex32, silk24, and silk12 via
 slin16.

When a format has no pre-recorded sound files, Asterisk has to transcode between
formats. For this, Asterisk has a fixed translation table. If the pre-recorded
sound files are not available in the same sample rate, Asterisk has not only to
transcode but also to resample.

Asterisk has pre-recorded files for SLN (8000 kHz) and SLN16 (16000 kHz).
However before this change, Asterisk did not take the sample rate into account,
because the translation paths to SLN and SLN16 got the same score/weight in the
table. Consequently, you might have got narrow-band audio with siren14, speex32,
silk24, and silk12 although those are (ultra) wide-band audio codecs.

With this change, the distance in sample-rates is taken into account. Now on the
Command-Line interface (CLI) 'core show channels', you should see:
(slin@16000)->(slin@32000)->(speex@32000).

ASTERISK-23735
Reported by: Richard Kenner

Change-Id: I9448295c1978be26f8633b6066395e7bbbe2e213
---
 main/translate.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/main/translate.c b/main/translate.c
index f2aa5886b2..92c0cb9ea5 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -32,6 +32,7 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <math.h>
+#include <stdlib.h>
 
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
@@ -1390,6 +1391,20 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap,
 				ao2_replace(bestdst, dst);
 				besttablecost = matrix_get(x, y)->table_cost;
 				beststeps = matrix_get(x, y)->multistep;
+			} else if (matrix_get(x, y)->table_cost == besttablecost
+					&& matrix_get(x, y)->multistep == beststeps) {
+				int gap_selected = abs(ast_format_get_sample_rate(best)
+					- ast_format_get_sample_rate(bestdst));
+				int gap_current = abs(ast_format_get_sample_rate(src)
+					- ast_format_get_sample_rate(dst));
+
+				if (gap_current < gap_selected) {
+					/* better than what we have so far */
+					ao2_replace(best, src);
+					ao2_replace(bestdst, dst);
+					besttablecost = matrix_get(x, y)->table_cost;
+					beststeps = matrix_get(x, y)->multistep;
+				}
 			}
 		}
 	}
-- 
GitLab