Mediastreamer2 VoIP เดŽเดžเตเดšเดฟเตป เดชเดฐเตเดฏเดตเต‡เด•เตเดทเดฃเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต. เดญเดพเด—เด‚ 10

เดฒเต‡เด–เดจเดคเตเดคเดฟเดจเตเดฑเต† เดฎเต†เดฑเตเดฑเต€เดฐเดฟเดฏเตฝ เดŽเดจเตเดฑเต†เดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดŽเดŸเตเดคเตเดคเดคเดพเดฃเต เดธเต†เตป เดšเดพเดจเตฝ.

เด…เดตเดธเดพเดจเดคเตเดคเดฟเตฝ เดฒเต‡เด–เดจเด‚ เดžเด™เตเด™เตพ เด’เดฐเต เดกเตเดฏเตเดชเตเดฒเต†เด•เตเดธเต RTP เดธเต†เดทเดจเดฟเดฒเต‚เดŸเต† เด“เดกเดฟเดฏเต‹ เดธเดฟเด—เตเดจเดฒเตเด•เตพ เด•เตˆเดฎเดพเดฑเตเดจเตเดจ เด’เดฐเต เดกเตเดฏเตเดชเตเดฒเต†เด•เตเดธเต เด‡เดจเตเดฑเตผเด•เต‹เด‚ เด‰เดฃเตเดŸเดพเด•เตเด•เดฟ. เดˆ เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ, เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เตพ เดŽเด™เตเด™เดจเต† เดŽเดดเตเดคเดพเดฎเต†เดจเตเดจเตเด‚ เด’เดฐเต DIY เด‡เดจเตเดฑเตผเด•เต‹เดฎเดฟเดฒเต‡เด•เตเด•เต เด’เดฐเต DIY เดซเดฟเตฝเดŸเตเดŸเตผ เดšเต‡เตผเด•เตเด•เดพเดฎเต†เดจเตเดจเตเด‚ เดจเดฎเตเดฎเตพ เดชเด เดฟเด•เตเด•เตเด‚.

เดžเด™เตเด™เตพ เด’เดฐเต เดชเตเดฒเด—เดฟเตป เดตเดฟเด•เดธเดฟเดชเตเดชเดฟเด•เตเด•เตเด•เดฏเดพเดฃเต

Mediastreamer2 VoIP เดŽเดžเตเดšเดฟเตป เดชเดฐเตเดฏเดตเต‡เด•เตเดทเดฃเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต. เดญเดพเด—เด‚ 10

เดฎเต€เดกเดฟเดฏ เดธเตเดŸเตเดฐเต€เดฎเดฑเดฟเดฒเต† เดชเตเดฒเด—เดฟเดจเตเด•เตพ, เดฎเดฑเตเดฑเต เดชเดฒ เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเตเด•เดณเดฟเดฒเต†เดฏเตเด‚ เดชเต‹เดฒเต†, เดฎเต€เดกเดฟเดฏ เดธเตเดŸเตเดฐเต€เดฎเตผ เดคเดจเตเดจเต† เดตเต€เดฃเตเดŸเตเด‚ เด•เด‚เดชเตˆเตฝ เดšเต†เดฏเตเดฏเดพเดคเต† เดคเดจเตเดจเต† เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚ เดตเดฟเดชเตเดฒเต€เด•เดฐเดฟเด•เตเด•เดพเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต.

เดจเดฟเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเดฟเตฝ เดชเตเดฒเด—เดฟเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต, เดจเดฟเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด• เด‰เตพเดชเตเดชเต†เดŸเตเดจเตเดจเต เดชเตเดฒเด—เดฟเตป เดนเต†เดกเตผ เดซเดฏเตฝ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฃเด‚. เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเดฟเดจเตเดฑเต† เดฌเต‹เดกเดฟเดฏเดฟเตฝ, y เดŽเดจเตเดจ เดซเด‚เด—เตเดทเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต ms_filter_register() เด’เดฐเต เดชเตเดคเดฟเดฏ เดซเดฟเตฝเดŸเตเดŸเตผ เดฐเดœเดฟเดธเตเดฑเตเดฑเตผ เดšเต†เดฏเตเดฏเตเด•. เดธเตเดตเดพเดญเดพเดตเดฟเด•เดฎเดพเดฏเตเด‚, เดจเดฟเด™เตเด™เดณเตเดŸเต† เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเตเด‚ เดชเตเดฒเด—เดฟเตป เด‰เดฑเดตเดฟเดŸเดตเตเด‚ เด•เด‚เดชเตˆเตฝ เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เด’เดฐเต เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเดจเดฟเตฝ เด•เต‚เดŸเตเดŸเดฟเดšเตเดšเต‡เตผเด•เตเด•เตเด•เดฏเตเด‚ เดตเต‡เดฃเด‚.

เด‡เดจเดฟ เดจเดฎเตเด•เตเด•เต เด’เดฐเต เดชเตเดฒเด—เดฟเตป เดŽเดดเตเดคเตเดจเตเดจเดคเดฟเดฒเต‡เด•เตเด•เต เดคเดฟเดฐเดฟเดฏเดพเด‚. เดŽเดฒเตเดฒเดพ เดฎเต€เดกเดฟเดฏ เดธเตเดŸเตเดฐเต€เดฎเตผ เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เดณเตเด‚ เดชเตเดฒเด—เดฟเดจเตเดจเตเด•เดณเตเด‚ เด…เดตเดฐเตเดŸเต† เดŽเดดเตเดคเตเดคเดฟเตฝ เด’เดฐเต เดชเตŠเดคเต เด•เดพเดจเต‹เตป เดชเดฟเดจเตเดคเตเดŸเดฐเตเดจเตเดจเต, เด‡เดคเต เดจเดฟเด™เตเด™เตพ เดชเด เดฟเด•เตเด•เดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจ เด…เดŸเตเดคเตเดค เดซเดฟเตฝเดŸเตเดŸเดฑเดฟเดจเตเดฑเต† เด˜เดŸเดจ เดฎเดจเดธเตเดธเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเดคเต เดตเดณเดฐเต† เดŽเดณเตเดชเตเดชเดฎเดพเด•เตเด•เตเดจเตเดจเต. เด…เดคเดฟเดจเดพเตฝ, เดŽเดจเตเดฑเดฟเดฑเตเดฑเดฟเด•เดณเต† เด—เตเดฃเดฟเด•เตเด•เดพเดคเดฟเดฐเดฟเด•เตเด•เดพเตป, เดžเดพเตป เดชเตเดฒเด—เดฟเดจเตเด•เดณเต† เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เตพ เดŽเดจเตเดจเต เดตเดฟเดณเดฟเด•เตเด•เตเด‚.

NASH_FILTR เดŽเดจเตเดจ เดชเต‡เดฐเดฟเตฝ เด’เดฐเต เดชเตเดคเดฟเดฏ เดซเดฟเตฝเดŸเตเดŸเตผ เดตเดฟเด•เดธเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เดชเดฑเดฏเดพเด‚. เด‡เดคเต เด’เดฐเต เดฒเดณเดฟเดคเดฎเดพเดฏ เด•เดพเดฐเตเดฏเด‚ เดšเต†เดฏเตเดฏเตเด‚ - เด…เดคเดฟเดจเตเดฑเต† เดธเดฟเด‚เด—เดฟเตพ เด‡เตปเดชเตเดŸเตเดŸเดฟเตฝ เดจเดฟเดจเตเดจเต เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เดธเตเดตเต€เด•เดฐเดฟเดšเตเดšเต เด…เดคเดฟเดจเตเดฑเต† เด…เดžเตเดšเต เด”เดŸเตเดŸเตเดชเตเดŸเตเดŸเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดŸเตเดฐเดพเตปเดธเตเดฎเดฟเดฑเตเดฑเต เดšเต†เดฏเตเดฏเตเด•. เดคเดจเตเดจเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจ เดชเดฐเดฟเดงเดฟเด•เตเด•เต เดคเดพเดดเต†เดฏเตเดณเตเดณ เดธเดฟเด—เตเดจเตฝ เดฒเต†เดตเดฒเตเดณเตเดณ เด…เดžเตเดšเดฟเตฝ เด•เต‚เดŸเตเดคเตฝ เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เด…เดคเดฟเดฒเต‚เดŸเต† เด•เดŸเดจเตเดจเตเดชเต‹เด•เตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ เด…เดคเต เด’เดฐเต เด‡เดตเดจเตเดฑเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเด‚, เด•เต‚เดŸเดพเดคเต† เดชเดฐเดฟเดงเดฟเด•เตเด•เต เดฎเตเด•เดณเดฟเดฒเตเดณเตเดณ เดธเดฟเด—เตเดจเตฝ เดฒเต†เดตเดฒเตเดณเตเดณ เด…เดžเตเดšเดฟเตฝ เด•เต‚เดŸเตเดคเตฝ เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เด…เดคเดฟเดฒเต‚เดŸเต† เด•เดŸเดจเตเดจเตเดชเต‹เด•เตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ, เด…เดคเต เด’เดฐเต เด‡เดตเดจเตเดฑเตเด‚ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเด‚.

เดซเดฟเตฝเดŸเตเดŸเตผ เดฐเต€เดคเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเดฐเดฟเดงเดฟ เดธเดœเตเดœเต€เด•เดฐเดฟเด•เตเด•เตเด‚. เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต†เดฏเตเด‚ เดฎเต‚เดจเตเดจเดพเดฎเดคเตเดคเต†เดฏเตเด‚ เดฐเต€เดคเดฟเด•เตพ เดŽเด•เตเดธเดฟเดฑเตเดฑเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เด•เดŸเดจเตเดจเตเดชเต‹เด•เดพเตป เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเด‚/เดจเดฟเดฐเต‹เดงเดฟเด•เตเด•เตเด‚.

เดจเดฎเตเด•เตเด•เต เดคเตเดŸเด™เตเด™เดพเด‚. เด’เดฐเต เดซเดฟเตฝเดŸเตเดŸเตผ เดŽเดดเตเดคเตเดฎเตเดชเต‹เตพ, เดจเดฟเด™เตเด™เตพ เด’เดฐเต เดนเต†เดกเตเดกเตผ เดซเดฏเตฝ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด†เดฐเด‚เดญเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เด†เดฆเตเดฏ เดตเดฐเดฟเด•เดณเดฟเตฝ เด…เดคเต เดซเดฏเตฝ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฃเด‚ msfilter.h, MS_FILTER_METHOD เดฎเดพเด•เตเดฐเต‹ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต, เดชเตเดคเดฟเดฏ เดซเดฟเตฝเดŸเตเดŸเดฑเดฟเดจเตเดฑเต† เดฐเต€เดคเดฟเด•เตพ เดชเตเดฐเด–เตเดฏเดพเดชเดฟเด•เตเด•เตเด• (เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เด‰เดฃเตเดŸเต†เด™เตเด•เดฟเตฝ), เดซเดฟเตฝเดŸเตเดŸเตผ เดธเตƒเดทเตเดŸเดฟเดšเตเดš เด‡เดตเดจเตเดฑเตเด•เตพ (เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เด‰เดฃเตเดŸเต†เด™เตเด•เดฟเตฝ) เดชเตเดฐเด–เตเดฏเดพเดชเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดคเดฐเดคเตเดคเดฟเดจเตเดฑเต† เด•เดฏเดฑเตเดฑเตเดฎเดคเดฟ เดšเต†เดฏเตเดค เด˜เดŸเดจ เดชเตเดฐเด–เตเดฏเดพเดชเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเด• MSFilterDesc เดซเดฟเตฝเดŸเตเดŸเตผ เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตเด•เดณเตเดŸเต† เดตเดฟเดตเดฐเดฃเดคเตเดคเต‹เดŸเตŠเดชเตเดชเด‚:

/* ะคะฐะนะป nash_filter.h, ะพะฟะธัั‹ะฒะฐะตั‚ ั„ะธะปัŒั‚ั€-ั€ะฐะทะฒะตั‚ะฒะธั‚ะตะปัŒ ะธ ะฝะพะนะทะณะตะนั‚. */

#ifndef myfilter_h
#define myfilter_h

/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ะทะฐะณะพะปะพะฒะพั‡ะฝั‹ะน ั„ะฐะนะป ั ะฟะตั€ะตั‡ะธัะปะตะฝะธะตะผ ั„ะธะปัŒั‚ั€ะพะฒ ะผะตะดะธะฐัั‚ั€ะธะผะตั€ะฐ. */
#include <mediastreamer2/msticker.h>

/* 
   ะ—ะฐะดะฐะตะผ ั‡ะธัะปะพะฒะพะน ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ ะฝะพะฒะพะณะพ ั‚ะธะฟะฐ ั„ะธะปัŒั‚ั€ะฐ.  ะญั‚ะพ ั‡ะธัะปะพ ะฝะต ะดะพะปะถะฝะพ
   ัะพะฒะฟะฐะดะฐั‚ัŒ ะฝะธ ั ะพะดะฝะธะผ ะธะท ะดั€ัƒะณะธั… ั‚ะธะฟะพะฒ.  ะ’ ะผะตะดะธะฐัั‚ั€ะธะผะตั€ะต  ะฒ ั„ะฐะนะปะต allfilters.h
   ะตัั‚ัŒ ัะพะพั‚ะฒะตั‚ัั‚ะฒัƒัŽั‰ะตะต ะฟะตั€ะตั‡ะธัะปะตะฝะธะต enum MSFilterId. ะš ัะพะถะฐะปะตะฝะธัŽ, ะฝะตะฟะพะฝัั‚ะฝะพ
   ะบะฐะบ ะพะฟั€ะตะดะตะปะธั‚ัŒ ะผะฐะบัะธะผะฐะปัŒะฝะพะต ะทะฐะฝัั‚ะพะต ะทะฝะฐั‡ะตะฝะธะต, ะบั€ะพะผะต ะบะฐะบ ะทะฐะณะปัะฝัƒั‚ัŒ ะฒ ัั‚ะพั‚
   ั„ะฐะนะป. ะะพ ะผั‹ ะฒะพะทัŒะผะตะผ ะฒ ะบะฐั‡ะตัั‚ะฒะต id ะดะปั ะฝะฐัˆะตะณะพ ั„ะธะปัŒั‚ั€ะฐ ะทะฐะฒะตะดะพะผะพ ะฑะพะปัŒัˆะตะต
   ะทะฝะฐั‡ะตะฝะธะต: 4000.  ะ‘ัƒะดะตะผ ะฟะพะปะฐะณะฐั‚ัŒ, ั‡ั‚ะพ ั€ะฐะทั€ะฐะฑะพั‚ั‡ะธะบะธ ะดะพะฑะฐะฒะปัั ะฝะพะฒั‹ะต ั„ะธะปัŒั‚ั€ั‹, ะฝะต
   ัะบะพั€ะพ ะดะพะฑะตั€ัƒั‚ัั ะดะพ ัั‚ะพะณะพ ะฝะพะผะตั€ะฐ.  
   */
#define NASH_FILTER_ID 4000

/* 
   ะžะฟั€ะตะดะตะปัะตะผ ะผะตั‚ะพะดั‹ ะฝะฐัˆะตะณะพ ั„ะธะปัŒั‚ั€ะฐ. ะ’ั‚ะพั€ั‹ะผ ะฟะฐั€ะฐะผะตั‚ั€ะพะผ ะผะฐะบั€ะพัะฐ ะดะพะปะถะตะฝ
   ะฟะพั€ัะดะบะพะฒั‹ะน ะฝะพะผะตั€ ะผะตั‚ะพะดะฐ, ั‡ะธัะปะพ ะพั‚ 0.  ะขั€ะตั‚ะธะน ะฟะฐั€ะฐะผะตั‚ั€ ัั‚ะพ ั‚ะธะฟ ะฐั€ะณัƒะผะตะฝั‚ะฐ
   ะผะตั‚ะพะดะฐ, ัƒะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ะบะพั‚ะพั€ั‹ะน ะฑัƒะดะตั‚ ะฟะตั€ะตะดะฐะฒะฐั‚ัŒัั ะผะตั‚ะพะดัƒ ะฟั€ะธ ะฒั‹ะทะพะฒะต. ะฃ ะผะตั‚ะพะดะพะฒ
   ะฐั€ะณัƒะผะตะฝั‚ะพะฒ ะผะพะถะตั‚ ะธ ะฝะต ะฑั‹ั‚ัŒ, ะบะฐะบ ะฟะพะบะฐะทะฐะฝะพ ะฝะธะถะต. 
   */
#define NASH_FILTER_SET_TRESHOLD MS_FILTER_METHOD(NASH_FILTER_ID , 0, float)
#define NASH_FILTER_TUNE_OFF     MS_FILTER_METHOD_NO_ARG(NASH_FILTER_ID ,1)
#define NASH_FILTER_TUNE_ON      MS_FILTER_METHOD_NO_ARG(NASH_FILTER_ID ,2)

/* ะขะตะฟะตั€ัŒ ะพะฟั€ะตะดะตะปัะตะผ ัั‚ั€ัƒะบั‚ัƒั€ัƒ, ะบะพั‚ะพั€ะฐั ะฑัƒะดะตั‚ ะฟะตั€ะตะดะฐะฒะฐั‚ัŒัั ะฒะผะตัั‚ะต ั ัะพะฑั‹ั‚ะธะตะผ. */
struct _NASHFilterEvent
{
    /* ะญั‚ะพ ะฟะพะปะต, ะบะพั‚ะพั€ะพะต ะฑัƒะดะตั‚ ะฒั‹ะฟะพะปะฝัั‚ัŒ ั€ะพะปัŒ ั„ะปะฐะณะฐ,
       0 - ะฟะพัะฒะธะปะธััŒ ะฝัƒะปะธ, 1 - ะฟะพัะฒะธะปัั ัะธะณะฝะฐะป.*/
    char state; 
    /* ะ’ั€ะตะผั, ะบะพะณะดะฐ ะฟั€ะพะธะทะพัˆะปะพ ัะพะฑั‹ั‚ะธะต. */
    uint64_t time;
};
typedef struct _NASHFilterEvent NASHFilterEvent;

/* ะžะฟั€ะตะดะตะปัะตะผ ัะพะฑั‹ั‚ะธะต ะดะปั ะฝะฐัˆะตะณะพ ั„ะธะปัŒั‚ั€ะฐ. */
#define NASH_FILTER_EVENT MS_FILTER_EVENT(MS_RTP_RECV_ID, 0, NASHFilterEvent)

/* ะžะฟั€ะตะดะตะปัะตะผ ัะบัะฟะพั€ั‚ะธั€ัƒะตะผัƒัŽ ะฟะตั€ะตะผะตะฝะฝัƒัŽ, ะบะพั‚ะพั€ะฐั ะฑัƒะดะตั‚
   ั…ั€ะฐะฝะธั‚ัŒ ั…ะฐั€ะฐะบั‚ะตั€ะธัั‚ะธะบะธ ะดะปั ะดะฐะฝะฝะพะณะพ ั‚ะธะฟะฐ ั„ะธะปัŒั‚ั€ะพะฒ. */
extern MSFilterDesc nash_filter_desc;

#endif /* myfilter_h */

เด‡เดชเตเดชเต‹เตพ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‰เดฑเดตเดฟเดŸ เดซเดฏเดฒเดฟเดฒเต‡เด•เตเด•เต เดชเต‹เด•เดพเด‚. เด•เดฎเดจเตเดฑเตเด•เดณเตเดณเตเดณ เดซเดฟเตฝเดŸเตเดŸเดฑเดฟเดจเตเดฑเต† เดธเต‹เดดเตเดธเต เด•เต‹เดกเต เดคเดพเดดเต† เด•เดพเดฃเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต. เดซเดฟเตฝเดŸเตเดŸเตผ เดฐเต€เดคเดฟเด•เดณเตเด‚ เด†เดตเดถเตเดฏเดฎเดพเดฏ เดซเดฟเตฝเดŸเตเดŸเตผ เดซเด‚เด—เตเดทเดจเตเด•เดณเตเด‚ เด‡เดตเดฟเดŸเต† เดจเดฟเตผเดตเดšเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต. เด•เดฏเดฑเตเดฑเตเดฎเดคเดฟ เดšเต†เดฏเตเดค เด˜เดŸเดจเดฏเดฟเตฝ เด’เดฐเต เดจเดฟเดถเตเดšเดฟเดค เด•เตเดฐเดฎเดคเตเดคเดฟเตฝ เดฐเต€เดคเดฟเด•เดณเต†เดฏเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดจเด™เตเด™เดณเต†เดฏเตเด‚ เด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดฑเดซเดฑเตปเดธเตเด•เตพ เดธเตเดฅเดพเดชเดฟเด•เตเด•เตเดจเตเดจเต เดžเด™เตเด™เดณเตเดŸเต†_filter_desc. เดˆ เดคเดฐเดคเตเดคเดฟเดฒเตเดณเตเดณ เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เตพ เดกเดพเดฑเตเดฑ เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เต เดตเตผเด•เตเด•เตเดซเตเดฒเต‹เดฏเดฟเดฒเต‡เด•เตเด•เต "เด‡เด‚เดชเตเดฒเดพเดจเตเดฑเต" เดšเต†เดฏเตเดฏเดพเตป เดฎเต€เดกเดฟเดฏ เดธเตเดŸเตเดฐเต€เดฎเตผ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเต.

/* ะคะฐะนะป nash_filter.ั, ะพะฟะธัั‹ะฒะฐะตั‚ ั„ะธะปัŒั‚ั€-ั€ะฐะทะฒะตั‚ะฒะธั‚ะตะปัŒ ะธ ะฝะพะนะทะณะตะนั‚. */

#include "nash_filter.h"
#include <math.h>

#define NASH_FILTER_NOUTPUTS 5

/* ะžะฟั€ะตะดะตะปัะตะผ ัั‚ั€ัƒะบั‚ัƒั€ัƒ, ะบะพั‚ะพั€ะฐั ั…ั€ะฐะฝะธั‚ ะฒะฝัƒั‚ั€ะตะฝะฝะตะต ัะพัั‚ะพัะฝะธะต ั„ะธะปัŒั‚ั€ะฐ. */
typedef struct _nash_filterData
{
    bool_t disable_out;  /* ะ ะฐะทั€ะตัˆะตะฝะธะต ะฟะตั€ะตะดะฐั‡ะธ ะฑะปะพะบะพะฒ ะฝะฐ ะฒั‹ั…ะพะด. */
    int last_state;   /* ะขะตะบัƒั‰ะตะต ัะพัั‚ะพัะฝะธะต ะฟะตั€ะตะบะปัŽั‡ะฐั‚ะตะปั. */
    char zero_count;     /* ะกั‡ะตั‚ั‡ะธะบ ะฝัƒะปะตะฒั‹ั… ะฑะปะพะบะพะฒ. */
    char lag;            /* ะšะพะปะธั‡ะตัั‚ะฒะพ ะฑะปะพะบะพะฒ ะดะปั ะฟั€ะธะฝัั‚ะธั ั€ะตัˆะตะฝะธั ะฝะพะนะทะณะตะนั‚ะพะผ. */
    char n_count;        /* ะกั‡ะตั‚ั‡ะธะบ ะะ•ะฝัƒะปะตะฒั‹ั… ะฑะปะพะบะพะฒ. */
    float skz_level;     /* ะกั€ะตะดะฝะตะบะฒะฐะดั€ะฐั‚ะธั‡ะตัะบะพะต ะทะฝะฐั‡ะตะฝะธะต ัะธะณะฝะฐะปะฐ ะฒะฝัƒั‚ั€ะธ
ะฑะปะพะบะฐ, ะฟั€ะธ ะบะพั‚ะพั€ะพะผ ั„ะธะปัŒั‚ั€ ะฑัƒะดะตั‚ ะฟั€ะพะฟัƒัะบะฐั‚ัŒ ัะธะณะฝะฐะป. ะžะดะฝะพะฒั€ะตะผะตะฝะฝะพ ัั‚ะพ ะฟะพั€ะพะณ
ัั€ะฐะฑะฐั‚ั‹ะฒะฐะฝะธั, ะฟะพ ะบะพั‚ะพั€ะพะผัƒ ะฑัƒะดะตั‚ ั„ะพั€ะผะธั€ะพะฒะฐั‚ัŒัั ัะพะฑั‹ั‚ะธะต.  */

} nash_filterData;

/*----------------------------------------------------------*/
/* ะžะฑัะทะฐั‚ะตะปัŒะฝะฐั ั„ัƒะฝะบั†ะธั ะธะฝะธั†ะธะฐะปะธะทะฐั†ะธะธ. */
static void nash_filter_init(MSFilter *f)
{
    nash_filterData *d=ms_new0(nash_filterData, 1);
    d->lag=5;
    f->data=d;
}

/*----------------------------------------------------------*/
/* ะžะฑัะทะฐั‚ะตะปัŒะฝะฐั ั„ัƒะฝะบั†ะธั ั„ะธะฝะฐะปะธะทะฐั†ะธะธ ั€ะฐะฑะพั‚ั‹ ั„ะธะปัŒั‚ั€ะฐ,
   ะพัะฒะพะฑะพะถะดะฐะตั‚ัั ะฟะฐะผัั‚ัŒ. */
static void nash_filter_uninit(MSFilter *f)
{
    ms_free(f->data);
}

/*----------------------------------------------------------*/
/* ะžะฟั€ะตะดะตะปัะตะผ ะพะฑั€ะฐะทั†ะพะฒั‹ะน ะผะฐััะธะฒ ั ะฝัƒะปัะผะธ, ะทะฐะฒะตะดะพะผะพ
   ะฑะพะปัŒัˆะตะณะพ ั€ะฐะทะผะตั€ะฐ ั‡ะตะผ ะฑะปะพะบ. */
char zero_array[1024]={0};

/* ะžะฟั€ะตะดะตะปัะตะผ ัะพะฑั‹ั‚ะธะต ั„ะธะปัŒั‚ั€ะฐ. */
NASHFilterEvent event;

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั ะพั‚ะฟั€ะฐะฒะบะธ ัะพะฑั‹ั‚ะธั. */
static void send_event(MSFilter *f, int state)
{
    nash_filterData *d =( nash_filterData* ) f->data;
     d->last_state = state;
    /* ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฒั€ะตะผั ะฒะพะทะฝะธะบะฝะพะฒะตะฝะธั ัะพะฑั‹ั‚ะธั,
       ะพั‚ ะผะพะผะตะฝั‚ะฐ ะฟะตั€ะฒะพะณะพ ั‚ะธะบะฐ. ะ’ั€ะตะผั ะฒ ะผะธะปะปะธัะตะบัƒะฝะดะฐั…. */
    event.time=f -> ticker -> time;
    event.state=state;  
    ms_filter_notify(f, NASH_FILTER_EVENT, &event);
}   

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั ะฒั‹ั‡ะธัะปัะตั‚ ัั€ะตะดะฝะตะบะฒะฐะดั€ะฐั‚ะธั‡ะตัะบะพะต (ัั„ั„ะตะบั‚ะธะฒะฝะพะต) ะทะฝะฐั‡ะตะฝะธะต ัะธะณะฝะฐะปะฐ ะฒะฝัƒั‚ั€ะธ
  ะฑะปะพะบะฐ. */
static float calc_skz(nash_filterData *d, int16_t *signal, int numsamples)
{
    int i;
    float acc = 0;
    for (i=0; i<numsamples; i++)
    {
        int s=signal[i];
        acc = acc + s * s;
    }
    float skz = (float)sqrt(acc / numsamples);
    return skz;
}

/*----------------------------------------------------------*/
/* ะžะฑัะทะฐั‚ะตะปัŒะฝะฐั ั„ัƒะฝะบั†ะธั ะพัะฝะพะฒะฝะพะณะพ ั†ะธะบะปะฐ ั„ะธะปัŒั‚ั€ะฐ,
   ะฒั‹ะทั‹ะฒะฐะตั‚ัั ั ะบะฐะถะดั‹ะผ ั‚ะธะบะพะผ. */
static void nash_filter_process(MSFilter *f)
{
    nash_filterData *d=(nash_filterData*)f->data;

    /* ะฃะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ะฒั…ะพะดะฝะพะต ัะพะพะฑั‰ะตะฝะธะต ัะพะดะตั€ะถะฐั‰ะตะต ะฑะปะพะบ ะดะฐะฝะฝั‹ั…. */
    mblk_t *im;
    int i;
    int state;
    /* ะ’ั‹ั‡ะธั‚ั‹ะฒะฐะตะผ ัะพะพะฑั‰ะตะฝะธั ะธะท ะฒั…ะพะดะฝะพะน ะพั‡ะตั€ะตะดะธ
       ะดะพ ะฟะพะปะฝะพะณะพ ะตั‘ ะพะฟัƒัั‚ะพัˆะตะฝะธั. */
    while((im=ms_queue_get(f->inputs[0]))!=NULL)
    {
        /* ะ•ัะปะธ ะฒั‹ั…ะพะดั‹ ะทะฐะฟั€ะตั‰ะตะฝั‹, ั‚ะพ ะฟั€ะพัั‚ะพ ัƒะดะฐะปัะตะผ ะฒั…ะพะดะฝะพะต ัะพะพะฑั‰ะตะฝะธะต. */
        if ( d -> disable_out)
        {
          freemsg(im);
          continue;
        }

        /* ะ˜ะทะผะตั€ัะตะผ ัƒั€ะพะฒะตะฝัŒ ัะธะณะฝะฐะปะฐ ะธ ะฟั€ะธะฝะธะผะฐะตะผ ั€ะตัˆะตะฝะธะต ะพะฑ ะพั‚ะฟั€ะฐะฒะบะต ัะธะณะฝะฐะปะฐ. */
        float skz = calc_skz(d, (int16_t*)im->b_rptr, msgdsize(im));
        state = (skz > d->skz_level) ? 1 : 0; 
        if (state) 
        {
            d->n_count++;
            d->zero_count = 0;
        }
        else
        {
            d->n_count = 0;
            d->zero_count++;
        }
        if (((d->zero_count > d->lag) || (d->n_count > d->lag))
            &&  (d->last_state != state)) send_event(f, state);

        /* ะŸั€ะธัั‚ัƒะฟะฐะตะผ ะบ ะบะพะฟะธั€ะพะฒะฐะฝะธัŽ ะฒั…ะพะดะฝะพะณะพ ัะพะพะฑั‰ะตะฝะธั ะธ ั€ะฐัะบะปะฐะดะบะต ะฟะพ ะฒั‹ั…ะพะดะฐะผ. ะะพ
         * ั‚ะพะปัŒะบะพ ะฟะพ ั‚ะตะผ, ะบ ะบะพั‚ะพั€ั‹ะผ ะฟะพะดะบะปัŽั‡ะตะฝะฐ ะฝะฐะณั€ัƒะทะบะฐ. ะžั€ะธะณะธะฝะฐะปัŒะฝะพะต ัะพะพะฑั‰ะตะฝะธะต
         * ัƒะนะดะตั‚ ะฝะฐ ะฒั‹ั…ะพะด ั ะธะฝะดะตะบัะพะผ 0, ะฐ ะตะณะพ ะบะพะฟะธะธ ะฟะพะฟะฐะดัƒั‚ ะฝะฐ ะพัั‚ะฐะปัŒะฝั‹ะต
         * ะฒั‹ั…ะพะดั‹. */ 
        int output_count = 0;
        mblk_t *outm; /* ะฃะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ัะพะพะฑั‰ะตะฝะธะต ั ะฒั‹ั…ะพะดะฝั‹ะผ ะฑะปะพะบะพะผ ะดะฐะฝะฝั‹ั…. */
        for(i=0; i < f->desc->noutputs; i++)
        {
            if (f->outputs[i]!=NULL)
            {
                if (output_count == 0)
                {
                    outm = im;
                }
                else
                {
                    /* ะกะพะทะดะฐะตะผ ะปะตะณะบัƒัŽ ะบะพะฟะธัŽ ัะพะพะฑั‰ะตะฝะธั. */       
                    outm = dupmsg(im);
                }
                /* ะŸะพะผะตั‰ะฐะตะผ ะบะพะฟะธัŽ ะธะปะธ ะพั€ะธะณะธะฝะฐะป ะฒั…ะพะดะฝะพะณะพ ัะพะพะฑั‰ะตะฝะธั ะฝะฐ ะพั‡ะตั€ะตะดะฝะพะน
                 * ะฒั‹ั…ะพะด ั„ะธะปัŒั‚ั€ะฐ. */ 
                ms_queue_put(f->outputs[i], outm);
                output_count++;
            }
        }
    }
}

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั-ะพะฑั€ะฐะฑะพั‚ั‡ะธะบ ะฒั‹ะทะพะฒะฐ ะผะตั‚ะพะดะฐ NASH_FILTER_SET_LAG. */
static int nash_filter_set_treshold(MSFilter *f, void *arg)
{
    nash_filterData *d=(nash_filterData*)f->data;
    d->skz_level=*(float*)arg;
    return 0;
}

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั-ะพะฑั€ะฐะฑะพั‚ั‡ะธะบ ะฒั‹ะทะพะฒะฐ ะผะตั‚ะพะดะฐ NASH_FILTER_TUNE_OFF. */
static int nash_filter_tune_off(MSFilter *f, void *arg)
{
    nash_filterData *d=(nash_filterData*)f->data;
    d->disable_out=TRUE;
    return 0;
}

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั-ะพะฑั€ะฐะฑะพั‚ั‡ะธะบ ะฒั‹ะทะพะฒะฐ ะผะตั‚ะพะดะฐ NASH_FILTER_TUNE_ON. */
static int nash_filter_tune_on(MSFilter *f, void *arg)
{
    nash_filterData *d=(nash_filterData*)f->data;
    d->disable_out=FALSE;
    return 0;
}

/*----------------------------------------------------------*/
/* ะ—ะฐะฟะพะปะฝัะตะผ ั‚ะฐะฑะปะธั†ัƒ ะผะตั‚ะพะดะพะฒ ั„ะธะปัŒั‚ั€ะฐ, ัะบะพะปัŒะบะพ ะผะตั‚ะพะดะพะฒ
   ะผั‹ ะพะฟั€ะตะดะตะปะธะปะธ ะฒ ะทะฐะณะพะปะพะฒะพั‡ะฝะพะผ ั„ะฐะนะปะต ัั‚ะพะปัŒะบะพ ะฝะตะฝัƒะปะตะฒั‹ั…
   ัั‚ั€ะพะบ. */
static MSFilterMethod nash_filter_methods[]={
    { NASH_FILTER_SET_TRESHOLD, nash_filter_set_treshold },
    { NASH_FILTER_TUNE_OFF, nash_filter_tune_off },
    { NASH_FILTER_TUNE_ON, nash_filter_tune_on },
    { 0 , NULL } /* ะœะฐั€ะบะตั€ ะบะพะฝั†ะฐ ั‚ะฐะฑะปะธั†ั‹. */
};

/*----------------------------------------------------------*/
/* ะžะฟะธัะฐะฝะธะต ั„ะธะปัŒั‚ั€ะฐ ะดะปั ะผะตะดะธะฐัั‚ั€ะธะผะตั€ะฐ. */
MSFilterDesc nash_filter_desc=
{
    NASH_FILTER_ID,
    "NASH_FILTER",
    "A filter with noise gate that reads from input and copy to it's five outputs.",
    MS_FILTER_OTHER,
    NULL,
    1,
    NASH_FILTER_NOUTPUTS,
    nash_filter_init,
    NULL,
    nash_filter_process,
    NULL,
    nash_filter_uninit,
    nash_filter_methods
};

MS_FILTER_DESC_EXPORT(nash_filter_desc)

เด‡เดชเตเดชเต‹เตพ, เด•เดพเดฒเดคเดพเดฎเดธเด‚ เด•เต‚เดŸเดพเดคเต†, เดžเด™เตเด™เตพ เดจเต‡เดฐเดคเตเดคเต† เด‰เดฃเตเดŸเดพเด•เตเด•เดฟเดฏ เด‡เดจเตเดฑเตผเด•เต‹เดฎเดฟเตฝ เดจเดฎเตเดฎเตเดŸเต† เดซเดฟเตฝเดŸเตเดŸเตผ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเด‚. เดถเต€เตผเดทเด• เดšเดฟเดคเตเดฐเด‚ เดชเดฐเดฟเดทเตเด•เดฐเดฟเดšเตเดš เด‡เดจเตเดฑเตผเด•เต‹เดฎเดฟเดจเตเดฑเต† เด’เดฐเต เดกเดฏเด—เตเดฐเด‚ เด•เดพเดฃเดฟเด•เตเด•เตเดจเตเดจเต.
เดžเด™เตเด™เดณเตเดŸเต† เด•เตˆเด•เตŠเดฃเตเดŸเต เดจเดฟเตผเดฎเตเดฎเดฟเดšเตเดš เดซเดฟเตฝเดŸเตเดŸเตผ เดชเตเดฐเดคเตเดฏเต‡เด•เดฟเดšเตเดšเต เดคเต†เดณเดฟเดšเตเดšเดฎเตเดณเตเดณ เดฐเต€เดคเดฟเดฏเดฟเตฝ เดšเดฟเดคเตเดฐเต€เด•เดฐเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเดšเตเดšเต. เด…เดคเดฟเดจเดพเตฝ, เดกเดฏเด—เตเดฐเดพเดฎเดฟเตฝ เดžเด™เตเด™เดณเตเดŸเต† เดซเดฟเตฝเดŸเตเดŸเตผ เดจเดฟเด™เตเด™เตพ เด‰เดŸเตป เด•เดฃเตเดŸเต†เดคเตเดคเตเด‚.

เดธเตผเด•เตเดฏเต‚เดŸเตเดŸเดฟเดฒเต‡เด•เตเด•เต เด’เดฐเต เดซเดฟเตฝเดŸเตเดŸเตผ-เดฑเต†เด•เตเด•เต‹เตผเดกเตผ เดšเต‡เตผเดคเตเดคเต, เด…เดคเต เด’เดฐเต wav เดซเดฏเดฒเดฟเดฒเต‡เด•เตเด•เต เด‡เตปเดชเตเดŸเตเดŸเต เดธเดฟเด—เตเดจเตฝ เดŽเดดเตเดคเตเดจเตเดจเต. เด†เดธเต‚เดคเตเดฐเดฃเด‚ เดšเต†เดฏเตเดคเดคเตเดชเต‹เดฒเต†, เดซเดฏเดฒเดฟเตฝ เดธเด‚เดญเดพเดทเดฃเดคเตเดคเดฟเตฝ เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด•เดฎเดพเดฏเดฟ เดจเดฟเตผเดคเตเดคเตเดจเตเดจเดคเต เด’เดดเดฟเดตเดพเด•เตเด•เดพเตป เดžเด™เตเด™เดณเตเดŸเต† เดซเดฟเตฝเดŸเตเดŸเตผ เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเด‚. เด…เด™เตเด™เดจเต† เด…เดคเดฟเดจเตเดฑเต† เดตเดฒเดฟเดชเตเดชเด‚ เด•เตเดฑเดฏเตเดจเตเดจเต.
เดฒเต‡เด–เดจเดคเตเดคเดฟเดจเตเดฑเต† เดคเตเดŸเด•เตเด•เดคเตเดคเดฟเตฝ, เดžเด™เตเด™เตพ เดซเดฟเตฝเดŸเตเดŸเดฑเดฟเดจเตเดฑเต† เด…เตฝเด—เต‹เดฐเดฟเดคเด‚ เดตเดฟเดตเดฐเดฟเดšเตเดšเต. เดชเตเดฐเดงเดพเดจ เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เด…เดคเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจ เด‡เดตเดจเตเดฑเตเด•เตพ เด•เตˆเด•เดพเดฐเตเดฏเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต. เด‡เดตเดจเตเดฑเดฟเตฝ "0" เดซเตเดฒเดพเด—เต เด…เดŸเด™เตเด™เดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเต†เด™เตเด•เดฟเตฝ, เดนเต‹เดธเตเดฑเตเดฑเต เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเด‚เด—เต เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด•เดฎเดพเดฏเดฟ เดจเดฟเตผเดคเตเดคเตเดจเตเดจเต. เดซเตเดฒเดพเด—เต "1" เด‰เดณเตเดณ เด’เดฐเต เด‡เดตเดจเตเดฑเต เดตเดจเตเดจเดพเดฒเตเดŸเตป, เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเด‚เด—เต เดชเตเดจเดฐเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต.

เดฎเตเดฎเตเดชเดคเตเดคเต‡เดคเดฟเดฒเต‡เด•เตเด•เต เดฐเดฃเตเดŸเต เด•เดฎเดพเตปเดกเต เดฒเตˆเตป เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเตเด•เตพ เด•เต‚เดŸเดฟ เดšเต‡เตผเดคเตเดคเต: --ng, เด‡เดคเต เดซเดฟเตฝเดŸเตเดŸเตผ เดคเตเดฐเต†เดทเต‹เตพเดกเต เดฒเต†เดตเตฝ เดธเดœเตเดœเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต เด’เดชเตเดชเด‚ --recเดŽเดจเตเดจเต เดตเดฟเดณเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดจเตเดจ เดซเดฏเดฒเดฟเดฒเต‡เด•เตเด•เต เดŽเดดเตเดคเดพเตป เดคเตเดŸเด™เตเด™เตเดจเตเดจเต เดฑเต†เด•เตเด•เต‹เตผเดกเต.wav.

/* ะคะฐะนะป mstest9.c ะ˜ะผะธั‚ะฐั‚ะพั€ ะฟะตั€ะตะณะพะฒะพั€ะฝะพะณะพ ัƒัั‚ั€ะพะนัั‚ะฒะฐ c ั€ะตะณะธัั‚ั€ะฐั‚ะพั€ะพะผ ะธ
* ะฝะพะนะทะณะตะนั‚ะพะผ. */
#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>
#include <mediastreamer2/msfilerec.h>
/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ะฝะฐัˆ ั„ะธะปัŒั‚ั€. */
#include "nash_filter.h"
/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ั„ะฐะนะป ะพะฑั‰ะธั… ั„ัƒะฝะบั†ะธะน. */
#include "mstest_common.c"
/*----------------------------------------------------------*/
struct _app_vars
{
int  local_port;              /* ะ›ะพะบะฐะปัŒะฝั‹ะน ะฟะพั€ั‚. */
int  remote_port;             /* ะŸะพั€ั‚ ะฟะตั€ะตะณะพะฒะพั€ะฝะพะณะพ ัƒัั‚ั€ะพะนัั‚ะฒะฐ ะฝะฐ ัƒะดะฐะปะตะฝะฝะพะผ ะบะพะผะฟัŒัŽั‚ะตั€ะต. */
char remote_addr[128];        /* IP-ะฐะดั€ะตั ัƒะดะฐะปะตะฝะฝะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ. */
MSDtmfGenCustomTone dtmf_cfg; /* ะะฐัั‚ั€ะพะนะบะธ ั‚ะตัั‚ะพะฒะพะณะพ ัะธะณะฝะฐะปะฐ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
MSFilter* recorder;           /* ะฃะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ั„ะธะปัŒั‚ั€ ั€ะตะณะธัั‚ั€ะฐั‚ะพั€. */
bool_t file_is_open;          /* ะคะปะฐะณ ั‚ะพะณะพ, ั‡ั‚ะพ ั„ะฐะนะป ะดะปั ะทะฐะฟะธัะธ ะพั‚ะบั€ั‹ั‚. */
/* ะŸะพั€ะพะณ, ะฟั€ะธ ะบะพั‚ะพั€ะพะผ ะฟั€ะตะบั€ะฐั‰ะฐะตั‚ัั ะทะฐะฟะธััŒ ะฟั€ะธะฝะธะผะฐะตะผะพะณะพ ัะธะณะฝะฐะปะฐ ะฒ ั„ะฐะนะป. */
float treshold; 
bool_t en_rec;                /*ะ’ะบะปัŽั‡ะธั‚ัŒ ะทะฐะฟะธััŒ ะฒ ั„ะฐะนะป.*/    
};
typedef struct _app_vars app_vars;
/*----------------------------------------------------------*/
/* ะกะพะทะดะฐะตะผ ะดัƒะฟะปะตะบัะฝัƒัŽ RTP-ัะตััะธัŽ. */
RtpSession* create_duplex_rtp_session(app_vars v)
{
RtpSession *session = create_rtpsession (v.local_port, v.local_port + 1,
FALSE, RTP_SESSION_SENDRECV);
rtp_session_set_remote_addr_and_port(session, v.remote_addr, v.remote_port,
v.remote_port + 1);
rtp_session_set_send_payload_type(session, PCMU);
return session;
}
/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั ะฟั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธั ะฐั€ะณัƒะผะตะฝั‚ะพะฒ ะบะพะผะฐะฝะดะฝะพะน ัั‚ั€ะพะบะธ ะฒ 
* ะฝะฐัั‚ั€ะพะนะบะธ ะฟั€ะพะณั€ะฐะผะผั‹. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
char i;
for (i=0; i<argc; i++)
{
if (!strcmp(argv[i], "--help"))
{
char *p=argv[0]; p=p + 2;
printf("  %s walkie talkienn", p);
printf("--help      List of options.n");
printf("--version   Version of application.n");
printf("--addr      Remote abonent IP address string.n");
printf("--port      Remote abonent port number.n");
printf("--lport     Local port number.n");
printf("--gen       Generator frequency.n");
printf("--ng        Noise gate treshold level from 0. to 1.0n");
printf("--rec       record to file 'record.wav'.n");
exit(0);
}
if (!strcmp(argv[i], "--version"))
{
printf("0.1n");
exit(0);
}
if (!strcmp(argv[i], "--addr"))
{
strncpy(v->remote_addr, argv[i+1], 16);
v->remote_addr[16]=0;
printf("remote addr: %sn", v->remote_addr);
}
if (!strcmp(argv[i], "--port"))
{
v->remote_port=atoi(argv[i+1]);
printf("remote port: %in", v->remote_port);
}
if (!strcmp(argv[i], "--lport"))
{
v->local_port=atoi(argv[i+1]);
printf("local port : %in", v->local_port);
}
if (!strcmp(argv[i], "--gen"))
{
v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
}
if (!strcmp(argv[i], "--ng"))
{
v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
printf("noise gate treshold: %fn", v -> treshold);
}
if (!strcmp(argv[i], "--rec"))
{
v -> en_rec = TRUE;
printf("enable recording: %in", v -> en_rec);
}
}
}
/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั ะพะฑั€ะฐั‚ะฝะพะณะพ ะฒั‹ะทะพะฒะฐ, ะพะฝะฐ ะฑัƒะดะตั‚ ะฒั‹ะทะฒะฐะฝะฐ ั„ะธะปัŒั‚ั€ะพะผ, ะบะฐะบ ั‚ะพะปัŒะบะพ ะพะฝ
* ะทะฐะผะตั‚ะธั‚, ั‡ั‚ะพ ะฝะฐัั‚ัƒะฟะธะปะฐ ั‚ะธัˆะธะฝะฐ ะธะปะธ ะฝะฐะพะฑะพั€ะพั‚ ั‚ะธัˆะธะฝะฐ ัะผะตะฝะธะปะฐััŒ ะทะฒัƒะบะฐะผะธ. */
static void change_detected_cb(void *data, MSFilter *f, unsigned int event_id,
NASHFilterEvent *ev)
{
app_vars *vars = (app_vars*) data;
/* ะ•ัะปะธ ะทะฐะฟะธััŒ ะฝะต ะฑั‹ะปะฐ ั€ะฐะทั€ะตัˆะตะฝะฐ, ั‚ะพ ะฒั‹ั…ะพะดะธะผ. */
if (! vars -> en_rec) return; 
if (ev -> state)
{
/* ะ’ะพะทะพะฑะฝะพะฒะปัะตะผ ะทะฐะฟะธััŒ. */
if(!vars->file_is_open)
{
ms_filter_call_method(vars->recorder, MS_FILE_REC_OPEN, "record.wav");
vars->file_is_open = 1;
}
ms_filter_call_method(vars->recorder, MS_FILE_REC_START, 0);
printf("Recording...n");
}
else
{
/* ะŸั€ะธะพัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะทะฐะฟะธััŒ. */
ms_filter_call_method(vars->recorder, MS_FILE_REC_STOP, 0);
printf("Pause...n");
}
}
/*----------------------------------------------------------*/
int main(int argc, char *argv[])
{
/* ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐัั‚ั€ะพะนะบะธ ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ. */
app_vars vars={5004, 7010, "127.0.0.1", {0}, 0, 0, 0.01, 0};
/* ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐัั‚ั€ะพะนะบะธ ะฝะฐัั‚ั€ะพะนะบะธ ะฟั€ะพะณั€ะฐะผะผั‹ ะฒ 
* ัะพะพั‚ะฒะตั‚ัั‚ะฒะธะธ ั ะฐั€ะณัƒะผะตะฝั‚ะฐะผะธ ะบะพะผะฐะฝะดะฝะพะน ัั‚ั€ะพะบะธ. */
scan_args(argc, argv, &vars);
ms_init();
/* ะกะพะทะดะฐะตะผ ัะบะทะตะผะฟะปัั€ั‹ ั„ะธะปัŒั‚ั€ะพะฒ ะฟะตั€ะตะดะฐัŽั‰ะตะณะพ ั‚ั€ะฐะบั‚ะฐ. */
MSSndCard *snd_card =
ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
MSFilter *snd_card_read = ms_snd_card_create_reader(snd_card);
MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);
/* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะบะพะดะตั€ะฐ. */
MSFilter *encoder = ms_filter_create_encoder("PCMU");
/* ะ ะตะณะธัั‚ั€ะธั€ัƒะตะผ ั‚ะธะฟั‹ ะฝะฐะณั€ัƒะทะบะธ. */
register_payloads();
/* ะกะพะทะดะฐะตะผ ะดัƒะฟะปะตะบัะฝัƒัŽ RTP-ัะตััะธัŽ. */
RtpSession* rtp_session = create_duplex_rtp_session(vars);
ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, rtp_session);
/* ะกะพะตะดะธะฝัะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟะตั€ะตะดะฐั‚ั‡ะธะบะฐ. */
ms_filter_link(snd_card_read, 0, dtmfgen, 0);
ms_filter_link(dtmfgen, 0, encoder, 0);
ms_filter_link(encoder, 0, rtpsend, 0);
/* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟั€ะธะตะผะฝะพะณะพ ั‚ั€ะฐะบั‚ะฐ. */
MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rtp_session);
/* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะดะตะบะพะดะตั€ะฐ. */
MSFilter *decoder=ms_filter_create_decoder("PCMU");
//MS_FILE_REC_ID
/* ะ ะตะณะธัั‚ั€ะธั€ัƒะตะผ ะฝะฐัˆ ั„ะธะปัŒั‚ั€. */
ms_filter_register(&nash_filter_desc);
MSFilter *nash = ms_filter_new(NASH_FILTER_ID);
/* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะทะฒัƒะบะพะฒะพะน ะบะฐั€ั‚ั‹. */
MSFilter *snd_card_write = ms_snd_card_create_writer(snd_card);
/* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ั€ะตะณะธัั‚ั€ะฐั‚ะพั€ะฐ. */
MSFilter *recorder=ms_filter_new(MS_FILE_REC_ID);
vars.recorder = recorder; 
/* ะกะพะตะดะธะฝัะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟั€ะธั‘ะผะฝะพะณะพ ั‚ั€ะฐะบั‚ะฐ. */
ms_filter_link(rtprecv, 0, decoder, 0);
ms_filter_link(decoder, 0, nash, 0);
ms_filter_link(nash, 0, snd_card_write, 0);
ms_filter_link(nash, 1, recorder, 0);
/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ะบ ั„ะธะปัŒั‚ั€ัƒ ั„ัƒะฝะบั†ะธัŽ ะพะฑั€ะฐั‚ะฝะพะณะพ ะฒั‹ะทะพะฒะฐ, ะธ ะฟะตั€ะตะดะฐะตะผ ะตะน ะฒ
* ะบะฐั‡ะตัั‚ะฒะต ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะธั… ะดะฐะฝะฝั‹ั… ัƒะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ัั‚ั€ัƒะบั‚ัƒั€ัƒ ั ะฝะฐัั‚ั€ะพะนะบะฐะผะธ
* ะฟั€ะพะณั€ะฐะผะผั‹, ะฒ ะบะพั‚ะพั€ะพะน ัั€ะตะดะธ ะฟั€ะพั‡ะธั… ะตัั‚ัŒ ัƒะบะฐะทะฐั‚ัŒ ะฝะฐ ั„ะธะปัŒั‚ั€
* ั€ะตะณะธัั‚ั€ะฐั‚ะพั€ะฐ. */
ms_filter_set_notify_callback(nash,
(MSFilterNotifyFunc)change_detected_cb, &vars);
ms_filter_call_method(nash,NASH_FILTER_SET_TRESHOLD, &vars.treshold); 
/* ะกะพะทะดะฐะตะผ ะธัั‚ะพั‡ะฝะธะบ ั‚ะฐะบั‚ะพะฒ - ั‚ะธะบะตั€. */
MSTicker *ticker = ms_ticker_new();
/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ะธัั‚ะพั‡ะฝะธะบ ั‚ะฐะบั‚ะพะฒ. */
ms_ticker_attach(ticker, snd_card_read);
ms_ticker_attach(ticker, rtprecv);
/* ะ•ัะปะธ ะฝะฐัั‚ั€ะพะนะบะฐ ั‡ะฐัั‚ะพั‚ั‹ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ ะพั‚ะปะธั‡ะฝะฐ ะพั‚ ะฝัƒะปั, ั‚ะพ ะทะฐะฟัƒัะบะฐะตะผ ะณะตะฝะตั€ะฐั‚ะพั€. */   
if (vars.dtmf_cfg.frequencies[0])
{
/* ะะฐัั‚ั€ะฐะธะฒะฐะตะผ ัั‚ั€ัƒะบั‚ัƒั€ัƒ, ัƒะฟั€ะฐะฒะปััŽั‰ัƒัŽ ะฒั‹ั…ะพะดะฝั‹ะผ ัะธะณะฝะฐะปะพะผ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
vars.dtmf_cfg.duration = 10000;
vars.dtmf_cfg.amplitude = 1.0;
}
/* ะžั€ะณะฐะฝะธะทัƒะตะผ ั†ะธะบะป ะฟะตั€ะตะทะฐะฟัƒัะบะฐ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
printf("Press ENTER to exit.n ");
char c=getchar();
while(c != 'n')
{
if(vars.dtmf_cfg.frequencies[0])
{
/* ะ’ะบะปัŽั‡ะฐะตะผ ะทะฒัƒะบะพะฒะพะน ะณะตะฝะตั€ะฐั‚ะพั€. */
ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
(void*)&vars.dtmf_cfg);
}
char c=getchar();
printf("--n");
}
if (vars.en_rec ) ms_filter_call_method(recorder, MS_FILE_REC_CLOSE, 0);
}

เดžเด™เตเด™เตพ เดซเดฏเดฒเตเด•เตพ เดšเต‡เตผเดคเตเดคเดคเตเด‚ เดฒเตˆเดฌเตเดฐเดฑเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเดคเตเด‚ เด•เดพเดฐเดฃเด‚ เด•เดฃเด•เตเด•เต, เดธเดฎเดพเดนเดพเดฐเดคเตเดคเดฟเดจเดพเดฏเตเดณเตเดณ เด•เดฎเดพเตปเดกเต เดฒเตˆเตป เด•เต‚เดŸเตเดคเตฝ เดธเด™เตเด•เต€เตผเดฃเตเดฃเดฎเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต, เด‡เดคเตเดชเต‹เดฒเต† เด•เดพเดฃเดชเตเดชเต†เดŸเตเดจเตเดจเต:

$ gcc mstest9.c nash_filter.c -o mstest9   `pkg-config mediastreamer   --libs --cflags`  -lm

เด†เดชเตเดฒเดฟเด•เตเด•เต‡เดทเตป เดจเดฟเตผเดฎเตเดฎเดฟเดšเตเดš เดถเต‡เดทเด‚, เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด†เดฆเตเดฏเดคเตเดคเต† เด•เดฎเตเดชเตเดฏเต‚เดŸเตเดŸเดฑเดฟเตฝ เด‡เดคเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด•:

$ ./mstest9  --lport 7010  --port 8010 --addr <ั‚ัƒั‚ ะฐะดั€ะตั ะฒั‚ะพั€ะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ> --rec

เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต† เด•เดฎเตเดชเตเดฏเต‚เดŸเตเดŸเดฑเดฟเตฝ เดžเด™เตเด™เตพ เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เด•เตเดฐเดฎเต€เด•เดฐเดฃเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต:

$ ./mstest9  --lport 8010  --port 7010 --addr <ั‚ัƒั‚ ะฐะดั€ะตั ะฟะตั€ะฒะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ>

เด‡เดคเดฟเดจเตเดถเต‡เดทเด‚, เด†เดฆเตเดฏเดคเตเดคเต† เด•เดฎเตเดชเตเดฏเต‚เดŸเตเดŸเตผ เดจเดฟเด™เตเด™เตพ เดชเดฑเดฏเตเดจเตเดจเดคเต†เดฒเตเดฒเดพเด‚ เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต‡เดคเดฟเดจเตเดฑเต† เดฎเตˆเด•เตเดฐเต‹เดซเต‹เดฃเดฟเดฒเต‡เด•เตเด•เต เดฑเต†เด•เตเด•เต‹เตผเดกเต เดšเต†เดฏเตเดฏเดพเตป เดคเตเดŸเด™เตเด™เตเด‚. เดˆ เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดตเดพเด•เตเด•เต "เดฑเต†เด•เตเด•เต‹เตผเดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเต...". เดจเดฟเด™เตเด™เตพ เดจเดฟเดถเดฌเตเดฆเดจเดพเดฏเดพเดฒเตเดŸเตป, เด’เดฐเต เดธเดจเตเดฆเต‡เดถเด‚ เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเต‹เดŸเต† เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเด‚เด—เต เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด•เดฎเดพเดฏเดฟ เดจเดฟเตผเดคเตเดคเตเด‚"เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด•เดฎเดพเดฏเดฟ เดจเดฟเตผเดคเตเดคเตเด•โ€ฆ"เดจเดฟเด™เตเด™เตพ เดคเตเดฐเต†เดทเต‹เตพเดกเต เดฒเต†เดตเดฒเดฟเตฝ เดชเดฐเต€เด•เตเดทเดฃเด‚ เดจเดŸเดคเตเดคเต‡เดฃเตเดŸเดฟ เดตเดจเตเดจเต‡เด•เตเด•เดพเด‚.

เดˆ เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เตพ เดŽเด™เตเด™เดจเต† เดŽเดดเตเดคเดพเดฎเต†เดจเตเดจเต เดžเด™เตเด™เตพ เดชเด เดฟเดšเตเดšเต. เดจเดฟเด™เตเด™เตพ เดถเตเดฐเดฆเตเดงเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เดพเด‚, nash_filter_process() เดซเด‚เด—เตเดทเตป เดกเดพเดฑเตเดฑ เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เตƒเดคเตเดฐเดฟเดฎเดคเตเดตเด‚ เดจเดŸเดคเตเดคเตเดจเตเดจเต. เด‰เดฆเดพเดนเดฐเดฃเด‚ เดตเดฟเดฆเตเดฏเดพเดญเตเดฏเดพเดธเดชเดฐเดฎเดพเดฏเดคเดฟเดจเดพเตฝ, เดกเดพเดฑเตเดฑ เดฌเตเดฒเต‹เด•เตเด•เตเด•เตพ เด•เตˆเด•เดพเดฐเตเดฏเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดฎเต€เดกเดฟเดฏ เดธเตเดŸเตเดฐเต€เดฎเดฑเดฟเดจเตเดฑเต† เดเดฑเตเดฑเดตเตเด‚ เด•เตเดฑเดžเตเดž เด•เดดเดฟเดตเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต.

เด…เดŸเตเดคเตเดคเดคเต เดฒเต‡เด–เดจเด‚ เดธเดจเตเดฆเต‡เดถ เด•เตเดฏเต‚เดฏเดฟเด‚เด—เตเด‚ เดธเดจเตเดฆเต‡เดถ เดฎเดพเดจเต‡เดœเตเดฎเต†เดจเตเดฑเต เดชเตเดฐเดตเตผเดคเตเดคเดจเด™เตเด™เดณเตเด‚ เดžเด™เตเด™เตพ เดจเต‹เด•เตเด•เตเด‚. เด•เต‚เดŸเตเดคเตฝ เดธเด™เตเด•เต€เตผเดฃเตเดฃเดฎเดพเดฏ เดตเดฟเดตเดฐ เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เต เด‰เดณเตเดณ เดซเดฟเตฝเดŸเตเดŸเดฑเตเด•เตพ เดตเดฟเด•เดธเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เด‡เดคเต เดญเดพเดตเดฟเดฏเดฟเตฝ เดธเดนเดพเดฏเดฟเด•เตเด•เตเด‚.

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•