[asterisk-commits] mmichelson: branch 1.4 r264541 - in /branches/1.4: include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 20 10:59:47 CDT 2010


Author: mmichelson
Date: Thu May 20 10:59:44 2010
New Revision: 264541

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=264541
Log:
1.4 version of PLC fix.

Analogous to trunk revision 264452, but without the change
to chan_sip since it is not necessary in this branch.


Modified:
    branches/1.4/include/asterisk/channel.h
    branches/1.4/include/asterisk/options.h
    branches/1.4/main/channel.c
    branches/1.4/main/loader.c

Modified: branches/1.4/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/channel.h?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/include/asterisk/channel.h (original)
+++ branches/1.4/include/asterisk/channel.h Thu May 20 10:59:44 2010
@@ -1467,6 +1467,12 @@
  */
 char *ast_channel_reason2str(int reason);
 
+/*!
+ * \brief Reload genericplc configuration value from codecs.conf
+ *
+ * Implementation is in main/channel.c
+ */
+int ast_plc_reload(void);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: branches/1.4/include/asterisk/options.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/options.h?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/include/asterisk/options.h (original)
+++ branches/1.4/include/asterisk/options.h Thu May 20 10:59:44 2010
@@ -80,7 +80,9 @@
 	/*! Always fork, even if verbose or debug settings are non-zero */
 	AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
 	/*! Disable log/verbose output to remote consoles */
-	AST_OPT_FLAG_MUTE = (1 << 22)
+	AST_OPT_FLAG_MUTE = (1 << 22),
+	/*! Generic PLC */
+	AST_OPT_FLAG_GENERIC_PLC = (1 << 23),
 };
 
 /*! These are the options that set by default when Asterisk starts */
@@ -113,6 +115,7 @@
 #define ast_opt_internal_timing		ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
 #define ast_opt_always_fork		ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
 #define ast_opt_mute			ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
+#define ast_opt_generic_plc         ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC)
 
 extern struct ast_flags ast_options;
 

Modified: branches/1.4/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/main/channel.c?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/main/channel.c (original)
+++ branches/1.4/main/channel.c Thu May 20 10:59:44 2010
@@ -2854,6 +2854,86 @@
 	return res;
 }
 
+struct plc_ds {
+	/* A buffer in which to store SLIN PLC
+	 * samples generated by the generic PLC
+	 * functionality in plc.c
+	 */
+	int16_t *samples_buf;
+	/* The current number of samples in the
+	 * samples_buf
+	 */
+	size_t num_samples;
+	plc_state_t plc_state;
+};
+
+static void plc_ds_destroy(void *data)
+{
+	struct plc_ds *plc = data;
+	ast_free(plc->samples_buf);
+	ast_free(plc);
+}
+
+static struct ast_datastore_info plc_ds_info = {
+	.type = "plc",
+	.destroy = plc_ds_destroy,
+};
+
+static void adjust_frame_for_plc(struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore)
+{
+	int num_new_samples = frame->samples;
+	struct plc_ds *plc = datastore->data;
+
+	/* First, we need to be sure that our buffer is large enough to accomodate
+	 * the samples we need to fill in. This will likely only occur on the first
+	 * frame we write.
+	 */
+	if (plc->num_samples < num_new_samples) {
+		ast_free(plc->samples_buf);
+		plc->samples_buf = ast_calloc(num_new_samples, sizeof(*plc->samples_buf));
+		if (!plc->samples_buf) {
+			ast_channel_datastore_remove(chan, datastore);
+			ast_channel_datastore_free(datastore);
+			return;
+		}
+		plc->num_samples = num_new_samples;
+	}
+
+	if (frame->datalen == 0) {
+		plc_fillin(&plc->plc_state, plc->samples_buf, frame->samples);
+		frame->data = plc->samples_buf;
+		frame->datalen = num_new_samples * 2;
+	} else {
+		plc_rx(&plc->plc_state, frame->data, frame->samples);
+	}
+}
+
+static void apply_plc(struct ast_channel *chan, struct ast_frame *frame)
+{
+	struct ast_datastore *datastore;
+	struct plc_ds *plc;
+
+	datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL);
+	if (datastore) {
+		plc = datastore->data;
+		adjust_frame_for_plc(chan, frame, datastore);
+		return;
+	}
+
+	datastore = ast_channel_datastore_alloc(&plc_ds_info, NULL);
+	if (!datastore) {
+		return;
+	}
+	plc = ast_calloc(1, sizeof(*plc));
+	if (!plc) {
+		ast_channel_datastore_free(datastore);
+		return;
+	}
+	datastore->data = plc;
+	ast_channel_datastore_add(chan, datastore);
+	adjust_frame_for_plc(chan, frame, datastore);
+}
+
 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 {
 	int res = -1;
@@ -2962,6 +3042,10 @@
 	case AST_FRAME_VOICE:
 		if (chan->tech->write == NULL)
 			break;	/*! \todo XXX should return 0 maybe ? */
+
+		if (ast_opt_generic_plc && fr->subclass == AST_FORMAT_SLINEAR) {
+			apply_plc(chan, fr);
+		}
 
 		/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
 		if (fr->subclass == chan->rawwriteformat)
@@ -3629,10 +3713,12 @@
 	}
 
 	/* if the best path is not 'pass through', then
-	   transcoding is needed; if desired, force transcode path
-	   to use SLINEAR between channels, but only if there is
-	   no direct conversion available */
-	if ((src != dst) && ast_opt_transcode_via_slin &&
+	 * transcoding is needed; if desired, force transcode path
+	 * to use SLINEAR between channels, but only if there is
+	 * no direct conversion available. If generic PLC is
+	 * desired, then transcoding via SLINEAR is a requirement
+	 */
+	if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
 	    (ast_translate_path_steps(dst, src) != 1))
 		dst = AST_FORMAT_SLINEAR;
 	if (ast_set_read_format(peer, dst) < 0) {
@@ -4932,9 +5018,26 @@
 		ast_moh_cleanup_ptr(chan);
 }
 
+int ast_plc_reload(void)
+{
+	struct ast_variable *var;
+	struct ast_config *cfg = ast_config_load("codecs.conf");
+	if (!cfg)
+		return 0;
+	for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
+		if (!strcasecmp(var->name, "genericplc")) {
+			ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
+		}
+	}
+	ast_config_destroy(cfg);
+	return 0;
+}
+
 void ast_channels_init(void)
 {
 	ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
+
+	ast_plc_reload();
 }
 
 /*! \brief Print call group and pickup group ---*/

Modified: branches/1.4/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/main/loader.c?view=diff&rev=264541&r1=264540&r2=264541
==============================================================================
--- branches/1.4/main/loader.c (original)
+++ branches/1.4/main/loader.c Thu May 20 10:59:44 2010
@@ -258,6 +258,7 @@
 	{ "rtp",	ast_rtp_reload },
 	{ "http",	ast_http_reload },
 	{ "logger",	logger_reload },
+	{ "plc",        ast_plc_reload },
 	{ NULL, 	NULL }
 };
 




More information about the asterisk-commits mailing list