ΠΠ°ΡΠ΅ΡΠΈΠ°Π» ΡΡΠ°ΡΡΠΈ Π²Π·ΡΡ Ρ ΠΌΠΎΠ΅Π³ΠΎ
Π ΠΏΡΠΎΡΠ»ΠΎΠΉ
Π Π°Π·ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½
ΠΠ»Π°Π³ΠΈΠ½Ρ Π² ΠΌΠ΅Π΄ΠΈΠ°ΡΡΡΠΈΠΌΠ΅ΡΠ΅, ΠΊΠ°ΠΊ ΠΈ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ Π΄ΡΡΠ³ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°Ρ , ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π° Π±Π΅Π· Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΠ΅ΡΠ΅ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΌΠ΅Π΄ΠΈΠ°ΡΡΡΠΈΠΌΠ΅ΡΠ°.
Π§ΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΠ»Π°Π³ΠΈΠ½ Π² ΡΠ²ΠΎΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅, Π²Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ include Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΠΏΠ»Π°Π³ΠΈΠ½Π°. Π ΡΠ΅Π»Π΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ Ρ 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_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
, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ Π·Π°ΠΏΠΈΡΡ Π² ΡΠ°ΠΉΠ» Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ 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);
}
ΠΠ·-Π·Π° ΡΠΎΠ³ΠΎ, ΡΡΠΎ Ρ Π½Π°Ρ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈΡΡ ΡΠ°ΠΉΠ»Ρ ΠΈ Π±ΡΠ»Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° math, ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°Ρ ΡΡΡΠΎΠΊΠ° Π΄Π»Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, ΡΡΠ»ΠΎΠΆΠ½ΠΈΠ»Π°ΡΡ, ΠΈ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:
$ 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 <ΡΡΡ Π°Π΄ΡΠ΅Ρ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ°>
ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΊΠΎΠΌΠΏΡΡΡΠ΅Ρ Π½Π°ΡΠ½Π΅Ρ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡ Π²ΡΠ΅, ΡΡΠΎ Π²Ρ ΡΠΊΠ°ΠΆΠ΅ΡΠ΅ Π² ΠΌΠΈΠΊΡΠΎΡΠΎΠ½ Π²ΡΠΎΡΠΎΠ³ΠΎ. ΠΡΠΈ ΡΡΠΎΠΌ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΎ ΡΠ»ΠΎΠ²ΠΎ "Recording…". ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ Π²Ρ Π·Π°ΠΌΠΎΠ»ΡΠΈΡΠ΅ Π·Π°ΠΏΠΈΡΡ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΡΠ°Π²Π»Π΅Π½Π° Π½Π° ΠΏΠ°ΡΠ·Ρ Ρ Π²ΡΠ²ΠΎΠ΄ΠΎΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ "Pause…". ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΏΠΎΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°ΡΡ Ρ ΡΡΠΎΠ²Π½Π΅ ΠΏΠΎΡΠΎΠ³Π°.
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ Π½Π°ΡΡΠΈΠ»ΠΈΡΡ ΠΏΠΈΡΠ°ΡΡ ΡΠΈΠ»ΡΡΡΡ. ΠΠ°ΠΊ Π²Ρ ΠΌΠΎΠ³Π»ΠΈ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, Π² ΡΡΠ½ΠΊΡΠΈΠΈ nash_filter_process() Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΠΈ Ρ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ Π΄Π°Π½Π½ΡΡ . ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΡΠ΅Π±Π½ΡΠΉ, ΡΠΎ ΡΠ°ΠΌ Π±ΡΠ» Π·Π°Π΄Π΅ΠΉΡΡΠ²ΠΎΠ²Π°Π½ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΠΌΠ΅Π΄ΠΈΠ°ΡΡΡΠΈΠΌΠ΅ΡΠ° ΠΏΠΎ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΡΠΌ Ρ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ Π΄Π°Π½Π½ΡΡ .
Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com