int queue_incoming_silent_frame( struct ast_conf_member *member, int count) { struct ast_frame f; int t = 0; memset(member->framedata,0,sizeof(member->framedata)); ast_fr_init_ex(&f, AST_FRAME_VOICE, AST_FORMAT_SLINEAR, "Nconf"); f.data = member->framedata; f.datalen = member->samples * sizeof(short); f.samples = member->samples; f.offset = 0; // Actually queue some frames for (t = 0; t < count; t++ ) queue_incoming_frame(member,&f); return 0; }
static int process_incoming(struct cw_conf_member *member, struct cw_frame *f) { int res; // Play our sound queue, if not empty. if (member->soundq) { // Free the frame. if ( f != NULL ) { cw_fr_free( f ) ; } res = conf_play_soundqueue( member ); if (res != 0) { queue_incoming_silent_frame(member,2); // send the DTMF event to the MGR interface.. manager_event( EVENT_FLAG_CALL, APP_CONFERENCE_MANID"DTMF", "Channel: %s\r\n" "Key: %c\r\n", member->channel_name, res ) ; parse_dtmf_option( member, res); } return res; } // // Moderator forces MOH management // if ( member->force_on_hold == 1 ) { cw_moh_start(member->chan,""); member->force_on_hold = 0 ; } else if ( member->force_on_hold == -1 ) { cw_moh_stop(member->chan); cw_generator_activate(member->chan,&membergen,member); member->force_on_hold = 0 ; } // // MOH When the user is alone in the conference // if ( member->conf->membercount == 1 && member->is_on_hold == 0 && member->skip_moh_when_alone == 0 ) { cw_moh_start(member->chan,""); member->is_on_hold = 1 ; return 0; } if ( member->conf->membercount > 1 && member->is_on_hold == 1 && member->skip_moh_when_alone == 0 ) { cw_moh_stop(member->chan); cw_generator_activate(member->chan,&membergen,member); member->is_on_hold = 0 ; return 0; } if ( member->force_remove_flag == 1 ) { return 0; } // If we don't have any frame to parse, then return if ( f == NULL ) { return 0; } // Actions based on the content of the frame if ( f->frametype == CW_FRAME_DTMF && member->manage_dtmf ) { queue_incoming_silent_frame(member,2); // send the DTMF event to the MGR interface.. manager_event( EVENT_FLAG_CALL, APP_CONFERENCE_MANID"DTMF", "Channel: %s\r\n" "Key: %c\r\n", member->channel_name, f->subclass ) ; parse_dtmf_option( member, f->subclass); cw_fr_free(f); } else if ( (member->type == MEMBERTYPE_LISTENER) || (member->talk_mute) ) { // this is a listen-only user, or it's muted. // Ignore the frame cw_fr_free( f ) ; } else if ( f->frametype == CW_FRAME_VOICE ) { // ********************************************************************************** VOICE int old_speaking_state = member->is_speaking; #if ENABLE_VAD if ( member->talk_mute == 1 ) member->is_speaking = 0; if ( member->enable_vad && f->subclass == CW_FORMAT_SLINEAR && f->samples > 0 ) { // and if it's time to check what the member is doing if ( member->skip_voice_detection <= 0 || member->is_speaking ) { int rees; rees = vad_is_talk( f->data, f->datalen, &member->silence_nr, 20); // send the frame to the preprocessor if ( rees != 0 ) { // voice detected, reset skip count if ( member->framelen != 0 ) member->skip_voice_detection = (CW_CONF_SKIP_MS_AFTER_VOICE_DETECTION / member->framelen); else // Let's suppose that 20ms as a framelen is not too different from the real situation member->skip_voice_detection = 20; member->is_speaking=1; } else { // member is silent member->is_speaking=0; if ( member->framelen != 0 ) member->skip_voice_detection = ( CW_CONF_SKIP_MS_WHEN_SILENT / member->framelen ); else member->skip_voice_detection = 5; } } --member->skip_voice_detection ; } if (old_speaking_state != member ->is_speaking) send_state_change_notifications(member); #endif // volume of the frame is modified after the VAD has been done if (member->talk_volume != 0) set_talk_volume(member, f, 1); if ( member->is_speaking && queue_incoming_frame( member, f ) != 0 ) cw_log( CW_CONF_DEBUG, "dropped incoming frame, channel => %s\n", member->channel_name ) ; // free the original frame cw_fr_free( f ) ; } else if ( f->frametype == CW_FRAME_CONTROL && f->subclass == CW_CONTROL_HANGUP ) { // hangup received, queue silence && free the frame queue_incoming_silent_frame(member,2); cw_fr_free( f ) ; } else { // Unmanaged frame #if ( APP_NCONFERENCE_DEBUG == 1 ) cw_log(LOG_WARNING,"Freeing unknown frame: type %d member %s \n", f->frametype, member->chan->name ); #endif cw_fr_free( f ) ; } return 0; }