linphone-iphone/linphone/mediastreamer2/src/dtmfgen.c
smorlat 4cafb80672 internationalization of mediastreamer2 (thanks to Petr Pisar)
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@208 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
2008-12-17 21:42:02 +00:00

204 lines
3.9 KiB
C

/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/dtmfgen.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
struct DtmfGenState{
int rate;
int dur;
int pos;
float highfreq;
float lowfreq;
char dtmf;
};
typedef struct DtmfGenState DtmfGenState;
static void dtmfgen_init(MSFilter *f){
DtmfGenState *s=(DtmfGenState *)ms_new(DtmfGenState,1);
s->rate=8000;
s->dur=s->rate/10;
s->pos=0;
s->dtmf=0;
f->data=s;
}
static void dtmfgen_uninit(MSFilter *f){
ms_free(f->data);
}
static int dtmfgen_put(MSFilter *f, void *arg){
DtmfGenState *s=(DtmfGenState*)f->data;
const char *dtmf=(char*)arg;
s->pos=0;
switch(dtmf[0]){
case '0':
s->lowfreq=941;
s->highfreq=1336;
break;
case '1':
s->lowfreq=697;
s->highfreq=1209;
break;
case '2':
s->lowfreq=697;
s->highfreq=1336;
break;
case '3':
s->lowfreq=697;
s->highfreq=1477;
break;
case '4':
s->lowfreq=770;
s->highfreq=1209;
break;
case '5':
s->lowfreq=770;
s->highfreq=1336;
break;
case '6':
s->lowfreq=770;
s->highfreq=1477;
break;
case '7':
s->lowfreq=852;
s->highfreq=1209;
break;
case '8':
s->lowfreq=852;
s->highfreq=1336;
break;
case '9':
s->lowfreq=852;
s->highfreq=1477;
break;
case '*':
s->lowfreq=941;
s->highfreq=1209;
break;
case '#':
s->lowfreq=941;
s->highfreq=1477;
break;
case 'A':
s->lowfreq=697;
s->highfreq=1633;
break;
case 'B':
s->lowfreq=770;
s->highfreq=1633;
break;
case 'C':
s->lowfreq=852;
s->highfreq=1633;
break;
case 'D':
s->lowfreq=941;
s->highfreq=1633;
break;
default:
ms_warning("Not a dtmf key.");
return -1;
}
s->lowfreq=s->lowfreq/s->rate;
s->highfreq=s->highfreq/s->rate;
s->dtmf=dtmf[0];
return 0;
}
static int dtmfgen_set_rate(MSFilter *f, void *arg){
DtmfGenState *s=(DtmfGenState*)f->data;
s->rate=*((int*)arg);
s->dur=s->rate/10;
return 0;
}
static void dtmfgen_process(MSFilter *f){
mblk_t *m;
DtmfGenState *s=(DtmfGenState*)f->data;
while((m=ms_queue_get(f->inputs[0]))!=NULL){
if (s->dtmf!=0){
int nsamples=(m->b_wptr-m->b_rptr)/2;
int i;
int16_t *sample=(int16_t*)m->b_rptr;
for (i=0;i<nsamples && s->pos<s->dur;i++,s->pos++){
sample[i]=(int16_t)(10000.0*sin(2*M_PI*(float)s->pos*s->lowfreq));
sample[i]+=(int16_t)(10000.0*sin(2*M_PI*(float)s->pos*s->highfreq));
}
if (s->pos==s->dur){
s->pos=0;
s->dtmf=0;
}
}
ms_queue_put(f->outputs[0],m);
}
}
MSFilterMethod dtmfgen_methods[]={
{ MS_FILTER_SET_SAMPLE_RATE , dtmfgen_set_rate },
{ MS_DTMF_GEN_PUT , dtmfgen_put },
{ 0 , NULL }
};
#ifdef _MSC_VER
MSFilterDesc ms_dtmf_gen_desc={
MS_DTMF_GEN_ID,
"MSDtmfGen",
N_("DTMF generator"),
MS_FILTER_OTHER,
NULL,
1,
1,
dtmfgen_init,
NULL,
dtmfgen_process,
NULL,
dtmfgen_uninit,
dtmfgen_methods
};
#else
MSFilterDesc ms_dtmf_gen_desc={
.id=MS_DTMF_GEN_ID,
.name="MSDtmfGen",
.text=N_("DTMF generator"),
.category=MS_FILTER_OTHER,
.ninputs=1,
.noutputs=1,
.init=dtmfgen_init,
.process=dtmfgen_process,
.uninit=dtmfgen_uninit,
.methods=dtmfgen_methods
};
#endif
MS_FILTER_DESC_EXPORT(ms_dtmf_gen_desc)