Changeset 228
- Timestamp:
- Feb 25, 2006 2:04:42 AM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 8 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/os.h
r106 r228 891 891 */ 892 892 #if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0 893 894 /**895 * This structure represents high resolution (64bit) time value. The time896 * values represent time in cycles, which is retrieved by calling897 * #pj_get_timestamp().898 */899 typedef union pj_timestamp900 {901 struct902 {903 #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0904 pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */905 pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */906 #else907 pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */908 pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */909 #endif910 } u32; /**< The 64-bit value as two 32-bit values. */911 912 #if PJ_HAS_INT64913 pj_uint64_t u64; /**< The whole 64-bit value, where available. */914 #endif915 } pj_timestamp;916 917 893 918 894 /** -
pjproject/trunk/pjlib/include/pj/types.h
r182 r228 121 121 }; 122 122 123 /** 124 * This structure represents high resolution (64bit) time value. The time 125 * values represent time in cycles, which is retrieved by calling 126 * #pj_get_timestamp(). 127 */ 128 typedef union pj_timestamp 129 { 130 struct 131 { 132 #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0 133 pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */ 134 pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */ 135 #else 136 pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */ 137 pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */ 138 #endif 139 } u32; /**< The 64-bit value as two 32-bit values. */ 140 141 #if PJ_HAS_INT64 142 pj_uint64_t u64; /**< The whole 64-bit value, where available. */ 143 #endif 144 } pj_timestamp; 145 146 123 147 124 148 /** -
pjproject/trunk/pjmedia/build/pjmedia.dsp
r222 r228 162 162 # Begin Source File 163 163 164 SOURCE=..\src\pjmedia\silencedet.c 165 # End Source File 166 # Begin Source File 167 164 168 SOURCE=..\src\pjmedia\stream.c 165 # End Source File166 # Begin Source File167 168 SOURCE=..\src\pjmedia\vad.c169 169 # End Source File 170 170 # End Group … … 238 238 # Begin Source File 239 239 240 SOURCE=..\include\pjmedia\silencedet.h 241 # End Source File 242 # Begin Source File 243 240 244 SOURCE=..\include\pjmedia\sound.h 241 245 # End Source File … … 247 251 248 252 SOURCE=..\include\pjmedia\types.h 249 # End Source File250 # Begin Source File251 252 SOURCE=..\include\pjmedia\vad.h253 253 # End Source File 254 254 # Begin Source File -
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r188 r228 16 16 * along with this program; if not, write to the Free Software 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 /* 20 * Based on implementation kindly contributed by Switchlab, Ltd. 18 21 */ 19 22 #ifndef __PJMEDIA_JBUF_H__ -
pjproject/trunk/pjmedia/include/pjmedia/silencedet.h
r222 r228 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #ifndef __PJMEDIA_ VAD_H__20 #define __PJMEDIA_ VAD_H__19 #ifndef __PJMEDIA_SILENCE_DET_H__ 20 #define __PJMEDIA_SILENCE_DET_H__ 21 21 22 22 23 23 /** 24 * @file vad.h25 * @brief Simple, adaptive silence detector.24 * @file silencedet.h 25 * @brief Adaptive silence detector. 26 26 */ 27 27 #include <pjmedia/types.h> … … 31 31 32 32 /** 33 * @see pjmedia_vad33 * Opaque declaration for silence detector. 34 34 */ 35 typedef struct pjmedia_ vad pjmedia_vad;35 typedef struct pjmedia_silence_det pjmedia_silence_det; 36 36 37 37 … … 42 42 * 43 43 * @param pool Pool for allocating the structure. 44 * @param p_ vad Pointer to receive the VADinstance.44 * @param p_sd Pointer to receive the silence detector instance. 45 45 * 46 46 * @return PJ_SUCCESS on success. 47 47 */ 48 PJ_DECL(pj_status_t) pjmedia_ vad_create( pj_pool_t *pool,49 pjmedia_vad **p_vad );48 PJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 49 pjmedia_silence_det **p_sd ); 50 50 51 51 52 52 /** 53 * Set the vad to operate in adaptive mode.53 * Set the sd to operate in adaptive mode. 54 54 * 55 * @param vad The vad56 * @param frame_size Number of samplseper frame.55 * @param sd The silence detector 56 * @param frame_size Number of samples per frame. 57 57 * 58 * @return 58 * @return PJ_SUCCESS on success. 59 59 */ 60 PJ_DECL(pj_status_t) pjmedia_ vad_set_adaptive( pjmedia_vad *vad,61 unsigned frame_size);60 PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 61 unsigned frame_size); 62 62 63 63 64 64 /** 65 * Set the vad to operate in fixed threshold mode.65 * Set the sd to operate in fixed threshold mode. 66 66 * 67 * @param vad The vad67 * @param sd The silence detector 68 68 * @param frame_size Number of samplse per frame. 69 69 * @param threshold The silence threshold. … … 71 71 * @return PJ_SUCCESS on success. 72 72 */ 73 PJ_DECL(pj_status_t) pjmedia_ vad_set_fixed( pjmedia_vad *vad,74 unsigned frame_size,75 unsigned threshold );73 PJ_DECL(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 74 unsigned frame_size, 75 unsigned threshold ); 76 76 77 77 /** 78 * Disable the vad.78 * Disable the silence detector. 79 79 * 80 * @param vad The vad80 * @param sd The silence detector 81 81 * 82 82 * @return PJ_SUCCESS on success. 83 83 */ 84 PJ_DECL(pj_status_t) pjmedia_ vad_disable( pjmedia_vad *vad );84 PJ_DECL(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd ); 85 85 86 86 … … 94 94 * divided by number of samples. 95 95 */ 96 PJ_DECL(pj_int32_t) pjmedia_ vad_calc_avg_signal( const pj_int16_t samples[],97 pj_size_t count );96 PJ_DECL(pj_int32_t) pjmedia_silence_det_calc_avg_signal( const pj_int16_t samples[], 97 pj_size_t count ); 98 98 99 99 … … 101 101 * Perform voice activity detection on the given input samples. 102 102 * 103 * @param vad The VADinstance.103 * @param sd The silence detector instance. 104 104 * @param samples Pointer to 16-bit PCM input samples. 105 105 * @param count Number of samples in the input. … … 109 109 * @return PJ_SUCCESS on success. 110 110 */ 111 PJ_DECL(pj_bool_t) pjmedia_ vad_detect_silence( pjmedia_vad *vad,112 const pj_int16_t samples[],113 pj_size_t count,114 pj_int32_t *p_level);111 PJ_DECL(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 112 const pj_int16_t samples[], 113 pj_size_t count, 114 pj_int32_t *p_level); 115 115 116 116 117 117 PJ_END_DECL 118 118 119 #endif /* __PJMEDIA_ VAD_H__ */119 #endif /* __PJMEDIA_SILENCE_DET_H__ */ 120 120 -
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r224 r228 18 18 */ 19 19 #include <pjmedia/conference.h> 20 #include <pjmedia/ vad.h>20 #include <pjmedia/silencedet.h> 21 21 #include <pjmedia/stream.h> 22 22 #include <pjmedia/sound.h> … … 56 56 int listener_cnt; /**< Number of listeners. */ 57 57 pj_bool_t *listeners; /**< Array of listeners. */ 58 pjmedia_ vad*vad; /**< VAD for this port. */58 pjmedia_silence_det *vad; /**< VAD for this port. */ 59 59 60 60 /* Tx buffer contains the frame to be "transmitted" to this port … … 140 140 141 141 /* Create and init vad. */ 142 status = pjmedia_ vad_create( pool, &conf_port->vad);142 status = pjmedia_silence_det_create( pool, &conf_port->vad); 143 143 if (status != PJ_SUCCESS) 144 144 return status; 145 145 146 pjmedia_ vad_set_adaptive(conf_port->vad, conf->samples_per_frame);146 pjmedia_silence_det_set_adaptive(conf_port->vad, conf->samples_per_frame); 147 147 148 148 … … 739 739 740 740 /* Do we have signal? */ 741 silence = pjmedia_ vad_detect_silence(conf_port->vad,742 output,743 conf->samples_per_frame,744 &level);741 silence = pjmedia_silence_det_detect_silence(conf_port->vad, 742 output, 743 conf->samples_per_frame, 744 &level); 745 745 746 746 /* Skip if we don't have signal. */ … … 790 790 frame.buf = NULL; 791 791 frame.size = 0; 792 792 793 793 if (conf_port->port) 794 794 pjmedia_port_put_frame(conf_port->port, &frame); -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r188 r228 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 /* 20 * Based on implementation kindly contributed by Switchlab, Ltd. 21 */ 19 22 #include <pjmedia/jbuf.h> 20 23 #include <pjmedia/errno.h> -
pjproject/trunk/pjmedia/src/pjmedia/silencedet.c
r222 r228 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #include <pjmedia/ vad.h>19 #include <pjmedia/silencedet.h> 20 20 #include <pjmedia/errno.h> 21 21 #include <pj/assert.h> … … 24 24 25 25 26 #define THIS_FILE " vad.c"27 28 typedef enum pjmedia_ vad_mode {26 #define THIS_FILE "silencedet.c" 27 28 typedef enum pjmedia_silence_det_mode { 29 29 VAD_MODE_NONE, 30 30 VAD_MODE_FIXED, 31 31 VAD_MODE_ADAPTIVE 32 } pjmedia_ vad_mode;32 } pjmedia_silence_det_mode; 33 33 34 34 35 35 /** 36 * This structure holds the vadstate.36 * This structure holds the silence detector state. 37 37 */ 38 struct pjmedia_ vad38 struct pjmedia_silence_det 39 39 { 40 40 int mode; /**< VAD mode. */ … … 60 60 61 61 62 PJ_DEF(pj_status_t) pjmedia_ vad_create( pj_pool_t *pool,63 pjmedia_vad **p_vad)64 { 65 pjmedia_ vad *vad;66 67 PJ_ASSERT_RETURN(pool && p_ vad, PJ_EINVAL);68 69 vad = pj_pool_zalloc(pool, sizeof(struct pjmedia_vad));70 71 vad->weakest_signal = 0xFFFFFFFFUL;72 vad->loudest_silence = 0;73 vad->signal_cnt = 0;74 vad->silence_cnt = 0;62 PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 63 pjmedia_silence_det **p_sd) 64 { 65 pjmedia_silence_det *sd; 66 67 PJ_ASSERT_RETURN(pool && p_sd, PJ_EINVAL); 68 69 sd = pj_pool_zalloc(pool, sizeof(struct pjmedia_silence_det)); 70 71 sd->weakest_signal = 0xFFFFFFFFUL; 72 sd->loudest_silence = 0; 73 sd->signal_cnt = 0; 74 sd->silence_cnt = 0; 75 75 76 76 /* Restart in adaptive, silent mode */ 77 vad->in_talk = PJ_FALSE;78 pjmedia_ vad_set_adaptive( vad, 160 );79 80 *p_ vad = vad;81 return PJ_SUCCESS; 82 } 83 84 PJ_DEF(pj_status_t) pjmedia_ vad_set_adaptive( pjmedia_vad *vad,85 unsigned frame_size)86 { 87 PJ_ASSERT_RETURN( vad && frame_size, PJ_EINVAL);88 89 vad->frame_size = frame_size;90 vad->mode = VAD_MODE_ADAPTIVE;91 vad->min_signal_cnt = 10;92 vad->min_silence_cnt = 64;93 vad->recalc_cnt = 250;94 vad->cur_threshold = 20;95 96 return PJ_SUCCESS; 97 } 98 99 PJ_DEF(pj_status_t) pjmedia_ vad_set_fixed( pjmedia_vad *vad,100 unsigned frame_size,101 unsigned threshold )102 { 103 PJ_ASSERT_RETURN( vad && frame_size, PJ_EINVAL);104 105 vad->mode = VAD_MODE_FIXED;106 vad->frame_size = frame_size;107 vad->cur_threshold = threshold;108 109 return PJ_SUCCESS; 110 } 111 112 PJ_DEF(pj_status_t) pjmedia_ vad_disable( pjmedia_vad *vad )113 { 114 PJ_ASSERT_RETURN( vad, PJ_EINVAL);115 116 vad->mode = VAD_MODE_NONE;117 118 return PJ_SUCCESS; 119 } 120 121 122 PJ_DEF(pj_int32_t) pjmedia_ vad_calc_avg_signal(const pj_int16_t samples[],123 pj_size_t count)77 sd->in_talk = PJ_FALSE; 78 pjmedia_silence_det_set_adaptive( sd, 160 ); 79 80 *p_sd = sd; 81 return PJ_SUCCESS; 82 } 83 84 PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 85 unsigned frame_size) 86 { 87 PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 88 89 sd->frame_size = frame_size; 90 sd->mode = VAD_MODE_ADAPTIVE; 91 sd->min_signal_cnt = 10; 92 sd->min_silence_cnt = 64; 93 sd->recalc_cnt = 250; 94 sd->cur_threshold = 20; 95 96 return PJ_SUCCESS; 97 } 98 99 PJ_DEF(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 100 unsigned frame_size, 101 unsigned threshold ) 102 { 103 PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 104 105 sd->mode = VAD_MODE_FIXED; 106 sd->frame_size = frame_size; 107 sd->cur_threshold = threshold; 108 109 return PJ_SUCCESS; 110 } 111 112 PJ_DEF(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd ) 113 { 114 PJ_ASSERT_RETURN(sd, PJ_EINVAL); 115 116 sd->mode = VAD_MODE_NONE; 117 118 return PJ_SUCCESS; 119 } 120 121 122 PJ_DEF(pj_int32_t) pjmedia_silence_det_calc_avg_signal(const pj_int16_t samples[], 123 pj_size_t count) 124 124 { 125 125 pj_uint32_t sum = 0; … … 141 141 } 142 142 143 PJ_DEF(pj_bool_t) pjmedia_ vad_detect_silence( pjmedia_vad *vad,144 const pj_int16_t samples[],145 pj_size_t count,146 pj_int32_t *p_level)143 PJ_DEF(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 144 const pj_int16_t samples[], 145 pj_size_t count, 146 pj_int32_t *p_level) 147 147 { 148 148 pj_uint32_t level; … … 150 150 151 151 /* Always return false if VAD is disabled */ 152 if ( vad->mode == VAD_MODE_NONE) {152 if (sd->mode == VAD_MODE_NONE) { 153 153 if (p_level) 154 154 *p_level = -1; … … 157 157 158 158 /* Calculate average signal level. */ 159 level = pjmedia_ vad_calc_avg_signal(samples, count);159 level = pjmedia_silence_det_calc_avg_signal(samples, count); 160 160 161 161 /* Report to caller, if required. */ … … 167 167 168 168 /* Do we have signal? */ 169 have_signal = level > vad->cur_threshold;169 have_signal = level > sd->cur_threshold; 170 170 171 171 /* We we're in transition between silence and signel, increment the … … 173 173 * frames. 174 174 */ 175 if ( vad->in_talk != have_signal) {175 if (sd->in_talk != have_signal) { 176 176 unsigned limit; 177 177 178 vad->cur_cnt++;179 180 limit = ( vad->in_talk ? vad->min_silence_cnt :181 vad->min_signal_cnt);182 183 if ( vad->cur_cnt > limit) {178 sd->cur_cnt++; 179 180 limit = (sd->in_talk ? sd->min_silence_cnt : 181 sd->min_signal_cnt); 182 183 if (sd->cur_cnt > limit) { 184 184 185 185 /* Swap mode */ 186 vad->in_talk = !vad->in_talk;186 sd->in_talk = !sd->in_talk; 187 187 188 188 /* Restart adaptive cur_threshold measurements */ 189 vad->weakest_signal = 0xFFFFFFFFUL;190 vad->loudest_silence = 0;191 vad->signal_cnt = 0;192 vad->silence_cnt = 0;189 sd->weakest_signal = 0xFFFFFFFFUL; 190 sd->loudest_silence = 0; 191 sd->signal_cnt = 0; 192 sd->silence_cnt = 0; 193 193 } 194 194 195 195 } else { 196 196 /* Reset frame count */ 197 vad->cur_cnt = 0;198 } 199 200 /* For fixed threshold vad, everything is done. */201 if ( vad->mode == VAD_MODE_FIXED) {202 return ! vad->in_talk;197 sd->cur_cnt = 0; 198 } 199 200 /* For fixed threshold sd, everything is done. */ 201 if (sd->mode == VAD_MODE_FIXED) { 202 return !sd->in_talk; 203 203 } 204 204 … … 206 206 /* Count the number of silent and signal frames and calculate min/max */ 207 207 if (have_signal) { 208 if (level < vad->weakest_signal)209 vad->weakest_signal = level;210 vad->signal_cnt++;208 if (level < sd->weakest_signal) 209 sd->weakest_signal = level; 210 sd->signal_cnt++; 211 211 } 212 212 else { 213 if (level > vad->loudest_silence)214 vad->loudest_silence = level;215 vad->silence_cnt++;213 if (level > sd->loudest_silence) 214 sd->loudest_silence = level; 215 sd->silence_cnt++; 216 216 } 217 217 … … 219 219 * silence/signal frames. 220 220 */ 221 if (( vad->signal_cnt + vad->silence_cnt) > vad->recalc_cnt) {221 if ((sd->signal_cnt + sd->silence_cnt) > sd->recalc_cnt) { 222 222 223 223 /* Adjust silence threshold by looking at the proportions of 224 224 * signal and silence frames. 225 225 */ 226 if ( vad->signal_cnt >= vad->recalc_cnt) {226 if (sd->signal_cnt >= sd->recalc_cnt) { 227 227 /* All frames where signal frames. 228 228 * Increase silence threshold. 229 229 */ 230 vad->cur_threshold += (vad->weakest_signal - vad->cur_threshold)/4;230 sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4; 231 231 PJ_LOG(6,(THIS_FILE, "Vad cur_threshold increased to %d", 232 vad->cur_threshold));233 } 234 else if ( vad->silence_cnt >= vad->recalc_cnt) {232 sd->cur_threshold)); 233 } 234 else if (sd->silence_cnt >= sd->recalc_cnt) { 235 235 /* All frames where silence frames. 236 236 * Decrease silence threshold. 237 237 */ 238 vad->cur_threshold = (vad->cur_threshold+vad->loudest_silence)/2+1;238 sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1; 239 239 PJ_LOG(6,(THIS_FILE, "Vad cur_threshold decreased to %d", 240 vad->cur_threshold));240 sd->cur_threshold)); 241 241 } 242 242 else { … … 244 244 245 245 /* Adjust according to signal/silence proportions. */ 246 if ( vad->signal_cnt > vad->silence_cnt * 2)247 vad->cur_threshold++;248 else if ( vad->silence_cnt > vad->signal_cnt* 2)249 vad->cur_threshold--;246 if (sd->signal_cnt > sd->silence_cnt * 2) 247 sd->cur_threshold++; 248 else if (sd->silence_cnt > sd->signal_cnt* 2) 249 sd->cur_threshold--; 250 250 else 251 251 updated = PJ_FALSE; … … 254 254 PJ_LOG(6,(THIS_FILE, 255 255 "Vad cur_threshold updated to %d", 256 vad->cur_threshold));256 sd->cur_threshold)); 257 257 } 258 258 } 259 259 260 260 /* Reset. */ 261 vad->weakest_signal = 0xFFFFFFFFUL;262 vad->loudest_silence = 0;263 vad->signal_cnt = 0;264 vad->silence_cnt = 0;265 } 266 267 return ! vad->in_talk;268 } 269 261 sd->weakest_signal = 0xFFFFFFFFUL; 262 sd->loudest_silence = 0; 263 sd->signal_cnt = 0; 264 sd->silence_cnt = 0; 265 } 266 267 return !sd->in_talk; 268 } 269 -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r223 r228 117 117 118 118 119 /* RFC 2833 digit */ 120 static const char digitmap[16] = { '0', '1', '2', '3', 121 '4', '5', '6', '7', 122 '8', '9', '*', '#', 123 'A', 'B', 'C', 'D'}; 124 119 125 /* 120 126 * Print error. … … 231 237 stream->tx_dtmf_buf[0].start_ts = cur_ts; 232 238 pj_mutex_unlock(stream->jb_mutex); 233 } 239 240 if (stream->tx_dtmf_count) 241 PJ_LOG(5,(THIS_FILE,"Sending DTMF digit id %c", 242 digitmap[stream->tx_dtmf_buf[0].event])); 243 244 } else if (duration == 0) { 245 PJ_LOG(5,(THIS_FILE,"Sending DTMF digit id %c", 246 digitmap[digit->event])); 247 } 248 234 249 235 250 frame_out->size = 4; … … 368 383 const void *payload, unsigned payloadlen) 369 384 { 370 static const char digitmap[16] = { '0', '1', '2', '3',371 '4', '5', '6', '7',372 '8', '9', '*', '#',373 'A', 'B', 'C', 'D'};374 385 const pjmedia_rtp_dtmf_event *event = payload; 375 386 -
pjproject/trunk/pjsip/include/pjsip-simple/evsub.h
r212 r228 174 174 * the subscription. 175 175 * 176 * This callback is OPTIONAL . When it is not implemented, the default177 * behavior is to refresh subscription by sending SUBSCRIBE with the178 * interval set to current/last interval.176 * This callback is OPTIONAL when PJSIP package such as presence or 177 * refer is used; the event package will refresh subscription by sending 178 * SUBSCRIBE with the interval set to current/last interval. 179 179 * 180 180 * @param sub The subscription instance. … … 186 186 * refresh after the specified subscription interval. 187 187 * 188 * This callback is OPTIONAL. When it is not implemented, the default 189 * behavior is to send NOTIFY to terminate the subscription. 188 * This callback is OPTIONAL when PJSIP package such as presence or 189 * refer is used; the event package send NOTIFY to terminate the 190 * subscription. 190 191 */ 191 192 void (*on_server_timeout)(pjsip_evsub *sub); … … 400 401 401 402 /** 402 * Get the event subscription instance in the transaction. 403 * Get the event subscription instance associated with the specified 404 * transaction. 403 405 * 404 406 * @param tsx The transaction.
Note: See TracChangeset
for help on using the changeset viewer.