mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-15 00:22:35 +00:00
FS-4527 --resolve add resample core support for asr. This code is very isolated and only effects mod_unimrcp at this time.
This commit is contained in:
parent
1aea82488b
commit
9bbee350c2
@ -408,6 +408,14 @@ struct switch_asr_handle {
|
|||||||
char *param;
|
char *param;
|
||||||
/*! the handle's memory pool */
|
/*! the handle's memory pool */
|
||||||
switch_memory_pool_t *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 */
|
/*! private data for the format module to store handle specific info */
|
||||||
void *private_info;
|
void *private_info;
|
||||||
};
|
};
|
||||||
|
@ -339,6 +339,7 @@ struct speech_channel {
|
|||||||
switch_hash_t *params;
|
switch_hash_t *params;
|
||||||
/** app specific data */
|
/** app specific data */
|
||||||
void *data;
|
void *data;
|
||||||
|
void *fsh;
|
||||||
};
|
};
|
||||||
typedef struct speech_channel speech_channel_t;
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
sh->private_info = schannel;
|
sh->private_info = schannel;
|
||||||
|
schannel->fsh = sh;
|
||||||
|
|
||||||
/* Open the channel */
|
/* Open the channel */
|
||||||
if (zstr(profile_name)) {
|
if (zstr(profile_name)) {
|
||||||
@ -1835,7 +1837,16 @@ static apt_bool_t speech_on_channel_add(mrcp_application_t *application, mrcp_se
|
|||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
schannel->rate = descriptor->sampling_rate;
|
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) {
|
if (descriptor->name.length) {
|
||||||
strncpy(codec_name, descriptor->name.buf, sizeof(codec_name));
|
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;
|
status = SWITCH_STATUS_FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
schannel->fsh = ah;
|
||||||
ah->private_info = schannel;
|
ah->private_info = schannel;
|
||||||
r = (recognizer_data_t *) switch_core_alloc(ah->memory_pool, sizeof(recognizer_data_t));
|
r = (recognizer_data_t *) switch_core_alloc(ah->memory_pool, sizeof(recognizer_data_t));
|
||||||
schannel->data = r;
|
schannel->data = r;
|
||||||
|
@ -77,6 +77,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_open(switch_asr_handle_t *ah,
|
|||||||
}
|
}
|
||||||
ah->rate = rate;
|
ah->rate = rate;
|
||||||
ah->name = switch_core_strdup(ah->memory_pool, module_name);
|
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);
|
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);
|
status = ah->asr_interface->asr_close(ah, flags);
|
||||||
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
|
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
|
||||||
|
|
||||||
|
switch_resample_destroy(&ah->resampler);
|
||||||
|
|
||||||
UNPROTECT_INTERFACE(ah->asr_interface);
|
UNPROTECT_INTERFACE(ah->asr_interface);
|
||||||
|
|
||||||
if (switch_test_flag(ah, SWITCH_ASR_FLAG_FREE_POOL)) {
|
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_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);
|
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);
|
return ah->asr_interface->asr_feed(ah, data, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user