Ejemplo n.º 1
0
void
desa2_freeswitch_int(int16_t *input, double *mean1, double *mean2, double *var1, double *var2)
{
    int i;
    circ_buffer_t   b;
	sma_buffer_t    sma_b;
	sma_buffer_t    sqa_b;
    double freq[BLOCK]; // frequency estimates

    INIT_CIRC_BUFFER(&b, BLOCK);
	INIT_SMA_BUFFER(&sma_b, 10);
	INIT_SMA_BUFFER(&sqa_b, 10);

	INSERT_INT16_FRAME(&b, input, BLOCK);

    // calculate the frequency estimate for each sample as in FS
    for (i = 0; i < (BLOCK - P); i++)
    {
        freq[i] = desa2_fs(&b, i);
        APPEND_SMA_VAL(&sma_b, freq[i]);
        APPEND_SMA_VAL(&sqa_b, freq[i] * freq[i]);
	*var1 = sqa_b.sma - (sma_b.sma * sma_b.sma);
	printf("<<< AVMD v[%f] f[%f][%f]Hz sma[%f][%f]Hz sqa[%f]\tsample[%d]\t[%d] >>>\n",
            *var1, freq[i], TO_HZ(8000, freq[i]), sma_b.sma, TO_HZ(8000, sma_b.sma), sqa_b.sma, i, input[i]);
    }
    /* set mean */
    *mean1 = sma_b.sma;
    /* calculate the variance */
	*var1 = sqa_b.sma - (sma_b.sma * sma_b.sma);

    /* for comparison calculate mean2 frequency & var2 */
    double mean = 0.0;
    for (i = 0; i < (BLOCK - P); i++)
    {
        mean += freq[i];
    }
    mean /= (double) (BLOCK - P);
    *mean2 = mean;
    *var2 = 0.0;
    for (i = 0; i < (BLOCK - P); i++ )
    {
        *var2 += freq[i] * freq[i];
    }
    *var2 /= (double)(BLOCK - P);
    *var2 -= (mean * mean);
 
    free(b.buf);
    return;
}
Ejemplo n.º 2
0
/*! \brief Process one frame of data with avmd algorithm
 * @author Eric des Courtis
 * @param session An avmd session
 * @param frame A audio frame
 */
static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
{
    switch_event_t *event;
    switch_status_t status;
    switch_event_t *event_copy;
    switch_channel_t *channel;

    circ_buffer_t *b;
    size_t pos;
    double f;
    double a;
    double error = 0.0;
    double success = 0.0;
    double amp = 0.0;
    double s_rate;
    double e_rate;
    double avg_a;
    double sine_len;
    uint32_t sine_len_i;
    int valid;
    
	b = &session->b;

	/*! If beep has already been detected skip the CPU heavy stuff */
    if(session->state.beep_state == BEEP_DETECTED){
        return;
    }

	/*! Precompute values used heavily in the inner loop */
    sine_len_i = SINE_LEN(session->rate);
    sine_len = (double)sine_len_i;


    channel = switch_core_session_get_channel(session->session);

	/*! Insert frame of 16 bit samples into buffer */
    INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples);

    /*! INNER LOOP -- OPTIMIZATION TARGET */
    for(pos = GET_BACKLOG_POS(b); pos != (GET_CURRENT_POS(b) - P); pos++){

		/*! Get a desa2 frequency estimate in Hertz */
        f = TO_HZ(session->rate, desa2(b, pos));

        /*! Don't caculate amplitude if frequency is not within range */
        if(f < MIN_FREQUENCY || f > MAX_FREQUENCY) {
            a = 0.0;
            error += 1.0;
        } else {
            a = amplitude(b, pos, f);
            success += 1.0;
            if(!ISNAN(a)){
                amp += a;
            }
        }
		
		/*! Every once in a while we evaluate the desa2 and amplitude results */
        if(((pos + 1) % sine_len_i) == 0){
            s_rate = success / (error + success);
            e_rate = error   / (error + success);
            avg_a  = amp     / sine_len;

			/*! Results out of these ranges are considered invalid */
            valid = 0;
            if(     s_rate >  0.60 && avg_a > 0.50)	valid = 1;
            else if(s_rate >  0.65 && avg_a > 0.45)	valid = 1;
            else if(s_rate >  0.70 && avg_a > 0.40)	valid = 1;
            else if(s_rate >  0.80 && avg_a > 0.30)	valid = 1;
            else if(s_rate >  0.95 && avg_a > 0.05)	valid = 1;
            else if(s_rate >= 0.99 && avg_a > 0.04)	valid = 1;
            else if(s_rate == 1.00 && avg_a > 0.02)	valid = 1;

			if(valid) {
				APPEND_SMA_VAL(&session->sma_b, s_rate * avg_a);
			}
			else {
				APPEND_SMA_VAL(&session->sma_b, 0.0           );
			}

			/*! If sma is higher then 0 we have some kind of detection (increase this value to eliminate false positives ex: 0.01) */
            if(session->sma_b.sma > 0.00){
				/*! Throw an event to FreeSWITCH */
                status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP);
                if(status != SWITCH_STATUS_SUCCESS) {
                    return;
                }

                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session->session));
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");

                if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
                    return;
                }

                switch_core_session_queue_event(session->session, &event);
                switch_event_fire(&event_copy);

                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected >>>\n");
                switch_channel_set_variable(channel, "avmd_detect", "TRUE");
                RESET_SMA_BUFFER(&session->sma_b);
                session->state.beep_state = BEEP_DETECTED;

                return;
            }

            amp = 0.0;
            success = 0.0;
            error = 0.0;
        }
    }
}