From c4558236573ac599e6664c47e4db19d8a8eb953e Mon Sep 17 00:00:00 2001 From: frahaase Date: Fri, 12 Aug 2016 18:22:02 +0200 Subject: Binaural synthesis (confbridge): interleaved two-channel audio. Asterisk only supports mono audio at the moment. This patch adds interleaved two-channel audio to Asterisk's channels. ASTERISK-26292 Change-Id: I7a547cea0fd3c6d1e502709d9e7e39605035757a --- main/channel.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'main') diff --git a/main/channel.c b/main/channel.c index 1f18d53b1..f8b218fd0 100644 --- a/main/channel.c +++ b/main/channel.c @@ -5407,7 +5407,7 @@ static const struct set_format_access set_format_access_write = { .setoption = AST_OPTION_FORMAT_WRITE, }; -static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction) +static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction, int interleaved_stereo) { struct ast_trans_pvt *trans_pvt; struct ast_format_cap *cap_native; @@ -5509,16 +5509,20 @@ static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, } /* Now we have a good choice for both. */ + trans_pvt = access->get_trans(chan); if ((ast_format_cmp(rawformat, best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) && (ast_format_cmp(format, best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) && ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || access->get_trans(chan))) { - /* the channel is already in these formats, so nothing to do */ - ast_channel_unlock(chan); - return 0; + /* the channel is already in these formats, so nothing to do, unless the interleaved format is not set correctly */ + if (trans_pvt != NULL) { + if (trans_pvt->interleaved_stereo == interleaved_stereo) { + ast_channel_unlock(chan); + return 0; + } + } } /* Free any translation we have right now */ - trans_pvt = access->get_trans(chan); if (trans_pvt) { ast_translator_free_path(trans_pvt); access->set_trans(chan, NULL); @@ -5536,9 +5540,11 @@ static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, if (!direction) { /* reading */ trans_pvt = ast_translator_build_path(best_set_fmt, best_native_fmt); + trans_pvt->interleaved_stereo = 0; } else { /* writing */ trans_pvt = ast_translator_build_path(best_native_fmt, best_set_fmt); + trans_pvt->interleaved_stereo = interleaved_stereo; } access->set_trans(chan, trans_pvt); res = trans_pvt ? 0 : -1; @@ -5578,7 +5584,7 @@ int ast_set_read_format(struct ast_channel *chan, struct ast_format *format) } ast_format_cap_append(cap, format, 0); - res = set_format(chan, cap, 0); + res = set_format(chan, cap, 0, 0); ao2_cleanup(cap); return res; @@ -5586,7 +5592,25 @@ int ast_set_read_format(struct ast_channel *chan, struct ast_format *format) int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap) { - return set_format(chan, cap, 0); + return set_format(chan, cap, 0, 0); +} + +int ast_set_write_format_interleaved_stereo(struct ast_channel *chan, struct ast_format *format) +{ + struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); + int res; + + ast_assert(format != NULL); + + if (!cap) { + return -1; + } + ast_format_cap_append(cap, format, 0); + + res = set_format(chan, cap, 1, 1); + + ao2_cleanup(cap); + return res; } int ast_set_write_format(struct ast_channel *chan, struct ast_format *format) @@ -5601,7 +5625,7 @@ int ast_set_write_format(struct ast_channel *chan, struct ast_format *format) } ast_format_cap_append(cap, format, 0); - res = set_format(chan, cap, 1); + res = set_format(chan, cap, 1, 0); ao2_cleanup(cap); return res; @@ -5609,7 +5633,7 @@ int ast_set_write_format(struct ast_channel *chan, struct ast_format *format) int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap) { - return set_format(chan, cap, 1); + return set_format(chan, cap, 1, 0); } const char *ast_channel_reason2str(int reason) -- cgit v1.2.3