diff -u a/member.c b/member.c --- a/member.c 2010-10-06 14:06:30.000000000 +0200 +++ b/member.c 2010-11-17 14:38:14.306186436 +0100 @@ -775,8 +775,23 @@ // tell conference_exec we're ready for frames member->ready_for_outgoing = 1 ; + int my_membercount = conf->membercount; while ( 42 == 42 ) { + if ( my_membercount != conf->membercount ) + { + // number of members has changed + if (my_membercount < conf->membercount && member->join_sound) + { + member_play_sound( member, member->join_sound ); + } + else if (my_membercount > conf->membercount && member->leave_sound) + { + member_play_sound( member, member->leave_sound ); + } + my_membercount = conf->membercount; + } + // make sure we have a channel to process if ( chan == NULL ) { @@ -1072,6 +1087,18 @@ // keep pointer to member's channel member->chan = chan ; + + // check for enter/leave sounds + { + const char *tmp; + ast_channel_lock(chan); + member->join_sound = (tmp = pbx_builtin_getvar_helper(chan, "CONFERENCE_JOIN_SOUND")) ? + ast_strdup(tmp) : NULL; + member->leave_sound = (tmp = pbx_builtin_getvar_helper(chan, "CONFERENCE_LEAVE_SOUND")) ? + ast_strdup(tmp) : NULL; + ast_channel_unlock(chan); + } + DEBUG("conference sounds: join '%s' leave '%s'\n", member->join_sound, member->leave_sound); // set default if no type parameter if (!member->type) { @@ -1550,6 +1577,10 @@ // free the member's copy of the spyee channel name free(member->spyee_channel_name); + // free join/leave sound file names (NULL if not set) + free(member->join_sound); + free(member->leave_sound); + // clear all sounds struct ast_conf_soundq *sound = member->soundq; struct ast_conf_soundq *next; @@ -3403,3 +3434,37 @@ } #endif + + +// Add sound file to a member's sound queue +void member_play_sound ( struct ast_conf_member *member, const char *filename ) +{ + struct ast_conf_soundq *newsound; + struct ast_conf_soundq **q; + + newsound = calloc(1,sizeof(struct ast_conf_soundq)); + if (newsound == NULL) { + perror("calloc for struct ast_conf_soundq failed"); + } + else + { + newsound->stream = ast_openstream(member->chan, filename, member->chan->language); + if (newsound->stream) + { + member->chan->stream = NULL; + ast_copy_string(newsound->name, filename, sizeof(newsound->name)); + // append sound to the end of the list. + for(q=&member->soundq; *q; q = &((*q)->next)) ;; + *q = newsound; + ast_log( LOG_VERBOSE, "Playing conference message %s to channel %s\n", filename, member->chan->name ) ; + } + else + { + char fmt[256]; + ast_log(LOG_ERROR, "Unable to open %s (format %s): %s\n", + filename, ast_getformatname_multiple(fmt, sizeof(fmt), member->chan->nativeformats), strerror(errno)); + free(newsound); + } + } + ast_mutex_unlock(&member->lock); +} diff -u a/member.h b/member.h --- a/member.h 2010-10-06 14:06:30.000000000 +0200 +++ b/member.h 2010-11-17 14:18:03.998186412 +0100 @@ -67,6 +67,11 @@ char *type ; // conference type char *spyee_channel_name ; // spyee channel name int max_users ; // zero or max users for this conference + + // sounds to play to the member when somebody joins/leaves the conference + char * join_sound; + char * leave_sound; + #if ( SILDET == 2 ) // voice flags int vad_flag; @@ -319,6 +324,7 @@ // int member_exec( struct ast_channel* chan, void* data ) ; +void member_play_sound( struct ast_conf_member *, const char *) ; struct ast_conf_member* check_active_video( int id, struct ast_conference *conf );