]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-6042 FS-6044 --resolve
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 17 Dec 2013 19:55:29 +0000 (00:55 +0500)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 17 Dec 2013 19:55:34 +0000 (00:55 +0500)
src/include/switch_resample.h
src/mod/applications/mod_conference/mod_conference.c
src/switch_resample.c

index ee1de4e2c7f1a5541bf4f2a5f8a1afdd99cbe873..59fc0c68ec57170d95d2414308292fb1127a2bb6 100644 (file)
@@ -39,7 +39,7 @@
        
 */
 #define switch_normalize_volume(x) if (x > 4) x = 4; if (x < -4) x = -4;
-#define switch_normalize_volume_granular(x) if (x > 12) x = 12; if (x < -12) x = -12;
+#define switch_normalize_volume_granular(x) if (x > 13) x = 13; if (x < -13) x = -13;
 
 #ifndef SWITCH_RESAMPLE_H
 #define SWITCH_RESAMPLE_H
index cc3003b0cc47e68a355d876326dd36386c03b0b6..da2f6762ad4131911b04d9595bd496e8be0dfe68 100644 (file)
@@ -274,6 +274,7 @@ typedef struct conference_file_node {
        struct conference_file_node *next;
        char *file;
        switch_bool_t mux;
+       uint32_t member_id;
 } conference_file_node_t;
 
 typedef enum {
@@ -2108,6 +2109,48 @@ static void conference_set_floor_holder(conference_obj_t *conference, conference
 
 }
 
+static switch_status_t conference_file_close(conference_obj_t *conference, conference_file_node_t *node)
+{
+       switch_event_t *event;
+       conference_member_t *member = NULL;
+
+       if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) &&
+               switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+               
+               conference_add_event_data(conference, event);
+
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "seconds", "%ld", (long) node->fh.samples_in / node->fh.native_rate);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "milliseconds", "%ld", (long) node->fh.samples_in / (node->fh.native_rate / 1000));
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "samples", "%ld", (long) node->fh.samples_in);
+
+               if (node->fh.params) {
+                       switch_event_merge(event, node->fh.params);
+               }
+
+               if (node->member_id) {
+                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done");
+               
+                       if ((member = conference_member_get(conference, node->member_id))) {
+                               conference_add_event_member_data(member, event);
+                               switch_thread_rwlock_unlock(member->rwlock);
+                       }
+
+               } else {
+                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done");
+               }
+
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", node->file);
+
+               if (node->async) {
+                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true");
+               }
+
+               switch_event_fire(&event);
+       }
+       
+       return switch_core_file_close(&node->fh);
+}
+
 /* Gain exclusive access and remove the member from the list */
 static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member)
 {
@@ -2177,7 +2220,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
                        fnode = fnode->next;
 
                        if (cur->type != NODE_TYPE_SPEECH) {
-                               switch_core_file_close(&cur->fh);
+                               conference_file_close(conference, cur);
                        }
 
                        pool = cur->pool;
@@ -2662,18 +2705,12 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
                                        }
                                } else if (conference->fnode->type == NODE_TYPE_FILE) {
                                        switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len);
+                                       if (conference->fnode->fh.vol) {
+                                               switch_change_sln_volume_granular((void *)file_frame, file_sample_len, conference->fnode->fh.vol);
+                                       }
                                }
 
                                if (file_sample_len <= 0) {
-                                       if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) &&
-                                               switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
-                                               conference_add_event_data(conference, event);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done");
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", conference->fnode->file);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true");
-                                               switch_event_fire(&event);
-                                       }
-
                                        conference->fnode->done++;
                                } else {
                                        has_file_data = 1;
@@ -2690,14 +2727,6 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
                                switch_core_file_read(&conference->async_fnode->fh, async_file_frame, &file_sample_len);
 
                                if (file_sample_len <= 0) {
-                                       if (test_eflag(conference, EFLAG_PLAY_FILE) &&
-                                               switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
-                                               conference_add_event_data(conference, event);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done");
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", conference->async_fnode->file);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true");
-                                               switch_event_fire(&event);
-                                       }
                                        conference->async_fnode->done++;
                                } else {
                                        if (has_file_data) {
@@ -2852,7 +2881,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
 
                if (conference->async_fnode && conference->async_fnode->done) {
                        switch_memory_pool_t *pool;
-                       switch_core_file_close(&conference->async_fnode->fh);
+                       conference_file_close(conference, conference->async_fnode);
                        pool = conference->async_fnode->pool;
                        conference->async_fnode = NULL;
                        switch_core_destroy_memory_pool(&pool);
@@ -2863,7 +2892,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
                        switch_memory_pool_t *pool;
 
                        if (conference->fnode->type != NODE_TYPE_SPEECH) {
-                               switch_core_file_close(&conference->fnode->fh);
+                               conference_file_close(conference, conference->fnode);
                        }
 
                        fnode = conference->fnode;
@@ -2918,7 +2947,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
                        fnode = fnode->next;
 
                        if (cur->type != NODE_TYPE_SPEECH) {
-                               switch_core_file_close(&cur->fh);
+                               conference_file_close(conference, cur);
                        }
 
                        pool = cur->pool;
@@ -2929,7 +2958,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
 
        if (conference->async_fnode) {
                switch_memory_pool_t *pool;
-               switch_core_file_close(&conference->async_fnode->fh);
+               conference_file_close(conference, conference->async_fnode);
                pool = conference->async_fnode->pool;
                conference->async_fnode = NULL;
                switch_core_destroy_memory_pool(&pool);
@@ -3953,7 +3982,7 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi
                switch_memory_pool_t *pool;
 
                if (member->fnode->type != NODE_TYPE_SPEECH) {
-                       switch_core_file_close(&member->fnode->fh);
+                       conference_file_close(member->conference, member->fnode);
                }
 
                fnode = member->fnode;
@@ -3981,17 +4010,7 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi
                        }
 
                        if (file_sample_len <= 0) {
-                               switch_event_t *event;
                                member->fnode->done++;
-
-                               if (test_eflag(member->conference, EFLAG_PLAY_FILE) &&
-                                       switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
-                                       conference_add_event_data(member->conference, event);
-                                       conference_add_event_member_data(member, event);
-                                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done");
-                                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", member->fnode->file);
-                                       switch_event_fire(&event);
-                               }
                        } else {                        /* there is file node data to mix into the frame */
                                int32_t i, sample;
 
@@ -4814,6 +4833,14 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char *
                goto done;
        }
 
+       if (fnode->fh.params) {
+               const char *vol = switch_event_get_header(fnode->fh.params, "vol");
+
+               if (!zstr(vol)) {
+                       fnode->fh.vol = atoi(vol);
+               }
+       }
+
        fnode->pool = pool;
        fnode->async = async;
        fnode->file = switch_core_strdup(fnode->pool, file);
@@ -4829,7 +4856,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char *
 
                if (nptr) {
                        switch_memory_pool_t *tmppool;
-                       switch_core_file_close(&nptr->fh);
+                       conference_file_close(conference, nptr);
                        tmppool = nptr->pool;
                        switch_core_destroy_memory_pool(&tmppool);
                }
@@ -4903,6 +4930,7 @@ static switch_status_t conference_member_play_file(conference_member_t *member,
        fnode->type = NODE_TYPE_FILE;
        fnode->leadin = leadin;
        fnode->mux = mux;
+       fnode->member_id = member->id;
 
        /* Open the file */
        fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
@@ -6232,6 +6260,11 @@ static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_st
                        if (test_eflag(conference, EFLAG_PLAY_FILE) &&
                                switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
                                conference_add_event_data(conference, event);
+
+                               if (conference->fnode->fh.params) {
+                                       switch_event_merge(event, conference->fnode->fh.params);
+                               }
+                               
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file");
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]);
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false");
@@ -6256,6 +6289,11 @@ static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_st
                                if (test_eflag(conference, EFLAG_PLAY_FILE_MEMBER) &&
                                        switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
                                        conference_add_event_member_data(member, event);
+
+                                       if (member->fnode->fh.params) {
+                                               switch_event_merge(event, member->fnode->fh.params);
+                                       }
+
                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member");
                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]);
                                        switch_event_fire(&event);
@@ -6897,6 +6935,54 @@ static switch_status_t conf_api_sub_recording(conference_obj_t *conference, swit
        }
 }
 
+static switch_status_t conf_api_sub_file_vol(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
+{
+       if (argc >= 1) {
+               conference_file_node_t *fnode;
+               int vol = 0;
+               int ok = 0;
+
+               if (argc < 2) {
+                       stream->write_function(stream, "missing args\n");
+                       return SWITCH_STATUS_GENERR;
+               }
+
+               switch_mutex_lock(conference->mutex);
+
+               fnode = conference->fnode;
+
+               vol = atoi(argv[2]);
+
+               if (argc > 3) {
+                       if (strcasecmp(argv[3], "async")) {
+                               fnode = conference->async_fnode;
+                       }
+               }
+
+               printf("WTF %p %p\n", (void *) conference, (void *) fnode);
+
+               if (fnode && fnode->type == NODE_TYPE_FILE) {
+                       fnode->fh.vol = vol;
+                       ok = 1;
+               }
+               switch_mutex_unlock(conference->mutex);
+               
+
+               if (ok) {
+                       stream->write_function(stream, "volume changed\n");
+                       return SWITCH_STATUS_SUCCESS;
+               } else {
+                       stream->write_function(stream, "File not playing\n");
+                       return SWITCH_STATUS_GENERR;
+               }
+
+
+       } else {
+               stream->write_function(stream, "Invalid parameters:\n");
+               return SWITCH_STATUS_GENERR;
+       }
+}
+
 static switch_status_t conf_api_sub_pin(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
 {
        switch_assert(conference != NULL);
@@ -7085,6 +7171,7 @@ static api_command_t conf_api_sub_commands[] = {
        {"nopin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "nopin", ""},
        {"get", (void_fn_t) & conf_api_sub_get, CONF_API_SUB_ARGS_SPLIT, "get", "<parameter-name>"},
        {"set", (void_fn_t) & conf_api_sub_set, CONF_API_SUB_ARGS_SPLIT, "set", "<max_members|sound_prefix|caller_id_name|caller_id_number|endconf_grace_time> <value>"},
+       {"file-vol", (void_fn_t) & conf_api_sub_file_vol, CONF_API_SUB_ARGS_SPLIT, "file-vol", "<vol#>"},
        {"floor", (void_fn_t) & conf_api_sub_floor, CONF_API_SUB_MEMBER_TARGET, "floor", "<member_id|last>"},
        {"vid-floor", (void_fn_t) & conf_api_sub_vid_floor, CONF_API_SUB_MEMBER_TARGET, "vid-floor", "<member_id|last> [force]"},
        {"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""}
@@ -9772,7 +9859,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)
                nl = strlen(conf_api_sub_commands[i].pcommand) + strlen(conf_api_sub_commands[i].psyntax) + 5;
 
                switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::list_conferences %s", conf_api_sub_commands[i].pcommand);
-
                switch_console_set_complete(cmd_str);
 
                if (p != NULL) {
index 807d8fb18f229b736b978a20ba42d4510ad92f54..e245ad188ed05ca5ba8fc225ee3bbe9ad718f9cb 100644 (file)
@@ -289,8 +289,8 @@ SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, u
 SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol)
 {
        double newrate = 0;
-       double pos[12] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0};
-       double neg[12] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .017, .087, .004};
+       double pos[13] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0, 4.5};
+       double neg[13] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .087, .017, .004, 0.0};
        double *chart;
        uint32_t i;
 
@@ -306,7 +306,7 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s
        
        i = abs(vol) - 1;
        
-       switch_assert(i < 12);
+       switch_assert(i < 13);
 
        newrate = chart[i];
 
@@ -320,6 +320,8 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s
                        switch_normalize_to_16bit(tmp);
                        fp[x] = (int16_t) tmp;
                }
+       } else {
+               memset(data, 0, samples * 2);
        }
 }