提交 756ef77b authored 作者: William King's avatar William King

FS-7845 Refactor of mod_conference to improve compilation speed, and

logical organization.
上级 d569b4ab
...@@ -2,7 +2,8 @@ include $(top_srcdir)/build/modmake.rulesam ...@@ -2,7 +2,8 @@ include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_conference MODNAME=mod_conference
mod_LTLIBRARIES = mod_conference.la mod_LTLIBRARIES = mod_conference.la
mod_conference_la_SOURCES = mod_conference.c mod_conference_la_SOURCES = mod_conference.c mod_conference_api.c mod_conference_loop.c mod_conference_al.c mod_conference_cdr.c mod_conference_video.c
mod_conference_la_SOURCES += mod_conference_event.c mod_conference_member.c mod_conference_utils.c mod_conference_file.c mod_conference_record.c
mod_conference_la_CFLAGS = $(AM_CFLAGS) -I. mod_conference_la_CFLAGS = $(AM_CFLAGS) -I.
mod_conference_la_LIBADD = $(switch_builddir)/libfreeswitch.la mod_conference_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_conference_la_LDFLAGS = -avoid-version -module -no-undefined -shared mod_conference_la_LDFLAGS = -avoid-version -module -no-undefined -shared
......
runtime in one file, header(with all structures), apps, api commands, utilities
Currently mod_conference can compile with 'time make -j' in:
real 0m9.709s
user 0m9.040s
sys 0m0.568s
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
* Dale Thatcher <freeswitch at dalethatcher dot com>
* Chris Danielson <chris at maxpowersoft dot com>
* Rupa Schomaker <rupa@rupa.com>
* David Weekly <david@weekly.org>
* Joao Mesquita <jmesquita@gmail.com>
* Raymond Chandler <intralanman@freeswitch.org>
* Seven Du <dujinfang@gmail.com>
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
* William King <william.king@quentustech.com>
*
* mod_conference.c -- Software Conference Bridge
*
*/
#include <mod_conference.h>
al_handle_t *create_al(switch_memory_pool_t *pool)
{
al_handle_t *al;
al = switch_core_alloc(pool, sizeof(al_handle_t));
switch_mutex_init(&al->mutex, SWITCH_MUTEX_NESTED, pool);
return al;
}
#ifndef OPENAL_POSITIONING
void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream)
{
}
void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate)
{
}
#else
void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream)
{
float offset;
float pos;
float radius;
float x, z;
float div = 3.14159f / 180;
conference_member_t *member;
uint32_t count = 0;
if (!conference->count) {
return;
}
switch_mutex_lock(conference->member_mutex);
for (member = conference->members; member; member = member->next) {
if (member->channel && member_test_flag(member, MFLAG_CAN_SPEAK) && !member_test_flag(member, MFLAG_NO_POSITIONAL)) {
count++;
}
}
if (count < 3) {
for (member = conference->members; member; member = member->next) {
if (member->channel && !member_test_flag(member, MFLAG_NO_POSITIONAL) && member->al) {
member->al->pos_x = 0;
member->al->pos_y = 0;
member->al->pos_z = 0;
member->al->setpos = 1;
if (stream) {
stream->write_function(stream, "Member %d (%s) 0.0:0.0:0.0\n", member->id, switch_channel_get_name(member->channel));
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) 0.0:0.0:0.0\n",
member->id, switch_channel_get_name(member->channel));
}
}
}
goto end;
}
offset = 180 / (count - 1);
radius = 1.0f;
pos = -90.0f;
for (member = conference->members; member; member = member->next) {
if (!member->channel || member_test_flag(member, MFLAG_NO_POSITIONAL) || !member_test_flag(member, MFLAG_CAN_SPEAK)) {
continue;
}
if (!member->al) {
member->al = create_al(member->pool);
}
member_set_flag(member, MFLAG_POSITIONAL);
if (pos == 0) {
x = 0;
z = radius;
} else if (pos == -90) {
z = 0;
x = radius * -1;
} else if (pos == 90) {
z = 0;
x = radius;
} else if (pos < 0) {
z = cos((90+pos) * div) * radius;
x = sin((90+pos) * div) * radius * -1.0f;
} else {
x = cos(pos * div) * radius;
z = sin(pos * div) * radius;
}
member->al->pos_x = x;
member->al->pos_y = 0;
member->al->pos_z = z;
member->al->setpos = 1;
if (stream) {
stream->write_function(stream, "Member %d (%s) %0.2f:0.0:%0.2f\n", member->id, switch_channel_get_name(member->channel), x, z);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) %0.2f:0.0:%0.2f\n",
member->id, switch_channel_get_name(member->channel), x, z);
}
pos += offset;
}
end:
switch_mutex_unlock(conference->member_mutex);
return;
}
void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate)
{
if (rate != 48000) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only 48khz is supported.\n");
return;
}
if (!al->device) {
ALCint contextAttr[] = {
ALC_FORMAT_CHANNELS_SOFT, ALC_STEREO_SOFT,
ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT,
ALC_FREQUENCY, rate,
ALC_HRTF_SOFT, AL_TRUE,
0
};
switch_mutex_lock(mod_conference_globals.setup_mutex);
if ((al->device = alcLoopbackOpenDeviceSOFT(NULL))) {
const ALshort silence[16] = { 0 };
float orient[6] = { /*fwd:*/ 0., 0., -1., /*up:*/ 0., 1., 0. };
al->context = alcCreateContext(al->device, contextAttr);
alcSetThreadContext(al->context);
/* listener at origin, facing down -z (ears at 0.0m height) */
alListener3f( AL_POSITION, 0. ,0, 0. );
alListener3f( AL_VELOCITY, 0., 0., 0. );
alListenerfv( AL_ORIENTATION, orient );
alGenSources(1, &al->source);
alSourcef( al->source, AL_PITCH, 1.);
alSourcef( al->source, AL_GAIN, 1.);
alGenBuffers(2, al->buffer_in);
alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, data, datalen, rate);
//alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, NULL, 0, rate);
alBufferData(al->buffer_in[1], AL_FORMAT_MONO16, silence, sizeof(silence), rate);
alSourceQueueBuffers(al->source, 2, al->buffer_in);
alSourcePlay(al->source);
}
switch_mutex_unlock(mod_conference_globals.setup_mutex);
}
if (al->device) {
ALint processed = 0, state = 0;
//alcSetThreadContext(al->context);
alGetSourcei(al->source, AL_SOURCE_STATE, &state);
alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &processed);
if (al->setpos) {
al->setpos = 0;
alSource3f(al->source, AL_POSITION, al->pos_x, al->pos_y, al->pos_z);
//alSource3f(al->source, AL_VELOCITY, .01, 0., 0.);
}
if (processed > 0) {
ALuint bufid;
alSourceUnqueueBuffers(al->source, 1, &bufid);
alBufferData(bufid, AL_FORMAT_MONO16, data, datalen, rate);
alSourceQueueBuffers(al->source, 1, &bufid);
}
if (state != AL_PLAYING) {
alSourcePlay(al->source);
}
alcRenderSamplesSOFT(al->device, data, datalen / 2);
}
}
#endif
void check_agc_levels(conference_member_t *member)
{
int x = 0;
if (!member->avg_score) return;
if ((int)member->avg_score < member->conference->agc_level - 100) {
member->agc_volume_in_level++;
switch_normalize_volume_granular(member->agc_volume_in_level);
x = 1;
} else if ((int)member->avg_score > member->conference->agc_level + 100) {
member->agc_volume_in_level--;
switch_normalize_volume_granular(member->agc_volume_in_level);
x = -1;
}
if (x) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7,
"AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n",
member->conference->name,
member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level,
member->score, member->avg_score, member->agc_volume_in_level, x > 0 ? "+++" : "---");
clear_avg(member);
}
}
#ifndef OPENAL_POSITIONING
switch_status_t parse_position(al_handle_t *al, const char *data)
{
return SWITCH_STATUS_FALSE;
}
#else
switch_status_t parse_position(al_handle_t *al, const char *data)
{
char *args[3];
int num;
char *dup;
dup = strdup((char *)data);
switch_assert(dup);
if ((num = switch_split(dup, ':', args)) != 3) {
return SWITCH_STATUS_FALSE;
}
al->pos_x = atof(args[0]);
al->pos_y = atof(args[1]);
al->pos_z = atof(args[2]);
al->setpos = 1;
switch_safe_free(dup);
return SWITCH_STATUS_SUCCESS;
}
#endif
#ifndef OPENAL_POSITIONING
switch_status_t member_parse_position(conference_member_t *member, const char *data)
{
return SWITCH_STATUS_FALSE;
}
#else
switch_status_t member_parse_position(conference_member_t *member, const char *data)
{
switch_status_t status = SWITCH_STATUS_FALSE;
if (member->al) {
status = parse_position(member->al, data);
}
return status;
}
#endif
#ifdef OPENAL_POSITIONING
void close_al(al_handle_t *al)
{
if (!al) return;
switch_mutex_lock(mod_conference_globals.setup_mutex);
if (al->source) {
alDeleteSources(1, &al->source);
al->source = 0;
}
if (al->buffer_in[0]) {
alDeleteBuffers(2, al->buffer_in);
al->buffer_in[0] = 0;
al->buffer_in[1] = 0;
}
if (al->context) {
alcDestroyContext(al->context);
al->context = 0;
}
if (al->device) {
alcCloseDevice(al->device);
al->device = NULL;
}
switch_mutex_unlock(mod_conference_globals.setup_mutex);
}
#endif
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论