Skip to content
Snippets Groups Projects
Commit 6be81ab0 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#3021] Cleanup tone generation

parent 5a462a74
No related branches found
No related tags found
No related merge requests found
......@@ -5,14 +5,12 @@ noinst_LTLIBRARIES = libsound.la
libsound_la_SOURCES = \
audiofile.cpp \
tone.cpp \
tonegenerator.cpp \
tonelist.cpp \
dtmf.cpp \
dtmfgenerator.cpp
noinst_HEADERS = \
audiofile.h \
tonegenerator.h \
tone.h \
tonelist.h \
dtmfgenerator.h \
......
......@@ -28,8 +28,12 @@
#include <cstdlib>
#include <strings.h>
Tone::Tone (const std::string& definition, unsigned int sampleRate) : AudioLoop(), _sampleRate (sampleRate)
#define TABLE_LENGTH 4096
double TWOPI = 2 * M_PI;
Tone::Tone (const std::string& definition, unsigned int sampleRate) : AudioLoop(), _sampleRate (sampleRate), _xhigher(0.0), _xlower(0.0)
{
fillWavetable();
genBuffer (definition); // allocate memory with definition parameter
}
......@@ -101,6 +105,7 @@ Tone::genBuffer (const std::string& definition)
}
// Generate SAMPLING_RATE samples of sinus, buffer is the result
_debug("genSin(%d, %d)", freq1, freq2);
genSin (bufferPos, freq1, freq2, count);
// To concatenate the different buffers for each section.
......@@ -124,20 +129,70 @@ Tone::genBuffer (const std::string& definition)
bufferPos=0;
}
void
Tone::fillWavetable()
{
double tableSize = (double)TABLE_LENGTH;
for(int i = 0; i < TABLE_LENGTH; i++) {
_wavetable[i] = sin( ((double)i / (tableSize - 1.0)) * TWOPI );
}
}
double
Tone::interpolate(double x)
{
int xi_0, xi_1;
double yi_0, yi_1, A, B;
xi_0 = (int)x;
xi_1 = xi_0+1;
yi_0 =_wavetable[xi_0];
yi_1 = _wavetable[xi_1];
A = (x - xi_0);
B = 1.0 - A;
return A*yi_0 + B*yi_1;
}
void
Tone::genSin (SFLDataFormat* buffer, int frequency1, int frequency2, int nb)
{
_xhigher = 0.0;
_xlower = 0.0;
double pi2 = 6.28318520;
double var1 = pi2 * (double) frequency1 / (double) _sampleRate;
double var2 = pi2 * (double) frequency2 / (double) _sampleRate;
double sr = (double)_sampleRate;
double tableSize = (double)TABLE_LENGTH;
// softer
double amp = (double) SFLDataAmplitude;
double N_h = sr / (double) (frequency1);
double N_l = sr / (double) (frequency2);
for (int t = 0; t < nb; t++) {
buffer[t] = (SFLDataFormat) (amp * ( (sin (var1 * t) + sin (var2 * t))));
}
double dx_h = tableSize / N_h;
double dx_l = tableSize / N_l;
double x_h = _xhigher;
double x_l = _xlower;
double amp = (double)SFLDataAmplitude;
for (int t = 0; t < nb; t ++) {
buffer[t] = (int16)(amp*(interpolate(x_h) + interpolate(x_l)));
x_h += dx_h;
x_l += dx_l;
if(x_h > tableSize) {
x_h -= tableSize;
}
if(x_l > tableSize) {
x_l -= tableSize;
}
}
_xhigher = x_h;
_xlower = x_l;
}
......@@ -28,6 +28,8 @@
#define TONE_NBTONE 4
#define TONE_NBCOUNTRY 7
#define TABLE_LENGTH 4096
/**
* @file tone.h
* @brief Tone sample (dial, busy, ring, congestion)
......@@ -65,6 +67,17 @@ public:
*/
void genSin(SFLDataFormat* buffer, int frequency1, int frequency2, int nb);
/**
*
*/
void fillWavetable(void);
/**
*
*/
double interpolate(double x);
private:
/**
......@@ -75,6 +88,11 @@ private:
/** Sample rate */
unsigned int _sampleRate;
double _wavetable[TABLE_LENGTH];
double _xhigher;
double _xlower;
};
#endif // __TONE_H__
......
/**
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <fstream>
#include <math.h>
#include <stdlib.h>
#include "tonegenerator.h"
#include "global.h"
int AMPLITUDE = 32767;
///////////////////////////////////////////////////////////////////////////////
// ToneGenerator implementation
///////////////////////////////////////////////////////////////////////////////
ToneGenerator::ToneGenerator (unsigned int sampleRate) : sample (NULL), freq1(), freq2(), time(), totalbytes(), _sampleRate (sampleRate)
{
}
ToneGenerator::~ToneGenerator (void)
{
}
/**
* Calculate superposition of 2 sinus
*
*/
void
ToneGenerator::generateSin (int lowerfreq, int higherfreq, int16* ptr, int len) const
{
double var1, var2;
var1 = (double) 2 * (double) M_PI * (double) higherfreq / (double) _sampleRate;
var2 = (double) 2 * (double) M_PI * (double) lowerfreq / (double) _sampleRate;
double amp = (double) (AMPLITUDE >> 2);
for (int t = 0; t < len; t++) {
ptr[t] = (int16) (amp * ( (sin (var1 * t) + sin (var2 * t))));
}
}
/*
* Copyright (C) 2004-2006 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __TONE_GENERATOR_H__
#define __TONE_GENERATOR_H__
#include <string>
#include <cc++/thread.h>
#include "global.h"
/**
* @file tonegenerator.h
* @brief Sine generator to create tone with string definition
*/
class ToneGenerator {
public:
/**
* Constructor
* @param sampleRate The sample rate of the generated samples
*/
ToneGenerator (unsigned int sampleRate);
/**
* Destructor
*/
~ToneGenerator (void);
/**
* Calculate sinus with superposition of 2 frequencies
* @param lowerfreq Lower frequency
* @param higherfreq Higher frequency
* @param ptr For result buffer
* @param len The length of the data to be generated
*/
void generateSin (int, int, int16 *, int len) const;
///////////////////////////
// Public members variable
//////////////////////////
int16 *sample;
int freq1, freq2;
int time;
int totalbytes;
private:
// Copy Constructor
ToneGenerator(const ToneGenerator& rh);
// Assignment Operator
ToneGenerator& operator=( const ToneGenerator& rh);
/*
* Initialisation of the supported tones according to the countries.
*/
void initTone (void);
int16 _buf[SIZEBUF];
int _sampleRate;
};
#endif // __TONE_GENRATOR_H__
......@@ -3478,7 +3478,7 @@ mod_on_rx_request (pjsip_rx_data *rdata)
// No need to go any further on incoming ACK
if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
_info("UserAgent: received an ACK");
return true;
return true;
}
// Handle the incoming call invite in this function
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment