เบเบฒเบ™เบชเบณเบซเบผเบงเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Mediastreamer2 VoIP. เบžเบฒเบเบ—เบต 10

เป€เบญเบเบฐเบชเบฒเบ™เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเปเบกเปˆเบ™เป€เบญเบปเบฒเบกเบฒเบˆเบฒเบเบ‚เบญเบ‡เบ‚เป‰เบญเบ เบŠเปˆเบญเบ‡ zen.

เปƒเบ™เบ—เบตเปˆเบชเบธเบ” เบšเบปเบ”เบ„เบงเบฒเบก เบžเบงเบเป€เบฎเบปเบฒเบชเป‰เบฒเบ‡เบชเบญเบ‡ intercom เบ—เบตเปˆเปเบฅเบเบ›เปˆเบฝเบ™เบชเบฑเบ™เบเบฒเบ™เบชเบฝเบ‡เบœเปˆเบฒเบ™เป€เบŠเบ”เบŠเบฑเบ™ RTP duplex. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบฎเบฝเบ™เบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เปเบฅเบฐเป€เบžเบตเปˆเบกเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ DIY เบเบฑเบš intercom DIY.

เบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบฅเบฑเบ‡เบžเบฑเบ”เบ—เบฐเบ™เบฒ plugin

เบเบฒเบ™เบชเบณเบซเบผเบงเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Mediastreamer2 VoIP. เบžเบฒเบเบ—เบต 10

Plugins เปƒเบ™ media streamer, เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบ™เบเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™เบญเบทเปˆเบ™เป†เบˆเปเบฒเบ™เบงเบ™เบซเบผเบฒเบ, เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป€เบžเบทเปˆเบญเบ‚เบฐเบซเบเบฒเบเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเป‚เบ”เบเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡ recompile media streamer เบ•เบปเบงเบ‚เบญเบ‡เบกเบฑเบ™เป€เบญเบ‡.

เป€เบžเบทเปˆเบญเปƒเบŠเป‰ plugin เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™, เบ—เปˆเบฒเบ™เปƒเบŠเป‰ เบ›เบฐเบเบญเบšเบ”เป‰เบงเบ เบ•เป‰เบญเบ‡เบกเบตเป„เบŸเบฅเปŒเบชเปˆเบงเบ™เบซเบปเบงเบ‚เบญเบ‡ plugin. เปƒเบ™เบ•เบปเบงเบ‚เบญเบ‡เป‚เบ›เบฅเปเบเบฅเบก, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบŸเบฑเบ‡เบŠเบฑเบ™ y ms_filter_register() เบฅเบปเบ‡เบ—เบฐเบšเบฝเบ™เบ•เบปเบงเบเบญเบ‡เปƒเบซเบกเปˆ. เบ•เบฒเบกเบ—เปเบฒเบกเบฐเบŠเบฒเบ”, เป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เปเบฅเบฐเปเบซเบผเปˆเบ‡ plugin เบ•เป‰เบญเบ‡เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบฅเบงเบšเบฅเบงเบกเปเบฅเบฐเบ›เบฐเบเบญเบšเป€เบ‚เบปเป‰เบฒเปƒเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเบ”เบฝเบง.

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เป€เบฎเบปเบฒเบซเบฑเบ™เป„เบ›เบซเบฒเบเบฒเบ™เบ‚เบฝเบ™ plugin. เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบฅเบฐ plugins เบชเบทเปˆเบกเบงเบ™เบŠเบปเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบฒเบก canon เบ—เบปเปˆเบงเป„เบ›เปƒเบ™เบเบฒเบ™เบ‚เบฝเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบ‚เบปเบฒ, เป€เบŠเบดเปˆเบ‡เป€เบฎเบฑเบ”เปƒเบซเป‰เบกเบฑเบ™เบ‡เปˆเบฒเบเบ‚เบถเป‰เบ™เบซเบผเบฒเบเบ—เบตเปˆเบˆเบฐเป€เบ‚เบปเป‰เบฒเปƒเบˆเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ‚เบญเบ‡เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ•เปเปˆเป„เบ›เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบชเบถเบเบชเบฒ. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ•เปเปˆเป„เบ›, เป€เบžเบทเปˆเบญเบšเปเปˆเปƒเบซเป‰เบซเบผเบฒเบเบซเบ™เปˆเบงเบเบ‡เบฒเบ™, เบ‚เป‰เบญเบเบˆเบฐเป‚เบ—เบซเบฒเบ•เบปเบงเบเบญเบ‡ plugins.

เบชเบปเบกเบกเบธเบ”เบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ•เบปเบงเบเบญเบ‡เปƒเบซเบกเปˆเบ—เบตเปˆเป€เบญเบตเป‰เบ™เบงเปˆเบฒ NASH_FILTR. เบกเบฑเบ™เบˆเบฐเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบ - เป„เบ”เป‰เบฎเบฑเบšเบ•เบฑเบ™เบˆเบฒเบเบงเบฑเบ”เบชเบฐเบ”เบธเบ›เป‰เบญเบ™เบ”เบฝเบงเบ‚เบญเบ‡เบกเบฑเบ™เปเบฅเบฐเบชเบปเปˆเบ‡เบกเบฑเบ™เป„เบ›เบซเบฒเบซเป‰เบฒเบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡เบกเบฑเบ™. เบกเบฑเบ™เบเบฑเบ‡เบˆเบฐเบชเป‰เบฒเบ‡เป€เบซเบ”เบเบฒเบ™เบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบซเบผเบฒเบเบเปˆเบงเบฒเบซเป‰เบฒเบ•เบฑเบ™เบ—เบตเปˆเบกเบตเบฅเบฐเบ”เบฑเบšเบชเบฑเบ™เบเบฒเบ™เบ•เปˆเปเบฒเบเบงเปˆเบฒเป€เบเบ™เบ—เบตเปˆเบเปเบฒเบ™เบปเบ”เป„เบงเป‰เบœเปˆเบฒเบ™เบกเบฑเบ™, เปเบฅเบฐเบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบซเบผเบฒเบเบเปˆเบงเบฒเบซเป‰เบฒเบ•เบฑเบ™เบ—เบตเปˆเบกเบตเบฅเบฐเบ”เบฑเบšเบชเบฑเบ™เบเบฒเบ™เบชเบนเบ‡เบเบงเปˆเบฒเป€เบเบ™เบœเปˆเบฒเบ™เบกเบฑเบ™, เบกเบฑเบ™เบˆเบฐเบชเป‰เบฒเบ‡เป€เบซเบ”เบเบฒเบ™.

เป€เบเบ™เบˆเบฐเบ–เบทเบเบเปเบฒเบ™เบปเบ”เป‚เบ”เบเปƒเบŠเป‰เบงเบดเบ—เบตเบเบฒเบ™เบเบญเบ‡. เบงเบดเบ—เบตเบเบฒเบ™เบ—เบตเบชเบญเบ‡เปเบฅเบฐเบ—เบตเบชเบฒเบกเบˆเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰ / เบซเป‰เบฒเบก passage เบ‚เบญเบ‡เบ•เบฑเบ™เป„เบ›เบซเบฒเบ—เบฒเบ‡เบญเบญเบ.

เปƒเบซเป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™. เป€เบกเบทเปˆเบญเบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบเป„เบŸเบฅเปŒ header. เปƒเบ™เปเบ–เบงเบ—เปเบฒเบญเบดเบ”เบกเบฑเบ™เบ„เบงเบ™เบˆเบฐเบ›เบฐเบเบญเบšเบกเบตเป„เบŸเบฅเปŒ 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 */

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบเป‰เบฒเบเป„เบ›เบ—เบตเปˆเป„เบŸเบฅเปŒเปเบซเบผเปˆเบ‡. เบฅเบฐเบซเบฑเบ”เปเบซเบผเปˆเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบกเบตเบ„เปเบฒเป€เบซเบฑเบ™เปเบกเปˆเบ™เบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰. เบงเบดเบ—เบตเบเบฒเบ™เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบฅเบฐเบซเบ™เป‰เบฒเบ—เบตเปˆเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบเปเบฒเบ™เบปเบ”เป„เบงเป‰เปเบกเปˆเบ™เบ–เบทเบเบเปเบฒเบ™เบปเบ”เบขเบนเปˆเบ—เบตเปˆเบ™เบตเป‰. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบเบฒเบ™เบญเป‰เบฒเบ‡เบญเบตเบ‡เป€เบ–เบดเบ‡เบงเบดเบ—เบตเบเบฒเบ™เปเบฅเบฐเบซเบ™เป‰เบฒเบ—เบตเปˆเบ–เบทเบเบˆเบฑเบ”เปƒเบชเปˆเปƒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเปเบ™เปˆเบ™เบญเบ™เปƒเบ™เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ—เบตเปˆเบชเบปเปˆเบ‡เบญเบญเบ our_filter_desc. เป€เบŠเบดเปˆเบ‡เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป‚เบ”เบ media streamer เป€เบžเบทเปˆเบญ "implant" เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ‚เบญเบ‡เบ›เบฐเป€เบžเบ”เบ™เบตเป‰เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ›เบฐเบกเบงเบ™เบœเบปเบ™เบ‚เปเป‰เบกเบนเบ™.

/* ะคะฐะนะป 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)

เบ”เบฝเบงเบ™เบตเป‰, เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบŠเบฑเบเบŠเป‰เบฒ, เปƒเบซเป‰เปƒเบŠเป‰เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเปƒเบ™ intercom เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป€เบฎเบฑเบ”เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰. เบฎเบนเบšเบžเบฒเบšเบซเบปเบงเบ‚เปเป‰เบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เปเบœเบ™เบงเบฒเบ”เบ‚เบญเบ‡ intercom เบ”เบฑเบ”เปเบเป‰.
เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบžเบฑเบ™เบฅเบฐเบ™เบฒเบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเป€เบฎเบฑเบ”เบ”เป‰เบงเบเบกเบทเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเปƒเบ™เบ—เบฒเบ‡เบ—เบตเปˆเบชเบปเบ”เปƒเบชเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐ. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ—เปˆเบฒเบ™เบˆเบฐเบŠเบญเบเบซเบฒเบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเปƒเบ™เปเบœเบ™เบงเบฒเบ”เบ—เบฑเบ™เบ—เบต.

เป€เบ„เบทเปˆเบญเบ‡เบšเบฑเบ™เบ—เบถเบเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เป„เบ”เป‰เบ–เบทเบเป€เบžเบตเปˆเบกเปƒเบชเปˆเบงเบปเบ‡เบˆเบญเบ™, เป€เบŠเบดเปˆเบ‡เบ‚เบฝเบ™เบชเบฑเบ™เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป„เบ›เบซเบฒเป„เบŸเบฅเปŒ wav. เบ”เบฑเปˆเบ‡เบ—เบตเปˆเป„เบ”เป‰เบงเบฒเบ‡เปเบœเบ™เป„เบงเป‰, เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบซเบผเบตเบเบฅเปˆเบฝเบ‡เบเบฒเบ™เบขเบธเบ”เบเบฒเบ™เบ‚เบฝเบ™เบ„เบณเป€เบงเบปเป‰เบฒเปƒเบ™เป„เบŸเบฅเปŒเป„เบ”เป‰. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบเบฒเบ™เบซเบผเบธเบ”เบœเปˆเบญเบ™เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เบกเบฑเบ™.
เปƒเบ™เบ•เบญเบ™เบ•เบปเป‰เบ™เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบก, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบญเบฐเบ—เบดเบšเบฒเบ algorithm เบ‚เบญเบ‡เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡. เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเบ•เบปเป‰เบ™เบ•เปเบˆเบฑเบ”เบเบฒเบ™เบเบฑเบšเป€เบซเบ”เบเบฒเบ™เบ—เบตเปˆเบกเบฑเบ™เบชเป‰เบฒเบ‡. เบ–เป‰เบฒเป€เบซเบ”เบเบฒเบ™เบกเบตเบ—เบธเบ‡ "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 <ั‚ัƒั‚ ะฐะดั€ะตั ะฟะตั€ะฒะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ>

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบตเป‰, เบ„เบญเบกเบžเบดเบงเป€เบ•เบตเบ—เปเบฒเบญเบดเบ”เบˆเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบšเบฑเบ™เบ—เบถเบเบ—เบธเบเบชเบดเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เป€เบงเบปเป‰เบฒเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™ microphone เบ‚เบญเบ‡เบ—เบตเบชเบญเบ‡. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰, เบ„เปเบฒเบงเปˆเบฒ "เบเบณเบฅเบฑเบ‡เบšเบฑเบ™เบ—เบถเบ...". เบ—เบฑเบ™เบ—เบตเบ—เบตเปˆเบ—เปˆเบฒเบ™เบกเบดเบ”เบ‡เบฝเบš, เบเบฒเบ™เบšเบฑเบ™เบ—เบถเบเบˆเบฐเบ–เบทเบเบขเบธเบ”เป„เบงเป‰เบŠเบปเปˆเบงเบ„เบฒเบงเบžเป‰เบญเบกเบเบฑเบšเบ‚เปเป‰เบ„เบงเบฒเบกเบ—เบตเปˆเบชเบฐเปเบ”เบ‡เบ‚เบถเป‰เบ™"เบขเบธเบ”โ€‹เบŠเบปเปˆเบงโ€‹เบ„เบฒเบงโ€ฆ"เบ—เปˆเบฒเบ™เบญเบฒเบ”เบˆเบฐเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบ—เบปเบ”เบฅเบญเบ‡เบเบฑเบšเบฅเบฐเบ”เบฑเบšเป€เบเบ™.

เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฝเบ™เบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡. เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบญเบฒเบ”เบˆเบฐเป„เบ”เป‰เบชเบฑเบ‡เป€เบเบ”เป€เบซเบฑเบ™, เบŸเบฑเบ‡เบŠเบฑเบ™ nash_filter_process() เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบซเบกเบนเบ™เปƒเบŠเป‰เบเบฑเบšเบ•เบฑเบ™เบ‚เปเป‰เบกเบนเบ™. เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบ•เบปเบงเบขเปˆเบฒเบ‡เปเบกเปˆเบ™เบเบฒเบ™เบชเบถเบเบชเบฒ, เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบ•เปเบฒเปˆเบชเบธเบ”เบ—เบตเปˆเบ‚เบญเบ‡ media streamer เบชเปเบฒเบฅเบฑเบš manipulating blocks เบ‚เปเป‰เบกเบนเบ™เป„เบ”เป‰เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰.

เบ•เปเปˆเป„เบ› เบšเบปเบ”เบ„เบงเบฒเบก เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบˆเบฐโ€‹เป€เบšเบดเปˆเบ‡โ€‹เบเบฒเบ™โ€‹เบˆเบฑเบ”โ€‹เปเบ–เบงโ€‹เบ‚เปเป‰โ€‹เบ„เบงเบฒเบกโ€‹เปเบฅเบฐโ€‹เบซเบ™เป‰เบฒโ€‹เบ—เบตเปˆโ€‹เบเบฒเบ™โ€‹เบ„เบธเป‰เบกโ€‹เบ„เบญเบ‡โ€‹เบ‚เปเป‰โ€‹เบ„เบงเบฒเบกโ€‹. เบ™เบตเป‰เบˆเบฐเบŠเปˆเบงเบเปƒเบซเป‰เปƒเบ™เบญเบฐเบ™เบฒเบ„เบปเบ”เป€เบžเบทเปˆเบญเบžเบฑเบ”เบ—เบฐเบ™เบฒเบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเบกเบตเบเบฒเบ™เบ›เบธเบ‡เปเบ•เปˆเบ‡เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบชเบฑเบšเบชเบปเบ™เบซเบผเบฒเบ.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™