00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "asterisk.h"
00035
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 399353 $")
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <sys/time.h>
00042 #include <signal.h>
00043 #include <errno.h>
00044 #include <unistd.h>
00045
00046 #include "asterisk/module.h"
00047 #include "asterisk/channel.h"
00048 #include "asterisk/bridging.h"
00049 #include "asterisk/bridging_technology.h"
00050 #include "asterisk/frame.h"
00051 #include "asterisk/options.h"
00052 #include "asterisk/logger.h"
00053 #include "asterisk/slinfactory.h"
00054 #include "asterisk/astobj2.h"
00055 #include "asterisk/timing.h"
00056 #include "asterisk/translate.h"
00057
00058 #define MAX_DATALEN 8096
00059
00060
00061 #define DEFAULT_SOFTMIX_INTERVAL 20
00062
00063
00064 #define SOFTMIX_DATALEN(rate, interval) ((rate/50) * (interval / 10))
00065
00066
00067 #define SOFTMIX_SAMPLES(rate, interval) (SOFTMIX_DATALEN(rate, interval) / 2)
00068
00069
00070 #define SOFTMIX_STAT_INTERVAL 100
00071
00072
00073
00074 #define DEFAULT_SOFTMIX_SILENCE_THRESHOLD 2500
00075 #define DEFAULT_SOFTMIX_TALKING_THRESHOLD 160
00076
00077 #define DEFAULT_ENERGY_HISTORY_LEN 150
00078
00079 struct video_follow_talker_data {
00080
00081 int energy_history[DEFAULT_ENERGY_HISTORY_LEN];
00082
00083
00084 int energy_history_cur_slot;
00085
00086 int energy_accum;
00087
00088 int energy_average;
00089 };
00090
00091
00092 struct softmix_channel {
00093
00094 ast_mutex_t lock;
00095
00096 struct ast_slinfactory factory;
00097
00098 struct ast_frame write_frame;
00099
00100 struct ast_frame read_frame;
00101
00102 struct ast_dsp *dsp;
00103
00104
00105 int talking:1;
00106
00107 int have_audio:1;
00108
00109 int have_frame:1;
00110
00111 short final_buf[MAX_DATALEN];
00112
00113 short our_buf[MAX_DATALEN];
00114
00115 struct video_follow_talker_data video_talker;
00116 };
00117
00118 struct softmix_bridge_data {
00119 struct ast_timer *timer;
00120 unsigned int internal_rate;
00121 unsigned int internal_mixing_interval;
00122 };
00123
00124 struct softmix_stats {
00125
00126 unsigned int sample_rates[16];
00127
00128 unsigned int num_channels[16];
00129
00130 unsigned int num_above_internal_rate;
00131
00132 unsigned int num_at_internal_rate;
00133
00134 unsigned int highest_supported_rate;
00135
00136 unsigned int locked_rate;
00137 };
00138
00139 struct softmix_mixing_array {
00140 int max_num_entries;
00141 int used_entries;
00142 int16_t **buffers;
00143 };
00144
00145 struct softmix_translate_helper_entry {
00146 int num_times_requested;
00147
00148 struct ast_format dst_format;
00149 struct ast_trans_pvt *trans_pvt;
00150 struct ast_frame *out_frame;
00151 AST_LIST_ENTRY(softmix_translate_helper_entry) entry;
00152 };
00153
00154 struct softmix_translate_helper {
00155 struct ast_format slin_src;
00156 AST_LIST_HEAD_NOLOCK(, softmix_translate_helper_entry) entries;
00157 };
00158
00159 static struct softmix_translate_helper_entry *softmix_translate_helper_entry_alloc(struct ast_format *dst)
00160 {
00161 struct softmix_translate_helper_entry *entry;
00162 if (!(entry = ast_calloc(1, sizeof(*entry)))) {
00163 return NULL;
00164 }
00165 ast_format_copy(&entry->dst_format, dst);
00166 return entry;
00167 }
00168
00169 static void *softmix_translate_helper_free_entry(struct softmix_translate_helper_entry *entry)
00170 {
00171 if (entry->trans_pvt) {
00172 ast_translator_free_path(entry->trans_pvt);
00173 }
00174 if (entry->out_frame) {
00175 ast_frfree(entry->out_frame);
00176 }
00177 ast_free(entry);
00178 return NULL;
00179 }
00180
00181 static void softmix_translate_helper_init(struct softmix_translate_helper *trans_helper, unsigned int sample_rate)
00182 {
00183 memset(trans_helper, 0, sizeof(*trans_helper));
00184 ast_format_set(&trans_helper->slin_src, ast_format_slin_by_rate(sample_rate), 0);
00185 }
00186
00187 static void softmix_translate_helper_destroy(struct softmix_translate_helper *trans_helper)
00188 {
00189 struct softmix_translate_helper_entry *entry;
00190
00191 while ((entry = AST_LIST_REMOVE_HEAD(&trans_helper->entries, entry))) {
00192 softmix_translate_helper_free_entry(entry);
00193 }
00194 }
00195
00196 static void softmix_translate_helper_change_rate(struct softmix_translate_helper *trans_helper, unsigned int sample_rate)
00197 {
00198 struct softmix_translate_helper_entry *entry;
00199
00200 ast_format_set(&trans_helper->slin_src, ast_format_slin_by_rate(sample_rate), 0);
00201 AST_LIST_TRAVERSE_SAFE_BEGIN(&trans_helper->entries, entry, entry) {
00202 if (entry->trans_pvt) {
00203 ast_translator_free_path(entry->trans_pvt);
00204 if (!(entry->trans_pvt = ast_translator_build_path(&entry->dst_format, &trans_helper->slin_src))) {
00205 AST_LIST_REMOVE_CURRENT(entry);
00206 entry = softmix_translate_helper_free_entry(entry);
00207 }
00208 }
00209 }
00210 AST_LIST_TRAVERSE_SAFE_END;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 static int16_t *softmix_process_read_audio(struct softmix_channel *sc, unsigned int num_samples)
00222 {
00223 if ((ast_slinfactory_available(&sc->factory) >= num_samples) &&
00224 ast_slinfactory_read(&sc->factory, sc->our_buf, num_samples)) {
00225 sc->have_audio = 1;
00226 return sc->our_buf;
00227 }
00228 sc->have_audio = 0;
00229 return NULL;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 static void softmix_process_write_audio(struct softmix_translate_helper *trans_helper,
00241 struct ast_format *raw_write_fmt,
00242 struct softmix_channel *sc)
00243 {
00244 struct softmix_translate_helper_entry *entry = NULL;
00245 int i;
00246
00247
00248
00249 if (sc->have_audio && sc->talking) {
00250 for (i = 0; i < sc->write_frame.samples; i++) {
00251 ast_slinear_saturated_subtract(&sc->final_buf[i], &sc->our_buf[i]);
00252 }
00253
00254
00255 return;
00256 }
00257
00258 AST_LIST_TRAVERSE(&trans_helper->entries, entry, entry) {
00259 if (ast_format_cmp(&entry->dst_format, raw_write_fmt) == AST_FORMAT_CMP_EQUAL) {
00260 entry->num_times_requested++;
00261 } else {
00262 continue;
00263 }
00264 if (!entry->trans_pvt && (entry->num_times_requested > 1)) {
00265 entry->trans_pvt = ast_translator_build_path(&entry->dst_format, &trans_helper->slin_src);
00266 }
00267 if (entry->trans_pvt && !entry->out_frame) {
00268 entry->out_frame = ast_translate(entry->trans_pvt, &sc->write_frame, 0);
00269 }
00270 if (entry->out_frame && (entry->out_frame->datalen < MAX_DATALEN)) {
00271 ast_format_copy(&sc->write_frame.subclass.format, &entry->out_frame->subclass.format);
00272 memcpy(sc->final_buf, entry->out_frame->data.ptr, entry->out_frame->datalen);
00273 sc->write_frame.datalen = entry->out_frame->datalen;
00274 sc->write_frame.samples = entry->out_frame->samples;
00275 }
00276 break;
00277 }
00278
00279
00280 if (!entry && (entry = softmix_translate_helper_entry_alloc(raw_write_fmt))) {
00281 AST_LIST_INSERT_HEAD(&trans_helper->entries, entry, entry);
00282 }
00283 }
00284
00285 static void softmix_translate_helper_cleanup(struct softmix_translate_helper *trans_helper)
00286 {
00287 struct softmix_translate_helper_entry *entry = NULL;
00288 AST_LIST_TRAVERSE(&trans_helper->entries, entry, entry) {
00289 if (entry->out_frame) {
00290 ast_frfree(entry->out_frame);
00291 entry->out_frame = NULL;
00292 }
00293 entry->num_times_requested = 0;
00294 }
00295 }
00296
00297 static void softmix_bridge_data_destroy(void *obj)
00298 {
00299 struct softmix_bridge_data *softmix_data = obj;
00300
00301 if (softmix_data->timer) {
00302 ast_timer_close(softmix_data->timer);
00303 softmix_data->timer = NULL;
00304 }
00305 }
00306
00307
00308 static int softmix_bridge_create(struct ast_bridge *bridge)
00309 {
00310 struct softmix_bridge_data *softmix_data;
00311
00312 if (!(softmix_data = ao2_alloc(sizeof(*softmix_data), softmix_bridge_data_destroy))) {
00313 return -1;
00314 }
00315 if (!(softmix_data->timer = ast_timer_open())) {
00316 ast_log(AST_LOG_WARNING, "Failed to open timer for softmix bridge\n");
00317 ao2_ref(softmix_data, -1);
00318 return -1;
00319 }
00320
00321
00322 softmix_data->internal_rate = 8000;
00323 softmix_data->internal_mixing_interval = DEFAULT_SOFTMIX_INTERVAL;
00324
00325 bridge->bridge_pvt = softmix_data;
00326 return 0;
00327 }
00328
00329
00330 static int softmix_bridge_destroy(struct ast_bridge *bridge)
00331 {
00332 struct softmix_bridge_data *softmix_data = bridge->bridge_pvt;
00333 if (!bridge->bridge_pvt) {
00334 return -1;
00335 }
00336 ao2_ref(softmix_data, -1);
00337 bridge->bridge_pvt = NULL;
00338 return 0;
00339 }
00340
00341 static void set_softmix_bridge_data(int rate, int interval, struct ast_bridge_channel *bridge_channel, int reset)
00342 {
00343 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00344 unsigned int channel_read_rate = ast_format_rate(ast_channel_rawreadformat(bridge_channel->chan));
00345
00346 ast_mutex_lock(&sc->lock);
00347 if (reset) {
00348 ast_slinfactory_destroy(&sc->factory);
00349 ast_dsp_free(sc->dsp);
00350 }
00351
00352 sc->write_frame.frametype = AST_FRAME_VOICE;
00353 ast_format_set(&sc->write_frame.subclass.format, ast_format_slin_by_rate(rate), 0);
00354 sc->write_frame.data.ptr = sc->final_buf;
00355 sc->write_frame.datalen = SOFTMIX_DATALEN(rate, interval);
00356 sc->write_frame.samples = SOFTMIX_SAMPLES(rate, interval);
00357
00358 sc->read_frame.frametype = AST_FRAME_VOICE;
00359 ast_format_set(&sc->read_frame.subclass.format, ast_format_slin_by_rate(channel_read_rate), 0);
00360 sc->read_frame.data.ptr = sc->our_buf;
00361 sc->read_frame.datalen = SOFTMIX_DATALEN(channel_read_rate, interval);
00362 sc->read_frame.samples = SOFTMIX_SAMPLES(channel_read_rate, interval);
00363
00364
00365 ast_slinfactory_init_with_format(&sc->factory, &sc->write_frame.subclass.format);
00366
00367
00368 ast_set_read_format(bridge_channel->chan, &sc->read_frame.subclass.format);
00369 ast_set_write_format(bridge_channel->chan, &sc->write_frame.subclass.format);
00370
00371
00372 sc->dsp = ast_dsp_new_with_rate(channel_read_rate);
00373
00374 if (bridge_channel->tech_args.talking_threshold) {
00375 ast_dsp_set_threshold(sc->dsp, bridge_channel->tech_args.talking_threshold);
00376 } else {
00377 ast_dsp_set_threshold(sc->dsp, DEFAULT_SOFTMIX_TALKING_THRESHOLD);
00378 }
00379
00380 ast_mutex_unlock(&sc->lock);
00381 }
00382
00383
00384 static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00385 {
00386 struct softmix_channel *sc = NULL;
00387 struct softmix_bridge_data *softmix_data = bridge->bridge_pvt;
00388
00389
00390 if (!(sc = ast_calloc(1, sizeof(*sc)))) {
00391 return -1;
00392 }
00393
00394
00395 ast_mutex_init(&sc->lock);
00396
00397
00398 bridge_channel->bridge_pvt = sc;
00399
00400 set_softmix_bridge_data(softmix_data->internal_rate,
00401 softmix_data->internal_mixing_interval ? softmix_data->internal_mixing_interval : DEFAULT_SOFTMIX_INTERVAL,
00402 bridge_channel, 0);
00403
00404 return 0;
00405 }
00406
00407
00408 static int softmix_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00409 {
00410 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00411
00412 if (!(bridge_channel->bridge_pvt)) {
00413 return 0;
00414 }
00415 bridge_channel->bridge_pvt = NULL;
00416
00417
00418 ast_mutex_destroy(&sc->lock);
00419
00420
00421 ast_slinfactory_destroy(&sc->factory);
00422
00423
00424 ast_dsp_free(sc->dsp);
00425
00426
00427 ast_free(sc);
00428
00429 return 0;
00430 }
00431
00432
00433
00434
00435
00436 static void softmix_pass_dtmf(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
00437 {
00438 struct ast_bridge_channel *tmp;
00439 AST_LIST_TRAVERSE(&bridge->channels, tmp, entry) {
00440 if (tmp == bridge_channel) {
00441 continue;
00442 }
00443 ast_write(tmp->chan, frame);
00444 }
00445 }
00446
00447 static void softmix_pass_video_top_priority(struct ast_bridge *bridge, struct ast_frame *frame)
00448 {
00449 struct ast_bridge_channel *tmp;
00450 AST_LIST_TRAVERSE(&bridge->channels, tmp, entry) {
00451 if (tmp->suspended) {
00452 continue;
00453 }
00454 if (ast_bridge_is_video_src(bridge, tmp->chan) == 1) {
00455 ast_write(tmp->chan, frame);
00456 break;
00457 }
00458 }
00459 }
00460
00461 static void softmix_pass_video_all(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame, int echo)
00462 {
00463 struct ast_bridge_channel *tmp;
00464 AST_LIST_TRAVERSE(&bridge->channels, tmp, entry) {
00465 if (tmp->suspended) {
00466 continue;
00467 }
00468 if ((tmp->chan == bridge_channel->chan) && !echo) {
00469 continue;
00470 }
00471 ast_write(tmp->chan, frame);
00472 }
00473 }
00474
00475
00476 static enum ast_bridge_write_result softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
00477 {
00478 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00479 struct softmix_bridge_data *softmix_data = bridge->bridge_pvt;
00480 int totalsilence = 0;
00481 int cur_energy = 0;
00482 int silence_threshold = bridge_channel->tech_args.silence_threshold ?
00483 bridge_channel->tech_args.silence_threshold :
00484 DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
00485 char update_talking = -1;
00486 int res = AST_BRIDGE_WRITE_SUCCESS;
00487
00488
00489 if (frame->frametype == AST_FRAME_DTMF_END || frame->frametype == AST_FRAME_DTMF_BEGIN) {
00490 softmix_pass_dtmf(bridge, bridge_channel, frame);
00491 goto bridge_write_cleanup;
00492 } else if (frame->frametype != AST_FRAME_VOICE && frame->frametype != AST_FRAME_VIDEO) {
00493 res = AST_BRIDGE_WRITE_UNSUPPORTED;
00494 goto bridge_write_cleanup;
00495 } else if (frame->datalen == 0) {
00496 goto bridge_write_cleanup;
00497 }
00498
00499
00500 if (frame->frametype == AST_FRAME_VIDEO) {
00501 int num_src = ast_bridge_number_video_src(bridge);
00502 int video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
00503
00504 switch (bridge->video_mode.mode) {
00505 case AST_BRIDGE_VIDEO_MODE_NONE:
00506 break;
00507 case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
00508 if (video_src_priority == 1) {
00509 softmix_pass_video_all(bridge, bridge_channel, frame, 1);
00510 }
00511 break;
00512 case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
00513 ast_mutex_lock(&sc->lock);
00514 ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan, sc->video_talker.energy_average, ast_format_get_video_mark(&frame->subclass.format));
00515 ast_mutex_unlock(&sc->lock);
00516 if (video_src_priority == 1) {
00517 int echo = num_src > 1 ? 0 : 1;
00518 softmix_pass_video_all(bridge, bridge_channel, frame, echo);
00519 } else if (video_src_priority == 2) {
00520 softmix_pass_video_top_priority(bridge, frame);
00521 }
00522 break;
00523 }
00524 goto bridge_write_cleanup;
00525 }
00526
00527
00528 ast_mutex_lock(&sc->lock);
00529 ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
00530
00531 if (bridge->video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
00532 int cur_slot = sc->video_talker.energy_history_cur_slot;
00533 sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot];
00534 sc->video_talker.energy_accum += cur_energy;
00535 sc->video_talker.energy_history[cur_slot] = cur_energy;
00536 sc->video_talker.energy_average = sc->video_talker.energy_accum / DEFAULT_ENERGY_HISTORY_LEN;
00537 sc->video_talker.energy_history_cur_slot++;
00538 if (sc->video_talker.energy_history_cur_slot == DEFAULT_ENERGY_HISTORY_LEN) {
00539 sc->video_talker.energy_history_cur_slot = 0;
00540 }
00541 }
00542
00543 if (totalsilence < silence_threshold) {
00544 if (!sc->talking) {
00545 update_talking = 1;
00546 }
00547 sc->talking = 1;
00548 } else {
00549 if (sc->talking) {
00550 update_talking = 0;
00551 }
00552 sc->talking = 0;
00553 }
00554
00555
00556
00557
00558 if (ast_slinfactory_available(&sc->factory) > (4 * SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval))) {
00559 ast_slinfactory_flush(&sc->factory);
00560 }
00561
00562
00563
00564 if (!(bridge_channel->tech_args.drop_silence && !sc->talking) &&
00565 (frame->frametype == AST_FRAME_VOICE && ast_format_is_slinear(&frame->subclass.format))) {
00566 ast_slinfactory_feed(&sc->factory, frame);
00567 }
00568
00569
00570 if (sc->have_frame) {
00571 ast_write(bridge_channel->chan, &sc->write_frame);
00572 sc->have_frame = 0;
00573 }
00574
00575
00576 ast_mutex_unlock(&sc->lock);
00577
00578 if (update_talking != -1) {
00579 ast_bridge_notify_talking(bridge, bridge_channel, update_talking);
00580 }
00581
00582 return res;
00583
00584 bridge_write_cleanup:
00585
00586
00587
00588 ast_mutex_lock(&sc->lock);
00589 if (sc->have_frame) {
00590 ast_write(bridge_channel->chan, &sc->write_frame);
00591 sc->have_frame = 0;
00592 }
00593 ast_mutex_unlock(&sc->lock);
00594
00595 return res;
00596 }
00597
00598
00599 static int softmix_bridge_poke(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00600 {
00601 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00602
00603 ast_mutex_lock(&sc->lock);
00604
00605 if (sc->have_frame) {
00606 ast_write(bridge_channel->chan, &sc->write_frame);
00607 sc->have_frame = 0;
00608 }
00609
00610 ast_mutex_unlock(&sc->lock);
00611
00612 return 0;
00613 }
00614
00615 static void gather_softmix_stats(struct softmix_stats *stats,
00616 const struct softmix_bridge_data *softmix_data,
00617 struct ast_bridge_channel *bridge_channel)
00618 {
00619 int channel_native_rate;
00620 int i;
00621
00622 channel_native_rate = MAX(ast_format_rate(ast_channel_rawwriteformat(bridge_channel->chan)),
00623 ast_format_rate(ast_channel_rawreadformat(bridge_channel->chan)));
00624
00625 if (channel_native_rate > stats->highest_supported_rate) {
00626 stats->highest_supported_rate = channel_native_rate;
00627 }
00628 if (channel_native_rate > softmix_data->internal_rate) {
00629 for (i = 0; i < ARRAY_LEN(stats->sample_rates); i++) {
00630 if (stats->sample_rates[i] == channel_native_rate) {
00631 stats->num_channels[i]++;
00632 break;
00633 } else if (!stats->sample_rates[i]) {
00634 stats->sample_rates[i] = channel_native_rate;
00635 stats->num_channels[i]++;
00636 break;
00637 }
00638 }
00639 stats->num_above_internal_rate++;
00640 } else if (channel_native_rate == softmix_data->internal_rate) {
00641 stats->num_at_internal_rate++;
00642 }
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652 static unsigned int analyse_softmix_stats(struct softmix_stats *stats, struct softmix_bridge_data *softmix_data)
00653 {
00654 int i;
00655
00656
00657
00658
00659
00660
00661 if (stats->locked_rate) {
00662
00663
00664 if (softmix_data->internal_rate != stats->locked_rate) {
00665 softmix_data->internal_rate = stats->locked_rate;
00666 ast_debug(1, " Bridge is locked in at sample rate %d\n", softmix_data->internal_rate);
00667 return 1;
00668 }
00669 } else if (stats->num_above_internal_rate >= 2) {
00670
00671 unsigned int best_rate = stats->highest_supported_rate;
00672 int best_index = -1;
00673
00674 for (i = 0; i < ARRAY_LEN(stats->num_channels); i++) {
00675 if (stats->num_channels[i]) {
00676 break;
00677 }
00678
00679
00680
00681 if (stats->num_channels[i] >= 2 && (best_index == -1)) {
00682 best_rate = stats->sample_rates[i];
00683 best_index = i;
00684
00685
00686
00687
00688 } else if (((best_index != -1) &&
00689 (stats->num_channels[i] >= 2) &&
00690 (stats->sample_rates[best_index] < stats->sample_rates[i]))) {
00691 best_rate = stats->sample_rates[i];
00692 best_index = i;
00693
00694
00695
00696
00697
00698
00699
00700 } else if (best_index == -1) {
00701 best_rate = MIN(best_rate, stats->sample_rates[i]);
00702 }
00703 }
00704
00705 ast_debug(1, " Bridge changed from %d To %d\n", softmix_data->internal_rate, best_rate);
00706 softmix_data->internal_rate = best_rate;
00707 return 1;
00708 } else if (!stats->num_at_internal_rate && !stats->num_above_internal_rate) {
00709
00710 softmix_data->internal_rate = stats->highest_supported_rate;
00711 ast_debug(1, " Bridge changed from %d to %d\n", softmix_data->internal_rate, stats->highest_supported_rate);
00712 return 1;
00713 }
00714 return 0;
00715 }
00716
00717 static int softmix_mixing_array_init(struct softmix_mixing_array *mixing_array, unsigned int starting_num_entries)
00718 {
00719 memset(mixing_array, 0, sizeof(*mixing_array));
00720 mixing_array->max_num_entries = starting_num_entries;
00721 if (!(mixing_array->buffers = ast_calloc(mixing_array->max_num_entries, sizeof(int16_t *)))) {
00722 ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure. \n");
00723 return -1;
00724 }
00725 return 0;
00726 }
00727
00728 static void softmix_mixing_array_destroy(struct softmix_mixing_array *mixing_array)
00729 {
00730 ast_free(mixing_array->buffers);
00731 }
00732
00733 static int softmix_mixing_array_grow(struct softmix_mixing_array *mixing_array, unsigned int num_entries)
00734 {
00735 int16_t **tmp;
00736
00737 mixing_array->max_num_entries = num_entries;
00738 if (!(tmp = ast_realloc(mixing_array->buffers, (mixing_array->max_num_entries * sizeof(int16_t *))))) {
00739 ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure. \n");
00740 return -1;
00741 }
00742 mixing_array->buffers = tmp;
00743 return 0;
00744 }
00745
00746
00747 static int softmix_bridge_thread(struct ast_bridge *bridge)
00748 {
00749 struct softmix_stats stats = { { 0 }, };
00750 struct softmix_mixing_array mixing_array;
00751 struct softmix_bridge_data *softmix_data = bridge->bridge_pvt;
00752 struct ast_timer *timer;
00753 struct softmix_translate_helper trans_helper;
00754 int16_t buf[MAX_DATALEN] = { 0, };
00755 unsigned int stat_iteration_counter = 0;
00756 int timingfd;
00757 int update_all_rates = 0;
00758 int i, x;
00759 int res = -1;
00760
00761 if (!(softmix_data = bridge->bridge_pvt)) {
00762 goto softmix_cleanup;
00763 }
00764
00765 ao2_ref(softmix_data, 1);
00766 timer = softmix_data->timer;
00767 timingfd = ast_timer_fd(timer);
00768 softmix_translate_helper_init(&trans_helper, softmix_data->internal_rate);
00769 ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
00770
00771
00772 if (softmix_mixing_array_init(&mixing_array, bridge->num + 10)) {
00773 ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure. \n");
00774 goto softmix_cleanup;
00775 }
00776
00777 while (!bridge->stop && !bridge->refresh && bridge->array_num) {
00778 struct ast_bridge_channel *bridge_channel = NULL;
00779 int timeout = -1;
00780 enum ast_format_id cur_slin_id = ast_format_slin_by_rate(softmix_data->internal_rate);
00781 unsigned int softmix_samples = SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
00782 unsigned int softmix_datalen = SOFTMIX_DATALEN(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
00783
00784 if (softmix_datalen > MAX_DATALEN) {
00785
00786
00787
00788
00789 ast_log(LOG_WARNING, "Conference mixing error, requested mixing length greater than mixing buffer.\n");
00790 goto softmix_cleanup;
00791 }
00792
00793
00794 if (mixing_array.max_num_entries < bridge->num && softmix_mixing_array_grow(&mixing_array, bridge->num + 5)) {
00795 goto softmix_cleanup;
00796 }
00797
00798
00799
00800 mixing_array.used_entries = 0;
00801
00802
00803 if (!stat_iteration_counter) {
00804 memset(&stats, 0, sizeof(stats));
00805 stats.locked_rate = bridge->internal_sample_rate;
00806 }
00807
00808
00809 if (update_all_rates) {
00810 softmix_translate_helper_change_rate(&trans_helper, softmix_data->internal_rate);
00811 }
00812
00813
00814 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00815 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00816
00817
00818 if (update_all_rates) {
00819 set_softmix_bridge_data(softmix_data->internal_rate, softmix_data->internal_mixing_interval, bridge_channel, 1);
00820 }
00821
00822
00823 if (!stat_iteration_counter) {
00824 gather_softmix_stats(&stats, softmix_data, bridge_channel);
00825 }
00826
00827
00828 if (bridge_channel->suspended) {
00829 continue;
00830 }
00831
00832
00833 ast_mutex_lock(&sc->lock);
00834 if ((mixing_array.buffers[mixing_array.used_entries] = softmix_process_read_audio(sc, softmix_samples))) {
00835 mixing_array.used_entries++;
00836 }
00837 ast_mutex_unlock(&sc->lock);
00838 }
00839
00840
00841 memset(buf, 0, softmix_datalen);
00842 for (i = 0; i < mixing_array.used_entries; i++) {
00843 for (x = 0; x < softmix_samples; x++) {
00844 ast_slinear_saturated_add(buf + x, mixing_array.buffers[i] + x);
00845 }
00846 }
00847
00848
00849 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00850 struct softmix_channel *sc = bridge_channel->bridge_pvt;
00851
00852 if (bridge_channel->suspended) {
00853 continue;
00854 }
00855
00856 ast_mutex_lock(&sc->lock);
00857
00858
00859 if (sc->write_frame.subclass.format.id != cur_slin_id) {
00860 ast_format_set(&sc->write_frame.subclass.format, cur_slin_id, 0);
00861 }
00862 sc->write_frame.datalen = softmix_datalen;
00863 sc->write_frame.samples = softmix_samples;
00864 memcpy(sc->final_buf, buf, softmix_datalen);
00865
00866
00867 softmix_process_write_audio(&trans_helper, ast_channel_rawwriteformat(bridge_channel->chan), sc);
00868
00869
00870 sc->have_frame = 1;
00871
00872 ast_mutex_unlock(&sc->lock);
00873
00874
00875 pthread_kill(bridge_channel->thread, SIGURG);
00876 }
00877
00878 update_all_rates = 0;
00879 if (!stat_iteration_counter) {
00880 update_all_rates = analyse_softmix_stats(&stats, softmix_data);
00881 stat_iteration_counter = SOFTMIX_STAT_INTERVAL;
00882 }
00883 stat_iteration_counter--;
00884
00885 ao2_unlock(bridge);
00886
00887 softmix_translate_helper_cleanup(&trans_helper);
00888
00889 ast_waitfor_n_fd(&timingfd, 1, &timeout, NULL);
00890 if (ast_timer_ack(timer, 1) < 0) {
00891 ast_log(LOG_ERROR, "Failed to acknowledge timer in softmix bridge\n");
00892 ao2_lock(bridge);
00893 goto softmix_cleanup;
00894 }
00895 ao2_lock(bridge);
00896
00897
00898 if (bridge->internal_mixing_interval && (bridge->internal_mixing_interval != softmix_data->internal_mixing_interval)) {
00899 softmix_data->internal_mixing_interval = bridge->internal_mixing_interval;
00900 ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
00901 update_all_rates = 1;
00902 }
00903 }
00904
00905 res = 0;
00906
00907 softmix_cleanup:
00908 softmix_translate_helper_destroy(&trans_helper);
00909 softmix_mixing_array_destroy(&mixing_array);
00910 if (softmix_data) {
00911 ao2_ref(softmix_data, -1);
00912 }
00913 return res;
00914 }
00915
00916 static struct ast_bridge_technology softmix_bridge = {
00917 .name = "softmix",
00918 .capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED | AST_BRIDGE_CAPABILITY_OPTIMIZE | AST_BRIDGE_CAPABILITY_VIDEO,
00919 .preference = AST_BRIDGE_PREFERENCE_LOW,
00920 .create = softmix_bridge_create,
00921 .destroy = softmix_bridge_destroy,
00922 .join = softmix_bridge_join,
00923 .leave = softmix_bridge_leave,
00924 .write = softmix_bridge_write,
00925 .thread = softmix_bridge_thread,
00926 .poke = softmix_bridge_poke,
00927 };
00928
00929 static int unload_module(void)
00930 {
00931 ast_format_cap_destroy(softmix_bridge.format_capabilities);
00932 return ast_bridge_technology_unregister(&softmix_bridge);
00933 }
00934
00935 static int load_module(void)
00936 {
00937 struct ast_format tmp;
00938 if (!(softmix_bridge.format_capabilities = ast_format_cap_alloc())) {
00939 return AST_MODULE_LOAD_DECLINE;
00940 }
00941 ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
00942 return ast_bridge_technology_register(&softmix_bridge);
00943 }
00944
00945 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Multi-party software based channel mixing");