]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-4527 --resolve add resample core support for asr. This code is very isolated and...
authorJeff Lenk <jeff@jefflenk.com>
Wed, 10 Oct 2012 19:20:07 +0000 (14:20 -0500)
committerJeff Lenk <jeff@jefflenk.com>
Wed, 10 Oct 2012 19:20:07 +0000 (14:20 -0500)
src/include/switch_module_interfaces.h
src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
src/switch_core_asr.c

index b3dddc7171c27db6368bcdf38e0e79414daf43f8..e92e1a136629c5542f502050efb890927b347d3b 100644 (file)
@@ -408,6 +408,14 @@ struct switch_asr_handle {
        char *param;
        /*! the handle's memory pool */
        switch_memory_pool_t *memory_pool;
+       switch_buffer_t *buffer;
+       switch_byte_t *dbuf;
+       switch_size_t dbuflen;
+       switch_audio_resampler_t *resampler;
+       /*! the current samplerate */
+       uint32_t samplerate;
+       /*! the current native samplerate */
+       uint32_t native_rate;
        /*! private data for the format module to store handle specific info */
        void *private_info;
 };
index aaf8f8764afc65b35427c48aab89f1391d8f7442..91b994380520b589acb1bbe02e785a59a7b21879 100644 (file)
@@ -339,6 +339,7 @@ struct speech_channel {
        switch_hash_t *params;
        /** app specific data */
        void *data;
+       void *fsh;
 };
 typedef struct speech_channel speech_channel_t;
 
@@ -1591,6 +1592,7 @@ static switch_status_t synth_speech_open(switch_speech_handle_t *sh, const char
                goto done;
        }
        sh->private_info = schannel;
+       schannel->fsh = sh;
 
        /* Open the channel */
        if (zstr(profile_name)) {
@@ -1835,7 +1837,16 @@ static apt_bool_t speech_on_channel_add(mrcp_application_t *application, mrcp_se
        if (!descriptor) {
                goto error;
        }
+
        schannel->rate = descriptor->sampling_rate;
+
+       /* report negotiated sample rate back to FreeSWITCH */
+       if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER) {
+               ((switch_speech_handle_t*)schannel->fsh)->native_rate = schannel->rate;
+       } else {
+               ((switch_asr_handle_t*)schannel->fsh)->native_rate = schannel->rate;
+       }
+
        if (descriptor->name.length) {
                strncpy(codec_name, descriptor->name.buf, sizeof(codec_name));
        }
@@ -2914,6 +2925,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec
                status = SWITCH_STATUS_FALSE;
                goto done;
        }
+       schannel->fsh = ah;
        ah->private_info = schannel;
        r = (recognizer_data_t *) switch_core_alloc(ah->memory_pool, sizeof(recognizer_data_t));
        schannel->data = r;
index e10928f29d911d3fc11f71674c25afe85eabe692..a8a9521b8767d1f1203e02539a6d1620b6fd67d0 100644 (file)
@@ -77,6 +77,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_open(switch_asr_handle_t *ah,
        }
        ah->rate = rate;
        ah->name = switch_core_strdup(ah->memory_pool, module_name);
+       ah->samplerate = rate;
+       ah->native_rate = rate;
 
        status = ah->asr_interface->asr_open(ah, codec, rate, dest, flags);
 
@@ -223,6 +225,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s
        status = ah->asr_interface->asr_close(ah, flags);
        switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
 
+       switch_resample_destroy(&ah->resampler);
+
        UNPROTECT_INTERFACE(ah->asr_interface);
 
        if (switch_test_flag(ah, SWITCH_ASR_FLAG_FREE_POOL)) {
@@ -234,8 +238,37 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s
 
 SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
 {
+       switch_size_t orig_len = len;
        switch_assert(ah != NULL);
 
+       if (ah->native_rate && ah->samplerate && ah->native_rate != ah->samplerate) {
+               if (!ah->resampler) {
+                       if (switch_resample_create(&ah->resampler,
+                                                                          ah->samplerate, ah->native_rate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY, 1) != SWITCH_STATUS_SUCCESS) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
+                               return SWITCH_STATUS_GENERR;
+                       }
+               }
+
+               switch_resample_process(ah->resampler, data, len / 2);
+               if (ah->resampler->to_len > orig_len) {
+                       if (!ah->dbuf) {
+                               void *mem;
+                               ah->dbuflen = ah->resampler->to_len * 2;
+                               mem = realloc(ah->dbuf, ah->dbuflen);
+                               switch_assert(mem);
+                               ah->dbuf = mem;
+                       }
+                       switch_assert(ah->resampler->to_len * 2 <= ah->dbuflen);
+                       memcpy(ah->dbuf, ah->resampler->to, ah->resampler->to_len * 2);
+                       data = ah->dbuf;
+               } else {
+                       memcpy(data, ah->resampler->to, ah->resampler->to_len * 2);
+               }
+
+               len = ah->resampler->to_len;
+       }
+
        return ah->asr_interface->asr_feed(ah, data, len, flags);
 }