How to detect frames in app_amd.c for identifying beeps

Hi,

I am trying to make changes in app_amd.c file to detect beeps.

To achieve this we are trying to change the app_amd.c file to capture the frames and do some calculations to identify if n number consecutive frames has got the same output which will determine if there is a beep. We picked this up from the freeswitch codes approach and trying to implement the concept in amd.

But for this we are struggling to find the right parameter of the frame in f->data.ptr which will be input to perform the calculation.

Please can anyone let me know what are the different values of f->data which can be used and if possible let me know which parameter of f->data should be used. Currently we have being using f->data.ptr which is giving some value out of the desa logic used in freeswitch.

I think you are out of your depth.

Frames with beeps in them will not be identical, because of noise and because of most beeps not being exact multiples of 50Hz, and varying in starting phase, and being distorted by transcoding.

If you don’t even know the exact frequency, you will probably need to convert to the frequency domain (FFT) and then look for spikes in the spectrum.

You would normally be interested only in VOICE frames.

Thanks David for a helping hope… I was unable to view anything different after applying all the logics i thought of…

I am thinking of playing with the frames data as much as possible, but I am thinking only from f->data.ptr point of view to get me the value.

Please can you help me know if i am working with the right variable f->data.ptr or should i use some other pointer or variable of this frame.

You are right, i will never be able to find what would be frequency of the different beeps. When you say i need to convert to the frequency domain, please can you help me know if you have any code for this and how can i get it.

Thanks again mate for just replying…

You would need the length, as well as the pointer, as you will need the whole of the data, not just the first byte. You will also need to check the type, and codec, although I assume that amd has already forced the use of a suitable codec.

hi David, do you have any code for this so that i can test with this or let me know what approach can i use.

i am currently using the below code added as functions which inserted in app_amd.c and calling in the answering machine detection to find a value.

#include “math.h”
#define SAMPLEFREQUENCY 8000;
//#define M_PI 3.14159265358979323846;

double goertzelFilter(int samples[], double freq, int N) {
double s_prev = 0.0;
double s_prev2 = 0.0;
double coeff,normalizedfreq,power,s;
int i;
normalizedfreq = freq / SAMPLEFREQUENCY;
coeff = 2 * cos(2 * M_PI * normalizedfreq);
for (i=0; i<N; i++) {
s = samples[i] + coeff * s_prev - s_prev2;
s_prev2 = s_prev;
s_prev = s;
}
power = s_prev2s_prev2+s_prevs_prev-coeffs_prevs_prev2;
return power;
}

float goertzel_mag(int numSamples,int TARGET_FREQUENCY,int SAMPLING_RATE, int* data)
{
int k,i;
float floatnumSamples;
float omega,sine,cosine,coeff,q0,q1,q2,magnitude,real,imag;

float   scalingFactor = numSamples / 2.0;

floatnumSamples = (float) numSamples;
k = (int) (0.5 + ((floatnumSamples * TARGET_FREQUENCY) / SAMPLING_RATE));
omega = (2.0 * M_PI * k) / floatnumSamples;
sine = sin(omega);
cosine = cos(omega);
coeff = 2.0 * cosine;
q0=0;
q1=0;
q2=0;

for(i=0; i<numSamples; i++)
{
    q0 = coeff * q1 - q2 + data[i];
    q2 = q1;
    q1 = q0;
}

// calculate the real and imaginary results
// scaling appropriately
real = (q1 - q2 * cosine) / scalingFactor;
imag = (q2 * sine) / scalingFactor;

magnitude = sqrtf(real*real + imag*imag);
return magnitude;

}

Code used in answering machine isAnsweringMachine()

int fdata[256];
int16_t *dataptr;
double sine_len;
int sine_len_i;
double beep_len_i;
int pos;

ast_verb(3, “BEEP: Channel [%s]. Beep Test Goertzel Power: %f\n”, chan->name, goertzelFilter(dataptr, 500, f->datalen ) );
ast_verb(3, “BEEP: Channel [%s]. Beep Test Goertzel Magnitude: %f\n”, chan->name, goertzel_mag(f->samples, 500, 8000, dataptr ) );

This is the wrong place to ask, anyway, as it is a developer question. You want the developer mailing list or IRC channel.

In your extract, dataptr is unset and the results of the filter are discarded.

The algorithm is looking for a known frequency (500Hz).

Hi

I’d be quite interested to see if you succeed in this endeavour - it would be very useful in many situations !

J.

Hi David, please can you let me know which would be the best place to put this question. I will put it there to get the best out it.

with regards to dataptr i am assiging as below which i missed in above vcode. Is this usage of f->data.ptr correct. This is the most important query/doubt i have if i am using the correct parameter from the frame to the calculation.
dataptr = f->data.ptr;

@cerien, please let us know your input as well :slight_smile:

http://www.asterisk.org/community/discuss