mirror of https://github.com/sipwise/rtpengine.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.6 KiB
72 lines
1.6 KiB
#include "dtmflib.h"
|
|
#include <math.h>
|
|
#include "compat.h"
|
|
#include "log.h"
|
|
|
|
struct dtmf_freq {
|
|
unsigned int prim,
|
|
sec;
|
|
};
|
|
|
|
static const struct dtmf_freq dtmf_freqs[] = {
|
|
{ 941, 1336 }, /* 0 */
|
|
{ 697, 1209 }, /* 1 */
|
|
{ 697, 1336 }, /* 2 */
|
|
{ 697, 1477 }, /* 3 */
|
|
{ 770, 1209 }, /* 4 */
|
|
{ 770, 1336 }, /* 5 */
|
|
{ 770, 1477 }, /* 6 */
|
|
{ 852, 1209 }, /* 7 */
|
|
{ 852, 1336 }, /* 8 */
|
|
{ 852, 1477 }, /* 9 */
|
|
{ 941, 1209 }, /* 10 = * */
|
|
{ 941, 1477 }, /* 11 = # */
|
|
{ 697, 1633 }, /* 12 = A */
|
|
{ 770, 1633 }, /* 13 = B */
|
|
{ 852, 1633 }, /* 14 = C */
|
|
{ 941, 1633 }, /* 15 = D */
|
|
};
|
|
|
|
|
|
INLINE double freq2iter(unsigned int hz, unsigned int sample_rate) {
|
|
double ret = hz;
|
|
ret *= 2 * M_PI;
|
|
ret /= sample_rate;
|
|
return ret;
|
|
}
|
|
|
|
void dtmf_samples(void *buf, unsigned long offset, unsigned long num, unsigned int event, unsigned int volume,
|
|
unsigned int sample_rate)
|
|
{
|
|
int16_t *samples = buf;
|
|
const struct dtmf_freq *df;
|
|
|
|
if (event == 0xff) {
|
|
// pause - silence samples
|
|
memset(samples, 0, num * 2);
|
|
return;
|
|
}
|
|
|
|
if (event >= G_N_ELEMENTS(dtmf_freqs)) {
|
|
ilog(LOG_WARN | LOG_FLAG_LIMIT, "Unsupported DTMF event %u", event);
|
|
memset(buf, 0, num * 2);
|
|
return;
|
|
}
|
|
df = &dtmf_freqs[event];
|
|
|
|
// XXX initialise/save these when the DTMF event starts
|
|
double vol = pow(1.122018, volume) * 2.0;
|
|
|
|
double prim_freq = freq2iter(df->prim, sample_rate);
|
|
double sec_freq = freq2iter(df->sec, sample_rate);
|
|
|
|
num += offset; // end here
|
|
while (offset < num) {
|
|
double prim = sin(prim_freq * offset) / vol;
|
|
double sec = sin(sec_freq * offset) / vol;
|
|
int16_t sample = prim * 32767.0 + sec * 32767.0;
|
|
*samples++ = sample;
|
|
offset++;
|
|
}
|
|
}
|