Example #1
0
int
main(int argc, char *argv[])
{
    int16_t intData[BLOCK];
    double inputData[BLOCK];
    double frequency, freq2;
    double variance, var2;
    int numWords;
    int sampleCount, i;
    char *inFileName;
    FILE *inFile;
 
    inFileName = NULL;
 
    if ( argc == 2 )
    {
        inFileName = argv[1];
        printf("input file name = %s\n",inFileName);
    }
    else
    {
        printf("Incorrect arguments, usage: desa filename\n");
        return(1);
    }
 
    inFile = fopen(inFileName,"rb");
    if ( !inFile )
    {
        printf("Exiting.Cannot open input file %s\n",inFileName);
        fclose( inFile );
        return(1);
    }
 
    // start counting frames
    sampleCount = 0;
 
    numWords = fread(intData, sizeof(int16_t), BLOCK, inFile );
 
    // until end of file
    while( numWords == BLOCK )
    {
        intToFloat(intData, inputData, numWords);

        printf("\nframe = %d\n",sampleCount);
        /*for (i = 0; i < BLOCK; ++i)
        {
            printf("[%d]", intData[i]);
        }*/
       /* for(i = 0; i < 5; i++){
inputData[30 + i] = 20000.0 + i;
        }*/
        // get the frequency estimates
        frequency = desa1( inputData, &variance );
        printf("\nDesa1: Mean freq = %f, var = %f, std dev = %f",
            frequency, variance, sqrt(variance));
 
        frequency = desa2( inputData, &variance );
        printf("\nDesa2: Mean freq = %f, var = %f, std dev = %f\n",
            frequency, variance, sqrt(variance));

        desa2_freeswitch_int(intData, &frequency, &freq2, &variance, &var2);
        printf("\nDesa2_fs_int: Mean freq = %f, var = %f, std dev = %f\n, freq2 = %f, var2 = %f\n",
            frequency, variance, sqrt(variance), freq2, var2);

        desa2_freeswitch_double(inputData, &frequency, &freq2, &variance, &var2);
        printf("\nDesa2_fs_double: Mean freq = %f, var = %f, std dev = %f\n, freq2 = %f, var2 = %f\n",
            frequency, variance, sqrt(variance), freq2, var2);
 
        sampleCount += BLOCK;
        numWords = fread(intData, sizeof(int16_t), BLOCK, inFile );
    }
 
    printf("\nFinished. sampleCount = %d\n",sampleCount);
 
    fclose( inFile );
    return 0;
}
Example #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;
        }
    }
}