Exemplo n.º 1
0
r2_mf_rx_state_t *r2_mf_rx_init(r2_mf_rx_state_t *s, int fwd)
{
    int i;
    static int initialised = FALSE;

    s->fwd = fwd;

    if (!initialised)
    {
        for (i = 0;  i < 6;  i++)
        {
            make_goertzel_descriptor(&mf_fwd_detect_desc[i], r2_mf_fwd_frequencies[i], 133);
            make_goertzel_descriptor(&mf_back_detect_desc[i], r2_mf_back_frequencies[i], 133);
        }
        initialised = TRUE;
    }
    if (fwd)
    {
        for (i = 0;  i < 6;  i++)
            goertzel_init(&s->out[i], &mf_fwd_detect_desc[i]);
    }
    else
    {
        for (i = 0;  i < 6;  i++)
            goertzel_init(&s->out[i], &mf_back_detect_desc[i]);
    }
    s->samples = 133;
    s->current_sample = 0;
    return s;
}
Exemplo n.º 2
0
SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ademco_contactid_sender_state_t *s,
        tone_report_func_t callback,
        void *user_data)
{
    if (s == NULL)
    {
        if ((s = (ademco_contactid_sender_state_t *) span_alloc(sizeof(*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));
    span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
    span_log_set_protocol(&s->logging, "Ademco");

    if (!tone_rx_init)
    {
        make_goertzel_descriptor(&tone_1400_desc, 1400.0f, GOERTZEL_SAMPLES_PER_BLOCK);
        make_goertzel_descriptor(&tone_2300_desc, 2300.0f, GOERTZEL_SAMPLES_PER_BLOCK);
        tone_rx_init = true;
    }
    goertzel_init(&s->tone_1400, &tone_1400_desc);
    goertzel_init(&s->tone_2300, &tone_2300_desc);
    s->current_sample = 0;

    s->callback = callback;
    s->callback_user_data = user_data;

    s->step = 0;
    s->remaining_samples = ms_to_samples(100);
    dtmf_tx_init(&s->dtmf, NULL, NULL);
    /* The specified timing is 50-60ms on, 50-60ms off */
    dtmf_tx_set_timing(&s->dtmf, 55, 55);
    return s;
}
Exemplo n.º 3
0
TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate)
{
	int i;
	float theta;

	dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;

	for (i = 0;	 i < GRID_FACTOR;  i++) {
		theta = (float)(M_TWO_PI*(dtmf_row[i]/(float)sample_rate));
		dtmf_detect_row[i].fac = (float)(2.0*cos(theta));

		theta = (float)(M_TWO_PI*(dtmf_col[i]/(float)sample_rate));
		dtmf_detect_col[i].fac = (float)(2.0*cos(theta));
	
		theta = (float)(M_TWO_PI*(dtmf_row[i]*2.0/(float)sample_rate));
		dtmf_detect_row_2nd[i].fac = (float)(2.0*cos(theta));

		theta = (float)(M_TWO_PI*(dtmf_col[i]*2.0/(float)sample_rate));
		dtmf_detect_col_2nd[i].fac = (float)(2.0*cos(theta));
	
		goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
		goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
		goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
		goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
	
		dtmf_detect_state->energy = 0.0;
	}
	dtmf_detect_state->current_sample = 0;
	dtmf_detect_state->detected_digits = 0;
	dtmf_detect_state->lost_digits = 0;
	dtmf_detect_state->digit = 0;
	dtmf_detect_state->dur = 0;
}
Exemplo n.º 4
0
SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
                                             digits_rx_callback_t callback,
                                             void *user_data)
{
    int i;
    static int initialised = FALSE;

    if (s == NULL)
    {
        if ((s = (dtmf_rx_state_t *) malloc(sizeof (*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));
    span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
    span_log_set_protocol(&s->logging, "DTMF");
    s->digits_callback = callback;
    s->digits_callback_data = user_data;
    s->realtime_callback = NULL;
    s->realtime_callback_data = NULL;
    s->filter_dialtone = FALSE;
    s->normal_twist = DTMF_NORMAL_TWIST;
    s->reverse_twist = DTMF_REVERSE_TWIST;
    s->threshold = DTMF_THRESHOLD;

    s->in_digit = 0;
    s->last_hit = 0;

    if (!initialised)
    {
        for (i = 0;  i < 4;  i++)
        {
            make_goertzel_descriptor(&dtmf_detect_row[i], dtmf_row[i], DTMF_SAMPLES_PER_BLOCK);
            make_goertzel_descriptor(&dtmf_detect_col[i], dtmf_col[i], DTMF_SAMPLES_PER_BLOCK);
        }
        initialised = TRUE;
    }
    for (i = 0;  i < 4;  i++)
    {
        goertzel_init(&s->row_out[i], &dtmf_detect_row[i]);
        goertzel_init(&s->col_out[i], &dtmf_detect_col[i]);
    }
#if defined(SPANDSP_USE_FIXED_POINT)
    s->energy = 0;
#else
    s->energy = 0.0f;
#endif
    s->current_sample = 0;
    s->lost_digits = 0;
    s->current_digits = 0;
    s->digits[0] = '\0';
    return s;
}
Exemplo n.º 5
0
bell_mf_rx_state_t *bell_mf_rx_init(bell_mf_rx_state_t *s,
                                    void (*callback)(void *user_data, const char *digits, int len),
                                    void *user_data)
{
    int i;
    static int initialised = FALSE;

    if (!initialised)
    {
        for (i = 0;  i < 6;  i++)
            make_goertzel_descriptor(&bell_mf_detect_desc[i], bell_mf_frequencies[i], 120);
        initialised = TRUE;
    }
    s->callback = callback;
    s->callback_data = user_data;

    s->hits[0] = 
    s->hits[1] =
    s->hits[2] =
    s->hits[3] = 
    s->hits[4] = 0;

    for (i = 0;  i < 6;  i++)
        goertzel_init(&s->out[i], &bell_mf_detect_desc[i]);
    s->current_sample = 0;
    s->lost_digits = 0;
    s->current_digits = 0;
    s->digits[0] = '\0';
    return s;
}
Exemplo n.º 6
0
super_tone_rx_state_t *super_tone_rx_init(super_tone_rx_state_t *s,
                                          super_tone_rx_descriptor_t *desc,
                                          tone_report_func_t callback,
                                          void *user_data)
{
    int i;

    if (desc == NULL)
        return NULL;
    if (callback == NULL)
        return NULL;
    if (s == NULL)
    {
        if ((s = (super_tone_rx_state_t *) malloc(sizeof(*s) + desc->monitored_frequencies*sizeof(goertzel_state_t))) == NULL)
            return NULL;
    }

    for (i = 0;  i < 11;  i++)
    {
        s->segments[i].f1 = -1;
        s->segments[i].f2 = -1;
        s->segments[i].min_duration = 0;
    }
    s->segment_callback = NULL;
    s->tone_callback = callback;
    s->callback_data = user_data;
    if (desc)
        s->desc = desc;
    s->detected_tone = -1;
    s->energy = 0.0f;
    for (i = 0;  i < desc->monitored_frequencies;  i++)
        goertzel_init(&s->state[i], &s->desc->desc[i]);
    return  s;
}
Exemplo n.º 7
0
SPAN_DECLARE(r2_mf_rx_state_t *) r2_mf_rx_init(r2_mf_rx_state_t *s,
                                               int fwd,
                                               tone_report_func_t callback,
                                               void *user_data)
{
    int i;
    static int initialised = FALSE;

    if (s == NULL)
    {
        if ((s = (r2_mf_rx_state_t *) malloc(sizeof(*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));

    s->fwd = fwd;

    if (!initialised)
    {
        for (i = 0;  i < 6;  i++)
        {
            make_goertzel_descriptor(&mf_fwd_detect_desc[i], (float) r2_mf_fwd_frequencies[i], R2_MF_SAMPLES_PER_BLOCK);
            make_goertzel_descriptor(&mf_back_detect_desc[i], (float) r2_mf_back_frequencies[i], R2_MF_SAMPLES_PER_BLOCK);
        }
        initialised = TRUE;
    }
    if (fwd)
    {
        for (i = 0;  i < 6;  i++)
            goertzel_init(&s->out[i], &mf_fwd_detect_desc[i]);
    }
    else
    {
        for (i = 0;  i < 6;  i++)
            goertzel_init(&s->out[i], &mf_back_detect_desc[i]);
    }
    s->callback = callback;
    s->callback_data = user_data;
    s->current_digit = 0;
    s->current_sample = 0;
    return s;
}
Exemplo n.º 8
0
TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
{
	float theta = 0;
	int x = 0;

	if (!mt->sample_rate) {
		mt->sample_rate = 8000;
	}

	if (!mt->min_samples) {
		mt->min_samples = 102;
	}

	mt->min_samples *= (mt->sample_rate / 8000);

	if (!mt->positive_factor) {
		mt->positive_factor = 2;
	}

	if(!mt->negative_factor) {
		mt->negative_factor = 10;
	}

	if (!mt->hit_factor) {
		mt->hit_factor = 2;
	}

	for(x = 0; x < TELETONE_MAX_TONES; x++) {
		if ((int) map->freqs[x] == 0) {
			break;
		}
		mt->tone_count++;
		theta = (float)(M_TWO_PI*(map->freqs[x]/(float)mt->sample_rate));
		mt->tdd[x].fac = (float)(2.0 * cos(theta));
		goertzel_init (&mt->gs[x], &mt->tdd[x]);
		goertzel_init (&mt->gs2[x], &mt->tdd[x]);
	}

}
Exemplo n.º 9
0
Arquivo: dsp.c Projeto: OPSF/uClinux
static void ast_mf_detect_init (mf_detect_state_t *s)
{
	int i;
#ifdef OLD_DSP_ROUTINES
	s->hit1 = 
	s->hit2 = 0;
#else	
	s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
#endif
	for (i = 0;  i < 6;  i++) {
		goertzel_init (&s->tone_out[i], mf_tones[i], 160);
#ifdef OLD_DSP_ROUTINES
		goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
		s->energy = 0.0;
#endif
	}
	s->current_digits = 0;
	memset(&s->digits, 0, sizeof(s->digits));
	s->current_sample = 0;
	s->detected_digits = 0;
	s->lost_digits = 0;
	s->digits[0] = '\0';
	s->mhit = 0;
}
Exemplo n.º 10
0
SPAN_DECLARE(bell_mf_rx_state_t *) bell_mf_rx_init(bell_mf_rx_state_t *s,
                                                   digits_rx_callback_t callback,
                                                   void *user_data)
{
    int i;
    static int initialised = FALSE;

    if (s == NULL)
    {
        if ((s = (bell_mf_rx_state_t *) malloc(sizeof(*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));

    if (!initialised)
    {
        for (i = 0;  i < 6;  i++)
            make_goertzel_descriptor(&bell_mf_detect_desc[i], (float) bell_mf_frequencies[i], BELL_MF_SAMPLES_PER_BLOCK);
        initialised = TRUE;
    }
    s->digits_callback = callback;
    s->digits_callback_data = user_data;

    s->hits[0] = 
    s->hits[1] =
    s->hits[2] =
    s->hits[3] = 
    s->hits[4] = 0;

    for (i = 0;  i < 6;  i++)
        goertzel_init(&s->out[i], &bell_mf_detect_desc[i]);
    s->current_sample = 0;
    s->lost_digits = 0;
    s->current_digits = 0;
    s->digits[0] = '\0';
    return s;
}
Exemplo n.º 11
0
Arquivo: dsp.c Projeto: OPSF/uClinux
static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
{
	int i;

#ifdef OLD_DSP_ROUTINES
	s->hit1 = 
	s->mhit = 
	s->hit3 =
	s->hit4 = 
	s->hit2 = 0;
#else
	s->hits[0] = s->hits[1] = s->hits[2] = 0;
#endif
	for (i = 0;  i < 4;  i++) {
		goertzel_init (&s->row_out[i], dtmf_row[i], 102);
		goertzel_init (&s->col_out[i], dtmf_col[i], 102);
#ifdef OLD_DSP_ROUTINES
		goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
		goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
#endif	
		s->energy = 0.0;
	}
#ifdef FAX_DETECT
	/* Same for the fax dector */
	goertzel_init (&s->fax_tone, fax_freq, 102);

#ifdef OLD_DSP_ROUTINES
	/* Same for the fax dector 2nd harmonic */
	goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
#endif	
#endif /* FAX_DETECT */
	s->current_sample = 0;
	s->detected_digits = 0;
	s->current_digits = 0;
	memset(&s->digits, 0, sizeof(s->digits));
	s->lost_digits = 0;
	s->digits[0] = '\0';
}
Exemplo n.º 12
0
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
						  int16_t sample_buffer[],
						  int samples)
{
	float row_energy[GRID_FACTOR];
	float col_energy[GRID_FACTOR];
	float famp;
	float v1;
	int i;
	int j;
	int sample;
	int best_row;
	int best_col;
	char hit;
	int limit;
	teletone_hit_type_t r = 0;

	hit = 0;
	for (sample = 0;  sample < samples;	 sample = limit) {
		/* BLOCK_LEN is optimised to meet the DTMF specs. */
		if ((samples - sample) >= (BLOCK_LEN - dtmf_detect_state->current_sample)) {
			limit = sample + (BLOCK_LEN - dtmf_detect_state->current_sample);
		} else {
			limit = samples;
		}

		for (j = sample;  j < limit;  j++) {
			int x = 0;
			famp = sample_buffer[j];
			
			dtmf_detect_state->energy += famp*famp;

			for(x = 0; x < GRID_FACTOR; x++) {
				v1 = dtmf_detect_state->row_out[x].v2;
				dtmf_detect_state->row_out[x].v2 = dtmf_detect_state->row_out[x].v3;
				dtmf_detect_state->row_out[x].v3 = (float)(dtmf_detect_state->row_out[x].fac*dtmf_detect_state->row_out[x].v2 - v1 + famp);
	
				v1 = dtmf_detect_state->col_out[x].v2;
				dtmf_detect_state->col_out[x].v2 = dtmf_detect_state->col_out[x].v3;
				dtmf_detect_state->col_out[x].v3 = (float)(dtmf_detect_state->col_out[x].fac*dtmf_detect_state->col_out[x].v2 - v1 + famp);

				v1 = dtmf_detect_state->col_out2nd[x].v2;
				dtmf_detect_state->col_out2nd[x].v2 = dtmf_detect_state->col_out2nd[x].v3;
				dtmf_detect_state->col_out2nd[x].v3 = (float)(dtmf_detect_state->col_out2nd[x].fac*dtmf_detect_state->col_out2nd[x].v2 - v1 + famp);
		
				v1 = dtmf_detect_state->row_out2nd[x].v2;
				dtmf_detect_state->row_out2nd[x].v2 = dtmf_detect_state->row_out2nd[x].v3;
				dtmf_detect_state->row_out2nd[x].v3 = (float)(dtmf_detect_state->row_out2nd[x].fac*dtmf_detect_state->row_out2nd[x].v2 - v1 + famp);
			}

		}

		if (dtmf_detect_state->zc > 0) {
			if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
				if (!--dtmf_detect_state->zc) {
					/* Reinitialise the detector for the next block */
					dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
					for (i = 0;	 i < GRID_FACTOR;  i++) {
						goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
						goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
						goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
						goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
					}
					dtmf_detect_state->dur -= samples;
					return TT_HIT_END;
				}
			}
			
			dtmf_detect_state->dur += samples;
			dtmf_detect_state->lenergy = dtmf_detect_state->energy;
			dtmf_detect_state->energy = 0.0;
			dtmf_detect_state->current_sample = 0;
			return TT_HIT_MIDDLE;
		} else if (dtmf_detect_state->digit) {
			return TT_HIT_END;
		}
		

		dtmf_detect_state->current_sample += (limit - sample);
		if (dtmf_detect_state->current_sample < BLOCK_LEN) {
			continue;
		}
		/* We are at the end of a DTMF detection block */
		/* Find the peak row and the peak column */
		row_energy[0] = teletone_goertzel_result (&dtmf_detect_state->row_out[0]);
		col_energy[0] = teletone_goertzel_result (&dtmf_detect_state->col_out[0]);

		for (best_row = best_col = 0, i = 1;  i < GRID_FACTOR;	i++) {
			row_energy[i] = teletone_goertzel_result (&dtmf_detect_state->row_out[i]);
			if (row_energy[i] > row_energy[best_row]) {
				best_row = i;
			}
			col_energy[i] = teletone_goertzel_result (&dtmf_detect_state->col_out[i]);
			if (col_energy[i] > col_energy[best_col]) {
				best_col = i;
			}
		}
		hit = 0;
		/* Basic signal level test and the twist test */
		if (row_energy[best_row] >= DTMF_THRESHOLD &&
			col_energy[best_col] >= DTMF_THRESHOLD &&
			col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
			col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
			/* Relative peak test */
			for (i = 0;	 i < GRID_FACTOR;  i++) {
				if ((i != best_col	&&	col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
					(i != best_row	&&	row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
					break;
				}
			}
			/* ... and second harmonic test */
			if (i >= GRID_FACTOR && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy &&
				teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] &&
				teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
				hit = dtmf_positions[(best_row << 2) + best_col];
				/* Look for two successive similar results */
				/* The logic in the next test is:
				   We need two successive identical clean detects, with
				   something different preceeding it. This can work with
				   back to back differing digits. More importantly, it
				   can work with nasty phones that give a very wobbly start
				   to a digit. */
				if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
					dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
					dtmf_detect_state->detected_digits++;
					if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
						dtmf_detect_state->digit = hit;
					} else {
						dtmf_detect_state->lost_digits++;
					}
					
					if (!dtmf_detect_state->zc) {
						dtmf_detect_state->zc = ZC;
						dtmf_detect_state->dur = 0;
						r = TT_HIT_BEGIN;
						break;
					}					

				}
			}
		}

		dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
		dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
		dtmf_detect_state->hit3 = hit;

		dtmf_detect_state->energy = 0.0;
		dtmf_detect_state->current_sample = 0;
		
	}

	return r;
}
Exemplo n.º 13
0
TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
								int16_t sample_buffer[],
								int samples)
{
	int sample, limit = 0, j, x = 0;
	float v1, famp;
	float eng_sum = 0, eng_all[TELETONE_MAX_TONES] = {0.0};
	int gtest = 0, see_hit = 0;

	for (sample = 0;  sample >= 0 && sample < samples; sample = limit) {
		mt->total_samples++;

		if ((samples - sample) >= (mt->min_samples - mt->current_sample)) {
			limit = sample + (mt->min_samples - mt->current_sample);
		} else {
			limit = samples;
		}
		if (limit < 0 || limit > samples) {
			limit = samples;
		}

		for (j = sample;  j < limit;  j++) {
			famp = sample_buffer[j];
			
			mt->energy += famp*famp;

			for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
				v1 = mt->gs[x].v2;
				mt->gs[x].v2 = mt->gs[x].v3;
				mt->gs[x].v3 = (float)(mt->gs[x].fac * mt->gs[x].v2 - v1 + famp);
	
				v1 = mt->gs2[x].v2;
				mt->gs2[x].v2 = mt->gs2[x].v3;
				mt->gs2[x].v3 = (float)(mt->gs2[x].fac*mt->gs2[x].v2 - v1 + famp);
			}
		}

		mt->current_sample += (limit - sample);
		if (mt->current_sample < mt->min_samples) {
			continue;
		}

		eng_sum = 0;
		for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
			eng_all[x] = (float)(teletone_goertzel_result (&mt->gs[x]));
			eng_sum += eng_all[x];
		}

		gtest = 0;
		for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
			gtest += teletone_goertzel_result (&mt->gs2[x]) < eng_all[x] ? 1 : 0;
		}

		if ((gtest >= 2 || gtest == mt->tone_count) && eng_sum > 42.0 * mt->energy) {
			if(mt->negatives) {
				mt->negatives--;
			}
			mt->positives++;

			if(mt->positives >= mt->positive_factor) {
				mt->hits++;
			}
			if (mt->hits >= mt->hit_factor) {
				see_hit++;
				mt->positives = mt->negatives = mt->hits = 0;
			}
		} else {
			mt->negatives++;
			if(mt->positives) {
				mt->positives--;
			}
			if(mt->negatives > mt->negative_factor) {
				mt->positives = mt->hits = 0;
			}
		}

		/* Reinitialise the detector for the next block */
		for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
			goertzel_init (&mt->gs[x], &mt->tdd[x]);
			goertzel_init (&mt->gs2[x], &mt->tdd[x]);
		}

		mt->energy = 0.0;
		mt->current_sample = 0;
	}

	return see_hit;
}