uint32_t score;
uint32_t score_iir;
switch_mutex_t *flag_mutex;
- switch_mutex_t *control_mutex;
+ switch_mutex_t *write_mutex;
switch_mutex_t *audio_in_mutex;
switch_mutex_t *audio_out_mutex;
+ switch_mutex_t *read_mutex;
switch_codec_implementation_t orig_read_impl;
switch_codec_t read_codec;
switch_codec_t write_codec;
static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event);
static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event);
+
+#define lock_member(_member) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex)
+#define unlock_member(_member) switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock(_member->write_mutex)
+
static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (member == NULL || other_member == NULL || member->relationships == NULL)
return NULL;
- switch_mutex_lock(member->control_mutex);
- switch_mutex_lock(other_member->control_mutex);
+ lock_member(member);
+ lock_member(other_member);
for (rel = member->relationships; rel; rel = rel->next) {
if (rel->id == other_member->id) {
}
}
- switch_mutex_unlock(other_member->control_mutex);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(other_member);
+ unlock_member(member);
return rel ? rel : global;
}
rel->id = id;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
rel->next = member->relationships;
member->relationships = rel;
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
return rel;
}
if (member == NULL || id == 0)
return status;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
for (rel = member->relationships; rel; rel = rel->next) {
if (rel->id == id) {
/* we just forget about rel here cos it was allocated by the member's pool
}
last = rel;
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
return status;
}
switch_mutex_lock(conference->mutex);
switch_mutex_lock(member->audio_in_mutex);
switch_mutex_lock(member->audio_out_mutex);
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
switch_mutex_lock(conference->member_mutex);
switch_clear_flag(conference, CFLAG_DESTRUCT);
}
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_mutex_unlock(member->audio_out_mutex);
switch_mutex_unlock(member->audio_in_mutex);
switch_assert(conference != NULL);
switch_assert(member != NULL);
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member_fnode = member->fnode;
member_sh = member->sh;
member->fnode = NULL;
member->sh = NULL;
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_mutex_lock(conference->mutex);
switch_mutex_lock(conference->member_mutex);
switch_mutex_lock(member->audio_in_mutex);
switch_mutex_lock(member->audio_out_mutex);
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
switch_clear_flag(member, MFLAG_INTREE);
for (imember = conference->members; imember; imember = imember->next) {
}
}
switch_mutex_unlock(conference->member_mutex);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_mutex_unlock(member->audio_out_mutex);
switch_mutex_unlock(member->audio_in_mutex);
switch_mutex_unlock(conference->mutex);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->energy_level += 200;
if (member->energy_level > 3000) {
member->energy_level = 3000;
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->energy_level = member->conference->energy_level;
if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL) &&
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->energy_level -= 100;
if (member->energy_level < 0) {
member->energy_level = 0;
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_out_level++;
switch_normalize_volume(member->volume_out_level);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_out_level = 0;
if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL) &&
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_out_level--;
switch_normalize_volume(member->volume_out_level);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_in_level++;
switch_normalize_volume(member->volume_in_level);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_in_level = 0;
if (test_eflag(member->conference, EFLAG_GAIN_LEVEL) &&
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
conference_member_say(member, msg, 0);
if (member == NULL)
return;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_in_level--;
switch_normalize_volume(member->volume_in_level);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
switch_event_fire(&event);
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
conference_member_say(member, msg, 0);
while (switch_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) {
- if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
+ switch_mutex_lock(member->read_mutex);
+
+ if (switch_channel_ready(channel) && switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
switch_yield(100000);
- continue;
+ goto do_continue;
}
/* end the loop, if appropriate */
if (!SWITCH_READ_ACCEPTABLE(status) || !switch_test_flag(member, MFLAG_RUNNING)) {
- break;
+ goto do_break;
}
if (switch_test_flag(read_frame, SFF_CNG)) {
}
}
}
- continue;
+ goto do_continue;
}
energy_level = member->energy_level;
ok = switch_buffer_write(member->audio_buffer, data, datalen);
switch_mutex_unlock(member->audio_in_mutex);
if (!ok) {
- break;
+ goto do_break;
}
}
}
+
+ do_continue:
+
+ switch_mutex_unlock(member->read_mutex);
+
}
+ do_break:
+
+ switch_mutex_unlock(member->read_mutex);
+
switch_resample_destroy(&member->read_resampler);
switch_clear_flag_locked(member, MFLAG_ITHREAD);
switch_size_t file_sample_len = csamples;
switch_size_t file_data_len = file_sample_len * 2;
+
+ switch_mutex_lock(member->write_mutex);
+
if (switch_test_flag(member, MFLAG_RESTART)) {
+ switch_mutex_unlock(member->write_mutex);
goto top;
}
- switch_mutex_lock(member->control_mutex);
-
if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
if (event->event_id == SWITCH_EVENT_MESSAGE) {
char *from = switch_event_get_header(event, "from");
switch_clear_flag_locked(member, MFLAG_FLUSH_BUFFER);
}
- switch_mutex_unlock(member->control_mutex);
+ switch_mutex_unlock(member->write_mutex);
if (switch_core_session_private_event_count(member->session)) {
switch_cond_next();
}
- } /* Rinse ... Repeat */
+ } /* Rinse ... Repeat */
+
if (member->digit_stream != NULL) {
switch_ivr_digit_stream_destroy(&member->digit_stream);
member->mux_frame = switch_core_alloc(member->pool, member->frame_size);
- switch_mutex_init(&member->control_mutex, SWITCH_MUTEX_NESTED, rec->pool);
+ switch_mutex_init(&member->write_mutex, SWITCH_MUTEX_NESTED, rec->pool);
switch_mutex_init(&member->flag_mutex, SWITCH_MUTEX_NESTED, rec->pool);
switch_mutex_init(&member->audio_in_mutex, SWITCH_MUTEX_NESTED, rec->pool);
switch_mutex_init(&member->audio_out_mutex, SWITCH_MUTEX_NESTED, rec->pool);
+ switch_mutex_init(&member->read_mutex, SWITCH_MUTEX_NESTED, rec->pool);
/* Setup an audio buffer for the incoming audio */
if (switch_buffer_create_dynamic(&member->audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, 0) != SWITCH_STATUS_SUCCESS) {
if (member == NULL)
return count;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
if (stop == FILE_STOP_ALL) {
for (nptr = member->fnode; nptr; nptr = nptr->next) {
}
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
return count;
}
const char *p;
for (p = dtmf; p && *p; p++) {
switch_dtmf_t digit = { *p, SWITCH_DEFAULT_DTMF_DURATION};
- switch_mutex_lock(imember->control_mutex);
+ lock_member(imember);
switch_core_session_kill_channel(imember->session, SWITCH_SIG_BREAK);
switch_core_session_send_dtmf(imember->session, &digit);
- switch_mutex_unlock(imember->control_mutex);
+ unlock_member(imember);
}
}
}
fnode->file = switch_core_strdup(fnode->pool, file);
/* Queue the node */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Queueing file '%s' for play\n", file);
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
for (nptr = member->fnode; nptr && nptr->next; nptr = nptr->next);
if (nptr) {
nptr->next = fnode;
} else {
member->fnode = fnode;
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
status = SWITCH_STATUS_SUCCESS;
done:
}
/* Queue the node */
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
for (nptr = member->fnode; nptr && nptr->next; nptr = nptr->next);
if (nptr) {
}
switch_core_speech_feed_tts(fnode->sh, text, &flags);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
status = SWITCH_STATUS_SUCCESS;
if (member == NULL)
return SWITCH_STATUS_GENERR;
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
switch_clear_flag(member, MFLAG_RUNNING);
switch_set_flag_locked(member, MFLAG_KICKED);
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
if (stream != NULL) {
stream->write_function(stream, "OK kicked %u\n", member->id);
}
return SWITCH_STATUS_GENERR;
}
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
switch_core_session_send_dtmf_string(member->session, (char *) data);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
if (stream != NULL) {
stream->write_function(stream, "OK sent %s to %u\n", (char *) data, member->id);
return SWITCH_STATUS_GENERR;
if (data) {
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->energy_level = atoi((char *) data);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
}
if (stream != NULL) {
stream->write_function(stream, "Energy %u = %d\n", member->id, member->energy_level);
return SWITCH_STATUS_GENERR;
if (data) {
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_in_level = atoi((char *) data);
switch_normalize_volume(member->volume_in_level);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
}
if (stream != NULL) {
stream->write_function(stream, "Volume IN %u = %d\n", member->id, member->volume_in_level);
return SWITCH_STATUS_GENERR;
if (data) {
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
member->volume_out_level = atoi((char *) data);
switch_normalize_volume(member->volume_out_level);
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
}
if (stream != NULL) {
stream->write_function(stream, "Volume OUT %u = %d\n", member->id, member->volume_out_level);
}
/* move the member from the old conference to the new one */
- switch_mutex_lock(member->control_mutex);
+ lock_member(member);
+
if (conference != new_conference) {
conference_del_member(conference, member);
conference_add_member(new_conference, member);
}
}
- switch_mutex_unlock(member->control_mutex);
+ unlock_member(member);
stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]);
/* Prepare MUTEXS */
member.id = next_member_id();
switch_mutex_init(&member.flag_mutex, SWITCH_MUTEX_NESTED, member.pool);
- switch_mutex_init(&member.control_mutex, SWITCH_MUTEX_NESTED, member.pool);
+ switch_mutex_init(&member.write_mutex, SWITCH_MUTEX_NESTED, member.pool);
+ switch_mutex_init(&member.read_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool);