spandsp_start_dtmf的bug及修复

news/2025/1/23 17:57:48/文章来源:https://www.cnblogs.com/qiuzhendezhen/p/18688286

概述

freeswitch是一款简单好用的VOIP开源软交换平台。

之前的文章中介绍过DTMF从2833到inband的转换,其中inband到2833的转换使用了“spandsp_start_dtmf”,这个函数在转换的过程中有缺陷。

环境

CentOS 7.9

freeswitch 1.10.7

问题描述

在fs桥接的呼叫,经过“spandsp_start_dtmf”处理inband中的dtmf按键,转换到otherleg的时候,2833的dtmf可以正常产生,但是inband中的波形删除的不够干净,如果后续的语音节点会检测inband的话,就会产生重码的问题。

 

解决方案

修改思路,在spandsp对dtmf波形的处理过程中,缓存2个媒体包,当检测到DTMF时,将缓存的媒体包清空。

修改mod_dtptools.c

case SWITCH_DTMF_RTP:switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_rtp", "true");/* change state to only allow RTP events */filter->only_rtp = 1;//modify by zr, 20241021, for DTMF inband to 2833/* stop inband detector */// switch_ivr_broadcast(switch_core_session_get_uuid(session), "spandsp_stop_dtmf::", SMF_ECHO_ALEG);break;

修改mod_spandsp_dsp.c

//modify by zr, 20241021, for DTMF inband to 2833
#define INBAND_DTMF_BUF_SIZE (2)
#define INBAND_DTMF_BUF_LEN (512)typedef struct {switch_core_session_t *session;dtmf_rx_state_t *dtmf_detect;int verbose;char last_digit;uint32_t samples;uint32_t last_digit_end;uint32_t digit_begin;uint32_t min_dup_digit_spacing;int twist;int reverse_twist;int filter_dialtone;int threshold;switch_audio_resampler_t *resampler;
//modify by zr, 20241021, for DTMF inband to 2833char data_buf[INBAND_DTMF_BUF_SIZE][INBAND_DTMF_BUF_LEN];int buf_index;
} switch_inband_dtmf_t;...dtmf_rx(pvt->dtmf_detect, dp, samples);//modify by zr, 20241021, for DTMF inband to 2833// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "dtmf_rx return, last_hit=%d, in_digit=%d, current_sample=%d,"// 														"duration=%d, lost_digits=%d, current_digits=%d\n", // 														pvt->dtmf_detect->last_hit, pvt->dtmf_detect->in_digit, pvt->dtmf_detect->current_sample, // 														pvt->dtmf_detect->duration, pvt->dtmf_detect->lost_digits, pvt->dtmf_detect->current_digits);if(pvt->dtmf_detect->filter_dialtone){	// double buffer modeif(pvt->dtmf_detect->last_hit > 0 || pvt->dtmf_detect->in_digit > 0) {switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "inband_dtmf_callback, memset frame to 0x00, pvt->dtmf_detect->last_hit=%d, pvt->dtmf_detect->in_digit=%d\n", pvt->dtmf_detect->last_hit, pvt->dtmf_detect->in_digit);memset(pvt->data_buf, 0x00, INBAND_DTMF_BUF_LEN*INBAND_DTMF_BUF_SIZE);memset(frame->data, 0x00, frame->datalen);}else{char data_tmp[INBAND_DTMF_BUF_LEN] = {0};memcpy(data_tmp, frame->data, INBAND_DTMF_BUF_LEN);memcpy(frame->data, pvt->data_buf[pvt->buf_index], frame->datalen);memcpy(pvt->data_buf[pvt->buf_index], data_tmp, datalen);}pvt->buf_index = (1 - pvt->buf_index);}switch_core_media_bug_set_read_replace_frame(bug, frame);...pvt->session = session;//modify by zr, 20241021, for DTMF inband to 2833pvt->buf_index = 0;

修改switch_core_media.c

				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send payload to %u recv payload to %u\n",switch_channel_get_name(session->channel), smh->mparams->te, smh->mparams->recv_te);//add by zr 20241018, for 2833 to inband, update method//如果在183的协商中已经设置了inband模式,后续的update协商中需要取消inband模式的函数设置if (switch_true(switch_channel_get_variable(session->channel, "inband_flag"))) {switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "reset inband_flag and channel variables.\n");//B路switch_channel_set_variable(session->channel, "inband_flag", NULL);switch_channel_set_variable(session->channel, "spandsp_dtmf_rx_filter_dialtone", NULL);switch_channel_set_variable(session->channel, "execute_on_answer_101", NULL);switch_channel_set_variable(session->channel, "execute_on_answer_102", NULL);//A路,2833 to inbandif( switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS ){switch_channel_set_variable(other_session->channel, "execute_on_answer_101", NULL);switch_core_session_rwunlock(other_session);}}} else {/* by default, use SIP INFO if 2833 is not in the SDP */if (!switch_false(switch_channel_get_variable(channel, "rtp_info_when_no_2833"))) {switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP.  Disable 2833 dtmf and switch to INFO\n");switch_channel_set_variable(session->channel, "dtmf_type", "info");smh->mparams->dtmf_type = DTMF_INFO;smh->mparams->recv_te = smh->mparams->te = 0;} else {// switch_channel_set_variable(session->channel, "dtmf_type", "none");// smh->mparams->dtmf_type = DTMF_NONE;// smh->mparams->recv_te = smh->mparams->te = 0;//add by zr 20241018, for 2833 to inband, update methodswitch_channel_set_variable(session->channel, "dtmf_type", "inband");smh->mparams->dtmf_type = DTMF_AUTO;smh->mparams->recv_te = smh->mparams->te = 0;switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "set inband_flag, No 2833 in SDP. Disable 2833 dtmf and switch to INBAND.\n");//TODO: add inband dtmf//A路,2833 to inbandif( switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS ){switch_channel_set_variable(other_session->channel, "execute_on_answer_101", "start_dtmf_generate");switch_core_session_rwunlock(other_session);}//B路,inband to 2833switch_channel_set_variable(session->channel, "inband_flag", "true");switch_channel_set_variable(session->channel, "spandsp_dtmf_rx_filter_dialtone", "true");switch_channel_set_variable(session->channel, "execute_on_answer_101", "deduplicate_dtmf");switch_channel_set_variable(session->channel, "execute_on_answer_102", "spandsp_start_dtmf");}}

测试

新的fs桥接的呼叫,经过“spandsp_start_dtmf”处理inband中的dtmf按键,在A路的波形中没有遗留。

 

总结

因为需要对inband的媒体流做缓存,所以该处理会产生40ms左右的语音时延。

 

空空如常

求真得真

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873783.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何打造一个高并发系统?

今天和大家聊聊作为一个后端开发,在实际工作中,我们如何打造一个高并发的系统? 如下图所示,大概有六个层面,我们结合具体的场景直播间签到去一一细说。一、前端 1、打散请求:即把用户的接口分散一点去请求后端,尽量不要集中在某一时刻。 场景:比如直播间讲师发起了一个…

批量登录灯塔扫描的信息收集GUI工具-TDGO更新(v1.0.1)发布

GitHub: https://github.com/lxflxfcl/DTGO作者语:嘘,我正在狠狠鞭打你的灯塔 前言 上一篇文章发布的DTGO的初始版本 TDGO(灯塔狩猎者)—一款分布式灯塔信息收集工具 现在更新了一版,更新内容如下: 功能更新:主界面UI美化【由Super师傅完成】删除任务记录【删除记录时会同…

「SPOJ2666」QTREE4 - Query on a tree IV

题目概述 对一棵树维护两种操作:翻转某个点的颜色,求 \(max\{ dist_{u, v} \}\) 且满足 \(u\) 的颜色和 \(v\) 的颜色都是白色( \(u,v\) 可以相同)。 思路 首先考虑若没有修改,给定带颜色的 \(N\) 个点怎么查询。 经典办法是树形 \(\text{dp}\) ,定义\(mx_u\) 表示在 \(u…

K8S静态PVPVC配置

持久卷与动态存储 NFS-PVC-PV实战案例1、创建后端存储NFS节点 [root@web04 ~]# mkdir -pv /kubelet/pv/pv00{1..3} mkdir: created directory ‘/kubelet/pv’ mkdir: created directory ‘/kubelet/pv/pv001’ mkdir: created directory ‘/kubelet/pv/pv002’ mkdir: created…

『Python底层原理』--CPython 虚拟机

在 Python 编程的世界里,我们每天都在使用 python 命令运行程序,但你是否曾好奇这背后究竟发生了什么? 本文将初步探究 CPython(Python 中最流行的实现)的一些内部机制,为了更好的来理解 Python 语言的底层运作。 1. CPython 简介 CPython 是用** C 语言**编写的 Python …

销售转化关键:掌握真诚沟通技巧

在日常沟通中,我特别不喜欢别人一上来就问“在吗”,或者只是单纯地发一个“微笑”表情。这种开场方式,总觉得少了点诚意和温度。 如果真的有事需要找人帮忙,与其冷冰冰地问“在吗”,不如先亲切地喊出对方的名字或昵称,然后再直截了当地说明来意。这样不仅能让对方感受到你…

万不得已,千万不要去外包

之前的失业日志系列里有讲,现在的就业环境不太好,有面试机会的基本都是外包岗位。刚好之前公司和外包有几次合作,主要是把一部分或者整个项目外包的外包公司,我们技术人员负责一部分的技术支持,通过几次的合作,对外包的工作也有可一个大概的了解,想谈一下自己对外包的了…

杂项-在vscdoe上使用jupyter notebook写javascript

目录准备安装notebook对javascript的支持进一步优化支持es6安装npm包将notebook集成到vsc中去 准备python / Anaconda :推荐专业的Python开发人员使用Anaconda进行包管理和版本控制安装jupyter notebook。pip3 install jupyter notebook 正常下载之后选择一个工作目录执行jupyt…

字节 GUI 代理模型 UI-TARS:具备像人一样的感知、推理、行动能力;SLAM-Omni:支持可控音色的语音对话模型

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

htb Pandora walkthrough snmp + ssh 隧道 + 环境变量劫持

80端口web界面划到最下面发现两个邮箱 记录一下尝试加上域名dirsearch 扫描只扫到一个assets目录但是值得注意的是这个目录里面有个blog目录 也就意味着他的网站是有博客网站的 只是我们没扫描出来扫扫udp端口发现161 的 snmp是开着的用nmap 枚举进程 nmap -sU -p161 --script …

IT-Tools-开源好用的IT工具集

访问地址: 线上访问:https://it-tools.tech/ 开源社区:https://github.com/CorentinTh/it-tools 支持私有化部署: docker run -d --name it-tools --restart unless-stopped -p 8080:80 ghcr.io/corentinth/it-tools:latest简要介绍: IT-Tools 是为开发人员提供的在线工具…

4.4.2 版本更新来了!全新内容抢鲜看

产品更新概览 功能新增: 新版API支持在进行数据解析选择JSON节点时,全选下一层节点。 功能修复: 修复新版API认证功能; 修复报表后台系统用户权限问题。 功能优化: 支持在Linux X64版本上连接神通数据库; 支持连接2.x版本的TDengine数据库。 功能新增 在山海鲸可视化4.4.…