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; }
/*! \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; } } }