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 */

เจนเฉเจฃ เจคเฉเจธเฉ€เจ‚ เจธเจฐเฉ‹เจค เจซเจพเจˆเจฒ 'เจคเฉ‡ เจœเจพ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจŸเจฟเฉฑเจชเจฃเฉ€เจ†เจ‚ เจตเจพเจฒเฉ‡ เจซเจฟเจฒเจŸเจฐ เจฒเจˆ เจธเจฐเฉ‹เจค เจ•เฉ‹เจก เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเจ–เจพเจ‡เจ† เจ—เจฟเจ† เจนเฉˆเฅค เจซเจฟเจฒเจŸเจฐ เจตเจฟเจงเฉ€เจ†เจ‚ เจ…เจคเฉ‡ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจซเจฟเจฒเจŸเจฐ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เฉฑเจฅเฉ‡ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆเฅค เจซเจฟเจฐ เจขเฉฐเจ—เจพเจ‚ เจ…เจคเฉ‡ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจฆเฉ‡ เจนเจตเจพเจฒเฉ‡ เจจเจฟเจฐเจฏเจพเจค เจขเจพเจ‚เจšเฉ‡ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ–เจพเจธ เจ•เฉเจฐเจฎ เจตเจฟเฉฑเจš เจฐเฉฑเจ–เฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจธเจพเจกเจพ_เจซเจฟเจฒเจŸเจฐ_เจกเฉˆเจธเจ•. เจœเฉ‹ เจ•เจฟ เจฎเฉ€เจกเฉ€เจ† เจธเจŸเฉเจฐเฉ€เจฎเจฐ เจฆเฉเจ†เจฐเจพ เจกเฉ‡เจŸเจพ เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— เจตเจฐเจ•เจซเจฒเฉ‹ เจตเจฟเฉฑเจš เจ‡เจธ เจ•เจฟเจธเจฎ เจฆเฉ‡ เจซเจฟเจฒเจŸเจฐเจพเจ‚ เจจเฉ‚เฉฐ "เจ‡เจฎเจชเจฒเจพเจ‚เจŸ" เจ•เจฐเจจ เจฒเจˆ เจตเจฐเจคเจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค

/* ะคะฐะนะป 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เจœเฉ‹ เจ•เจฟ เจ‡เฉฑเจ• เจซเจพเจˆเจฒ เจจเฉ‚เฉฐ เจฒเจฟเจ–เจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจฟเจธเจจเฉ‚เฉฐ เจ•เจนเจฟเฉฐเจฆเฉ‡ เจนเจจ record.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

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹